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

100 lines
3.6 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 set_bytes(buf, off, blob):
buf[off:off + len(blob)] = blob
def set_u16(buf, off, value):
buf[off] = value & 0xFF
buf[off + 1] = (value >> 8) & 0xFF
def main():
data = bytearray(Path(r'd:\Ghidra\Crusader\REGRET.EXE').read_bytes())
cleanup_off = 0xD2840
cleanup = bytes.fromhex(
'55 8B EC 8B 46 06 0B 46 08 75 14 6A 26 9A FF FF 00 00 83 C4 02 89 56 08 89 46 06 0B C2 74 38 C4 5E 06 26 C7 47 08 00 00 26 C7 47 06 00 00 26 C7 47 04 00 00 26 C7 47 02 00 00 26 C7 07 FF FF 26 C7 47 20 00 00 26 C7 47 1E 00 00 26 C7 47 24 00 00 26 C7 47 22 00 00 8B 56 08 8B 46 06 5D CB 55 8B EC 56 8B 76 0A 8B 46 06 0B 46 08 74 2C C4 5E 06 26 C7 07 98 02 FF 76 08 53'
)
set_bytes(data, cleanup_off, cleanup)
code_off = 0xD28DD
code = bytes.fromhex(
'55 8B EC 50 52 53 56 57 06 A1 2C 71 8B 16 2E 71 0B C2 75 05 9A FF FF 00 00 A1 2C 71 8B 16 2E 71 0B C2 74 0A 52 50 9A FF FF 00 00 83 C4 04 9A FF FF 00 00 07 5F 5E 5B 5A 58 5D CB 00 8B 46 06 05 28 00 FF 76 08 50 9A FF FF 00 00 83 C4 06 6A 02 8B 46 06 05 1E 00 FF 76 08 50 9A FF FF 00 00 83 C4 06 F7 C6 01 00 74 10 FF 76 08 FF 76 06 9A FF FF 00 00 83 C4 04 EB 02 EB 00 5E'
)
set_bytes(data, code_off, code)
reloc_patches = {
0xD2C94: bytes.fromhex('03 00 FB 10 7F 00 8B 03'),
0xD2E0C: bytes.fromhex('03 00 4E 20 01 00 B4 36'),
0xD2E14: bytes.fromhex('03 00 CF 20 01 00 51 31'),
0xD2E1C: bytes.fromhex('03 00 BB 20 56 00 94 03'),
0xD2E3C: bytes.fromhex('03 00 F2 20 74 00 00 00'),
0xD2E34: bytes.fromhex('03 00 04 21 7D 00 19 04'),
0xD2E2C: bytes.fromhex('03 00 0C 21 74 00 0D 02'),
0x7BB25: bytes.fromhex('03 00 79 36 74 00 00 00'),
0x7BB15: bytes.fromhex('03 00 C1 36 80 00 DD 20'),
0x7BB05: bytes.fromhex('03 00 03 37 80 00 DD 20'),
0x7BAF5: bytes.fromhex('03 00 44 37 80 00 DD 20'),
}
for off, blob in reloc_patches.items():
set_bytes(data, off, blob)
# Simulate relocation fixups for segment 13f8 and 1148 sites we changed.
# Internal ref type 3 writes target offset and target selector into the 4-byte operand.
relocs = [
0xD2C94,
0xD2E0C,
0xD2E1C,
0xD2E14,
0xD2E2C,
0xD2E34,
0xD2E3C,
0x7BB25,
0x7BB15,
0x7BB05,
0x7BAF5,
]
seg13f8_file = 0xD0800
seg1148_file = 0x76E00
for rec_off in relocs:
rec = data[rec_off:rec_off + 8]
src = u16(rec, 2)
target_seg = rec[4]
target_off = u16(rec, 6)
if rec_off >= 0xD2C94:
base = seg13f8_file
else:
base = seg1148_file
op_off = base + src
selector = 0x1000 + ((target_seg - 1) << 3)
set_u16(data, op_off, target_off)
set_u16(data, op_off + 2, selector)
cleanup_loaded = data[0xD2840:0xD28BA]
helper_loaded = data[0xD28DD:0xD2958]
print('cleanup_loaded=', cleanup_loaded.hex(' '))
print('helper_loaded=', helper_loaded.hex(' '))
print('call_10fa=', data[0xD18FA:0xD18FF].hex(' '))
print('call_20f1=', data[0xD28F1:0xD28F6].hex(' '))
print('call_2103=', data[0xD2903:0xD2908].hex(' '))
print('call_210b=', data[0xD290B:0xD2910].hex(' '))
print('call_3678=', data[0x7A478:0x7A47D].hex(' '))
print('call_36c0=', data[0x7A4C0:0x7A4C5].hex(' '))
print('call_3702=', data[0x7A502:0x7A507].hex(' '))
print('call_3743=', data[0x7A543:0x7A548].hex(' '))
if __name__ == '__main__':
main()