from pathlib import Path def u16(data, off): return data[off] | (data[off + 1] << 8) def u32(data, off): return u16(data, off) | (u16(data, off + 2) << 16) def main(): path = Path(r"k:\ghidra\Crusader_Decomp\REGRET.EXE") data = path.read_bytes() ne_off = u32(data, 0x3C) seg_table_off = ne_off + u16(data, ne_off + 0x22) align_shift = u16(data, ne_off + 0x32) seg_count = u16(data, ne_off + 0x1C) print(f"NE header: 0x{ne_off:X}") print(f"Segment table: 0x{seg_table_off:X}") print(f"Align shift: {align_shift}") print(f"Segment count: {seg_count}") selector = 0x1148 seg_index = ((selector - 0x1000) // 8) + 1 seg_entry_off = seg_table_off + (seg_index - 1) * 8 sector = u16(data, seg_entry_off) seg_len = u16(data, seg_entry_off + 2) flags = u16(data, seg_entry_off + 4) min_alloc = u16(data, seg_entry_off + 6) seg_file_off = sector << align_shift print(f"Selector 0x{selector:X} -> segment index {seg_index}") print( f"Segment entry @ 0x{seg_entry_off:X}: sector=0x{sector:X} len=0x{seg_len:X} flags=0x{flags:X} min=0x{min_alloc:X} file=0x{seg_file_off:X}" ) for site in (0x3678, 0x36C0, 0x3702): raw = seg_file_off + site print(f"Site 0x{site:04X} -> file 0x{raw:X}: {data[raw:raw+8].hex(' ')}") reloc_off = seg_file_off + seg_len count = u16(data, reloc_off) print(f"Reloc table @ 0x{reloc_off:X}, count={count}") wanted = { 0x3678, 0x3679, 0x367A, 0x36C0, 0x36C1, 0x36C2, 0x3702, 0x3703, 0x3704, } hits = [] pos = reloc_off + 2 for i in range(count): src_type = data[pos] flags = data[pos + 1] src_off = u16(data, pos + 2) payload = data[pos + 4 : pos + 8] if src_off in wanted: hits.append((i, pos, src_type, flags, src_off, payload)) pos += 8 for i, pos, src_type, flags, src_off, payload in hits: print( f"Hit #{i} rec@0x{pos:X}: src_type=0x{src_type:02X} flags=0x{flags:02X} src=0x{src_off:04X} payload={payload.hex(' ')}" ) if __name__ == "__main__": main()