"""Find the resolved NE targets for the top-called wrapper functions.""" import json with open(r'k:\ghidra\Crusader_Decomp\ne_reloc_fixups.json') as f: fixups = json.load(f) by_off = {f['source_file_offset']: f for f in fixups} # Top wrappers: look up what their internal CALLF targets are wrappers = { '0003:ac9c': 'FUN_0003_ac7e inner CALLF (272 callers, alloc wrapper)', '0003:a75a': 'FUN_0003_a751 inner CALLF (207 callers, 2-arg forward)', '0008:bb4f': 'FUN_0008_bb4f (174 callers)', } def g2f(a): s,o = a.split(':') return (int(s,16)<<16) + int(o,16) for addr, desc in wrappers.items(): flat = g2f(addr) for delta in range(0, 5): if flat + delta in by_off: m = by_off[flat + delta] print(f"{addr} ({desc})") print(f" -> {m.get('target','?')} (ghidra: {m.get('target_ghidra','?')})") break else: print(f"{addr} ({desc}) — NOT FOUND in fixups") # Also look up 000a:44fd — it had no function, check if it's data or seg boundary print() print(f"Checking 000a:44fd — flat 0x{g2f('000a:44fd'):X}") print(f" This is file offset 0xA44FD") # Find which NE segment contains this import csv with open(r'k:\ghidra\Crusader_Decomp\crusader_ne_segments.csv') as f: reader = csv.DictReader(f) for row in reader: seg_off = int(row['FileOffset'], 16) seg_len = int(row['Length'], 16) if seg_off <= 0xA44FD < seg_off + seg_len: print(f" In NE segment {row['Segment']}: file 0x{seg_off:X}, len 0x{seg_len:X}") print(f" Offset within segment: 0x{0xA44FD - seg_off:X}") break # Also check what calls 000a:44fd (search for its Ghidra address in call patterns) print() seg91_calls = [f for f in fixups if f.get('target_ghidra') == '000a:44fd'] print(f"Calls to 000a:44fd (seg091:00fd): {len(seg91_calls)} total") # Show first 5 callers for c in seg91_calls[:5]: src_flat = c['source_file_offset'] - 1 src_ghidra = f"{src_flat>>16:04x}:{src_flat&0xFFFF:04x}" print(f" from {src_ghidra} (seg{c['source_seg']:03d}+0x{c['source_offset_in_seg']:04x})")