Files
dragon-hd/tools/scan_disp.py

46 lines
1.5 KiB
Python

import struct
from capstone import *
exe = r"F:\steam\steamapps\common\The I of the Dragon\TheIOfTheDragon.exe"
data = open(exe, "rb").read()
e = struct.unpack_from("<I", data, 0x3C)[0]
coff = e + 4
nsec = struct.unpack_from("<H", data, coff + 2)[0]
optsize = struct.unpack_from("<H", data, coff + 16)[0]
opt = coff + 20
imagebase = struct.unpack_from("<I", data, opt + 28)[0]
so = opt + optsize
secs = []
for i in range(nsec):
o = so + i * 40
nm = data[o:o+8].rstrip(b"\x00").decode("latin1")
vs, va, rs, rp = struct.unpack_from("<IIII", data, o + 8)
secs.append((nm, va, vs, rp, rs))
text = next(s for s in secs if s[0] == ".text")
name, tva, tvs, trp, trs = text
blob = data[trp:trp+trs]
md = Cs(CS_ARCH_X86, CS_MODE_32)
for tag, dispbytes in [("0x101c metrics", b"\x1c\x10\x00\x00"), ("0x181c flag", b"\x1c\x18\x00\x00")]:
print("================", tag)
i = 0
found = []
while True:
j = blob.find(dispbytes, i)
if j == -1:
break
found.append(j)
i = j + 1
print("byte occurrences:", len(found))
for j in found:
# disassemble a window ending at this disp; the instruction starts a few bytes earlier
start = max(0, j - 6)
addr = imagebase + tva + start
ctx = []
for ins in md.disasm(blob[start:j+8], addr):
ctx.append("%08x: %s %s" % (ins.address, ins.mnemonic, ins.op_str))
print("--- at file 0x%x VA 0x%x" % (j, imagebase + tva + j))
for c in ctx[-3:]:
print(" ", c)