import capstone, struct, sys
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
data = open(r"C:/git/bt411/content/BTL4OPT.EXE","rb").read()
CODE_VA=0x401000; CODE_RA=0xE00
pe = struct.unpack_from("<I", data, 0x3c)[0]
nsec = struct.unpack_from("<H", data, pe+6)[0]
opt=pe+24; szopt=struct.unpack_from("<H",data,pe+20)[0]; sec0=opt+szopt
for i in range(nsec):
    off=sec0+i*40
    name=data[off:off+8].rstrip(b"\0").decode()
    vsz,va,rsz,ra=struct.unpack_from("<IIII",data,off+8)
    if name=="CODE": code_rsz=rsz
pat=b"\x34\x04\x00\x00"
md=capstone.Cs(capstone.CS_ARCH_X86, capstone.CS_MODE_32)
start=0; matched={0x4a1d2d,0x4a22ad,0x4b984b,0x4bacc7,0x4baeb4}
while True:
    idx=data.find(pat,start)
    if idx<0: break
    start=idx+1
    if not (CODE_RA<=idx<CODE_RA+code_rsz): continue
    va=CODE_VA+(idx-CODE_RA)
    ok=False
    for back in range(2,9):
        for ins in md.disasm(data[idx-back:idx-back+16], va-back):
            if "0x434" in ins.op_str and va+4 <= ins.address+ins.size <= va+8:
                ok=True; break
        if ok: break
    if not ok:
        # show raw bytes context for manual inspection
        print(f"UNMATCHED at va {va:08x}: {data[idx-8:idx+8].hex()}")
print("done")
