Files
dragon-hd/tools/disasm.py

47 lines
1.5 KiB
Python

import struct, sys
from capstone import *
exe = r"F:\steam\steamapps\common\The I of the Dragon\TheIOfTheDragon.exe"
data = open(exe, "rb").read()
e_lfanew = struct.unpack_from("<I", data, 0x3C)[0]
coff = e_lfanew + 4
machine, nsec, tstamp, symptr, nsym, optsize, chars = struct.unpack_from("<HHIIIHH", data, coff)
opt = coff + 20
imagebase = struct.unpack_from("<I", data, opt+28)[0]
sec_off = opt + optsize
sections = []
for i in range(nsec):
o = sec_off + i*40
name = data[o:o+8].rstrip(b"\x00").decode("latin1")
vsize, vaddr, rawsize, rawptr = struct.unpack_from("<IIII", data, o+8)
sections.append((name, vaddr, vsize, rawptr, rawsize))
def va2off(va):
rva = va - imagebase
for name, sva, vs, rp, rs in sections:
if sva <= rva < sva+max(vs, rs):
return rp + (rva-sva)
return None
md = Cs(CS_ARCH_X86, CS_MODE_32)
md.detail = True
def show(fileoff, n=60, before=6):
start = fileoff - before
# linear disasm from section start is messy; assume instruction boundary is ok-ish
code = data[start:start+ n*8]
# compute VA
rva = None
for name, sva, vs, rp, rs in sections:
if rp <= start < rp+rs:
rva = sva + (start-rp); base = imagebase
addr = imagebase + rva
print(f"### disasm at file {start:#x} VA {addr:#x}")
for ins in md.disasm(code, addr):
print(f" {ins.address:08x}: {ins.mnemonic:8s} {ins.op_str}")
import sys
args = sys.argv[1:]
for a in args:
show(int(a,16))