22 lines
1.1 KiB
Python
22 lines
1.1 KiB
Python
"""Find bounded E8/E9 references to an explicit AMD64 PE code RVA, offline."""
|
|
import argparse,re,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),action='append',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];found={target:[] for target in a.target}
|
|
for i in range(n):
|
|
off=pe+24+optional+i*40
|
|
virtual,rva,size,raw=struct.unpack_from('<IIII',b,off+8)
|
|
if not struct.unpack_from('<I',b,off+36)[0]&0x20000000:continue
|
|
section=b[raw:raw+size]
|
|
for m in re.finditer(rb'[\xe8\xe9].{4}',section,re.S):
|
|
address=rva+m.start()
|
|
target=address+5+struct.unpack_from('<i',m[0],1)[0]
|
|
if target in found:found[target].append(address)
|
|
for target,refs in found.items():
|
|
if len(found)>1:print('target',hex(target))
|
|
print('\n'.join(hex(x)for x in refs[:128]));print('references',len(refs))
|