39 lines
1.3 KiB
Python
39 lines
1.3 KiB
Python
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
|
||
|
|
def u16(data, off):
|
||
|
|
return data[off] | (data[off + 1] << 8)
|
||
|
|
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
|
|
||
|
|
data = bytearray(Path(r'd:\Ghidra\Crusader\REGRET.EXE').read_bytes())
|
||
|
|
code_off = 0xD2840
|
||
|
|
code = bytes.fromhex('55 8B EC 56 57 53 06 A1 2C 71 8B 16 2E 71 0B C2 74 4E C4 5E 06 83 EB 36 26 8B 47 02 D1 E0 D1 E0 C4 1E 30 44 01 C3 26 8B 37 26 8B 7F 02 8B C6 0B C7 74 2D C4 5E 06 26 FF B7 E3 00 26 FF B7 E1 00 26 FF B7 DC 00 26 FF B7 DA 00 26 FF B7 D8 00 26 FF B7 D6 00 57 56 52 50 9A FF FF 00 00 83 C4 14 FF 76 0C FF 76 0A FF 76 08 FF 76 06 9A FF FF 00 00 83 C4 08 07 5B 5F 5E 5D CB')
|
||
|
|
set_bytes(data, code_off, code)
|
||
|
|
patches = {
|
||
|
|
0xD2C94: bytes.fromhex('03 00 FB 10 80 00 40 20'),
|
||
|
|
0xD2E0C: bytes.fromhex('03 00 99 20 7D 00 F5 02'),
|
||
|
|
0xD2E14: bytes.fromhex('03 00 AD 20 7F 00 8B 03'),
|
||
|
|
}
|
||
|
|
for off, blob in patches.items():
|
||
|
|
set_bytes(data, off, blob)
|
||
|
|
|
||
|
|
for rec_off in [0xD2C94,0xD2E0C,0xD2E14,0xD2E1C]:
|
||
|
|
rec = data[rec_off:rec_off+8]
|
||
|
|
src = u16(rec, 2)
|
||
|
|
segidx = rec[4]
|
||
|
|
target_off = u16(rec, 6)
|
||
|
|
selector = 0x1000 + ((segidx - 1) << 3)
|
||
|
|
op_off = 0xD0800 + src
|
||
|
|
set_u16(data, op_off, target_off)
|
||
|
|
set_u16(data, op_off+2, selector)
|
||
|
|
|
||
|
|
print('2040-20dc=', data[0xD2840:0xD28DD].hex(' '))
|