#!/usr/bin/env python3 """ xref.py -- locate a string in FLYK.EXE's data object, find code that references its address (absolute imm32 operands), and disassemble a window around each reference. Used to reverse the boot-handshake path: anchor on the error/format strings we saw at runtime, then read the surrounding logic to learn exactly what the board must send. python xref.py FLYK.EXE "velocirender_input failed" python xref.py FLYK.EXE 0x00041234 # disasm at a VA """ import sys, struct from leimage import LE from capstone import Cs, CS_ARCH_X86, CS_MODE_32 def le32(v): return struct.pack('= va-3 and ins.address <= va+1 else "" print(f" {ins.address:#010x} {ins.mnemonic:7} {ins.op_str}{mark}") if arg.startswith('0x'): va = int(arg, 16) print(f"--- disasm @ {va:#x} ---"); disasm(va, 0, 160); return needle = arg.encode('latin1') soffs = find_all(data, needle) if not soffs: print("string not found in data object"); return for so in soffs[:4]: sva = dbase + so # show the full string end = data.find(b'\x00', so) s = data[so:end].decode('latin1', 'replace') print(f'\n=== string @ {sva:#x}: "{s}" ===') # Watcom LE stores the OBJECT-RELATIVE offset in code; the fixup adds the base. refs = find_all(code, le32(so)) or find_all(code, le32(sva)) if not refs: print(" (no code references found)") for r in refs[:6]: rva = cbase + r print(f" referenced by imm32 at code VA {rva:#x}:") disasm(rva, 40, 40) print() if __name__ == '__main__': main()