Crusader_Decomp/tmp_inspect_regret_debug_patch_sites.py
2026-04-10 18:14:55 +02:00

87 lines
2.7 KiB
Python

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 selector_to_segment_index(selector):
return ((selector - 0x1000) // 8) + 1
def get_segment_info(data, selector):
ne_off = u32(data, 0x3C)
seg_table_off = ne_off + u16(data, ne_off + 0x22)
align_shift = u16(data, ne_off + 0x32)
seg_index = selector_to_segment_index(selector)
seg_entry_off = seg_table_off + (seg_index - 1) * 8
sector = u16(data, seg_entry_off)
seg_len = u16(data, seg_entry_off + 2)
if seg_len == 0:
seg_len = 0x10000
flags = u16(data, seg_entry_off + 4)
seg_file_off = sector << align_shift
reloc_off = seg_file_off + seg_len
reloc_count = u16(data, reloc_off)
return {
'selector': selector,
'segment_index': seg_index,
'segment_file_off': seg_file_off,
'segment_len': seg_len,
'flags': flags,
'reloc_off': reloc_off,
'reloc_count': reloc_count,
}
def read_relocs(data, seg_info):
relocs = []
pos = seg_info['reloc_off'] + 2
for i in range(seg_info['reloc_count']):
relocs.append({
'index': i,
'record_off': pos,
'src_type': data[pos],
'flags': data[pos + 1],
'src_off': u16(data, pos + 2),
'b4': data[pos + 4],
'b5': data[pos + 5],
'target_off': u16(data, pos + 6),
'raw': data[pos:pos + 8],
})
pos += 8
return relocs
def dump_site(data, seg_info, site, size=16):
raw = seg_info['segment_file_off'] + site
print(f'site {seg_info["selector"]:04X}:{site:04X} -> file 0x{raw:X}: {data[raw:raw+size].hex(" ")}')
def main():
path = Path(r'd:\Ghidra\Crusader\REGRET.EXE')
data = path.read_bytes()
for selector in (0x1148, 0x13F8):
info = get_segment_info(data, selector)
print(f'selector 0x{selector:04X} -> segment index {info["segment_index"]}, file 0x{info["segment_file_off"]:X}, len 0x{info["segment_len"]:X}, reloc@0x{info["reloc_off"]:X}, count={info["reloc_count"]}')
relocs = read_relocs(data, info)
interesting = []
if selector == 0x1148:
interesting = [0x3678, 0x36C0, 0x3702, 0x3743]
else:
interesting = [0x10FA, 0x2040, 0x209F, 0x20B9]
for site in interesting:
dump_site(data, info, site, 24)
local_hits = [r for r in relocs if site <= r['src_off'] <= site + 0x80]
for r in local_hits[:20]:
print(f' reloc idx={r["index"]} rec@0x{r["record_off"]:X} src=0x{r["src_off"]:04X} bytes={r["raw"].hex(" ")}')
print('')
if __name__ == '__main__':
main()