import shutil
import os
def patch_exe(input_path, output_path, old_text, new_text):
# Convert strings to UTF-16LE bytes
old_b = old_text.encode("utf-16le")
new_b = new_text.encode("utf-16le")
if len(new_b) > len(old_b):
raise ValueError(
f"\nERROR: Replacement text is longer than the original text.\n"
f"Original: '{old_text}' ({len(old_b)} bytes)\n"
f"New: '{new_text}' ({len(new_b)} bytes)"
)
# Pad replacement with null bytes
new_b = new_b + b"\x00" * (len(old_b) - len(new_b))
# Create a copy first
shutil.copy2(input_path, output_path)
with open(output_path, "r+b") as f:
data = f.read()
count = data.count(old_b)
if count == 0:
print(f"\nWARNING: '{old_text}' was not found in the file.")
return
print(f"\nFound {count} occurrence(s).")
data = data.replace(old_b, new_b)
f.seek(0)
f.write(data)
f.truncate()
print("\nPatch completed successfully.")
print(f"Patched file: {output_path}")
# ----------------------------
# Main Program
# ----------------------------
print("=" * 60)
print("EXE String Patcher")
print("=" * 60)
input_file = input("\nEnter source EXE path: ").strip()
if not os.path.isfile(input_file):
print("\nERROR: File not found.")
input("\nPress Enter to exit...")
exit()
output_file = input(
"\nEnter output EXE path (patched copy): "
).strip()
old_text = input(
"\nEnter text to search for: "
).strip()
new_text = input(
"\nEnter replacement text: "
).strip()
print("\nSummary")
print("-" * 60)
print(f"Source : {input_file}")
print(f"Output : {output_file}")
print(f"Find : {old_text}")
print(f"Replace with: {new_text}")
confirm = input("\nProceed? (Y/N): ").strip().upper()
if confirm != "Y":
print("\nCancelled.")
input("\nPress Enter to exit...")
exit()
try:
patch_exe(
input_file,
output_file,
old_text,
new_text
)
except Exception as e:
print(f"\nERROR: {e}")
input("\nPress Enter to exit...")