"""Patch hardcoded C:\ path prefixes out of HAVOC_NOCD.EXE so it loads files from the current directory instead of C:\ root.""" exe = bytearray(open("HAVOC_NOCD.EXE", "rb").read()) # Each tuple: (bytes_to_find, bytes_to_replace, description) # Lengths must match -- we strip "C:\" (3 bytes) and pad with nulls at the end. patches = [ # C:\MUSIC.FF\0 (12 bytes) -> MUSIC.FF\0 + 3 nulls ( bytes([0x43,0x3a,0x5c,0x4d,0x55,0x53,0x49,0x43,0x2e,0x46,0x46,0x00]), bytes([ 0x4d,0x55,0x53,0x49,0x43,0x2e,0x46,0x46,0x00,0x00,0x00,0x00]), "C:\\MUSIC.FF -> MUSIC.FF", ), # C:\INTRFACE.FF\0\0 (16 bytes) -> INTRFACE.FF\0 + 4 nulls ( bytes([0x43,0x3a,0x5c,0x49,0x4e,0x54,0x52,0x46,0x41,0x43,0x45,0x2e,0x46,0x46,0x00,0x00]), bytes([ 0x49,0x4e,0x54,0x52,0x46,0x41,0x43,0x45,0x2e,0x46,0x46,0x00,0x00,0x00,0x00,0x00]), "C:\\INTRFACE.FF -> INTRFACE.FF", ), # C:\WORLDS\ \0\0 (12 bytes) -> WORLDS\ \0 + 4 nulls ( bytes([0x43,0x3a,0x5c,0x57,0x4f,0x52,0x4c,0x44,0x53,0x5c,0x00,0x00]), bytes([ 0x57,0x4f,0x52,0x4c,0x44,0x53,0x5c,0x00,0x00,0x00,0x00,0x00]), "C:\\WORLDS\\ -> WORLDS\\", ), # C:\BIGFILE.DAT\0\0 (16 bytes) -> BIGFILE.DAT\0 + 4 nulls ( bytes([0x43,0x3a,0x5c,0x42,0x49,0x47,0x46,0x49,0x4c,0x45,0x2e,0x44,0x41,0x54,0x00,0x00]), bytes([ 0x42,0x49,0x47,0x46,0x49,0x4c,0x45,0x2e,0x44,0x41,0x54,0x00,0x00,0x00,0x00,0x00]), "C:\\BIGFILE.DAT -> BIGFILE.DAT", ), ] for search, replace, desc in patches: assert len(search) == len(replace), f"Length mismatch for {desc}: {len(search)} vs {len(replace)}" idx = bytes(exe).find(search) if idx == -1: print(f" NOT FOUND (check bytes): {desc}") # print surrounding bytes for debugging # try to find just the ascii part ascii_part = bytes(b for b in search if 0x20 <= b < 0x7f) idx2 = bytes(exe).find(ascii_part) if idx2 != -1: print(f" ASCII match at 0x{idx2:06x}: {bytes(exe[idx2-4:idx2+len(ascii_part)+4]).hex(' ')}") continue exe[idx:idx+len(replace)] = replace print(f" OK 0x{idx:06x}: {desc}") open("HAVOC_NOCD.EXE", "wb").write(exe) print("\nDone. HAVOC_NOCD.EXE no longer needs C:\\ symlinks for file loading.")