26 lines
1.1 KiB
Python
26 lines
1.1 KiB
Python
"""Read-only references to one explicit AMD64 PE RIP-relative data slot."""
|
|||
|
|
import argparse
|
||
|
|
import re
|
||
|
|
import struct
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
p=argparse.ArgumentParser(description=__doc__)
|
||
|
|
p.add_argument('--binary',type=Path,required=True)
|
||
|
|
p.add_argument('--target',type=lambda x:int(x,0),required=True)
|
||
|
|
a=p.parse_args()
|
||
|
|
b=a.binary.read_bytes()
|
||
|
|
pe=struct.unpack_from('<I',b,0x3c)[0]
|
||
|
|
if b[:2]!=b'MZ' or b[pe:pe+4]!=b'PE\0\0' or struct.unpack_from('<H',b,pe+4)[0]!=0x8664:raise ValueError('Expected AMD64 PE')
|
||
|
|
n=struct.unpack_from('<H',b,pe+6)[0];optional=struct.unpack_from('<H',b,pe+20)[0]
|
||
|
|
pattern=re.compile(rb'[\x48\x4c][\x8b\x8d][\x05\x0d\x15\x1d\x25\x2d\x35\x3d].{4}',re.S)
|
||
|
|
results=[]
|
||
|
|
for i in range(n):
|
||
|
|
off=pe+24+optional+i*40
|
||
|
|
virtual,rva,size,raw=struct.unpack_from('<IIII',b,off+8)
|
||
|
|
flags=struct.unpack_from('<I',b,off+36)[0]
|
||
|
|
if not flags&0x20000000:continue
|
||
|
|
for m in pattern.finditer(b[raw:raw+size]):
|
||
|
|
address=rva+m.start()
|
||
|
|
if address+7+struct.unpack_from('<i',m[0],3)[0]==a.target:results.append(address)
|
||
|
|
print('\n'.join(hex(x) for x in results[:128]))
|
||
|
|
print('references',len(results))
|