"""build_patched_binary.py Build acclient.eor.patched.exe by applying the v3b byte patches to a backed-up copy of the original EoR acclient.exe. Patches (file offsets = VA - 0x400 since base=0x400000 and .text RVA is +0x400): - VA 0x0053effe ff 40 24 -> 90 90 90 ; NOP makeModifiedPalette() over-increment - VA 0x0053f19c ff 46 24 -> 90 90 90 ; NOP makeModifiedPalette(id,sub) over-increment For 32-bit PE with base=0x00400000 and .text starting at RVA 0x1000 mapped to file offset 0x400 (standard MSVC layout), file_offset = VA - 0x00400000 - 0x1000 + 0x400 = VA - 0x00400C00. """ import hashlib, os, shutil, struct, sys SRC = r"C:\Turbine\Asheron's Call\acclient.exe" ORIG = r"C:\Turbine\Asheron's Call\acclient.eor.orig.exe" PATCHED = r"C:\Turbine\Asheron's Call\acclient.eor.patched.exe" # VA-based patches (we resolve file offsets via PE parsing) PATCHES = [ (0x0053effe, bytes([0xff, 0x40, 0x24]), bytes([0x90, 0x90, 0x90])), (0x0053f19c, bytes([0xff, 0x46, 0x24]), bytes([0x90, 0x90, 0x90])), ] def parse_pe_sections(data): """Return list of (rva_start, rva_size, file_offset) tuples.""" e_lfanew = struct.unpack_from(" " f"{' '.join(f'{b:02x}' for b in patched_bytes)}") elif actual == patched_bytes: print(f" VA 0x{va:08x} already patched, skipping") else: print(f" VA 0x{va:08x} UNEXPECTED bytes: {' '.join(f'{b:02x}' for b in actual)}") sys.exit(2) with open(PATCHED, "wb") as f: f.write(data) sha_new = hashlib.sha256(bytes(data)).hexdigest() print(f"\npatched sha256: {sha_new}") print(f"written: {PATCHED}") if __name__ == "__main__": main()