Skip to content

Instantly share code, notes, and snippets.

@Dither
Last active July 3, 2016 15:08
Show Gist options
  • Save Dither/76768479fe0a51003e4b to your computer and use it in GitHub Desktop.
Save Dither/76768479fe0a51003e4b to your computer and use it in GitHub Desktop.
Python binary patcher for .dif files
#!/usr/bin/env python
# Small .dif patcher for Python 3+
# File format of .dif file (description and filename should be on the 1st and 3rd lines exactly):
# File description
#
# filename.ext
# 0000000a: 00 01
# 0000000b: 00 02
import re,ntpath,sys
from sys import argv,exit
from ctypes import c_uint8
def path_leaf(path):
head, tail = ntpath.split(path)
return tail or ntpath.basename(head)
def patch(file, dif, revert=False):
code = open(file,'rb').read()
open(file+'.bak','wb').write(code)
dif = open(dif,'r').read()
m = re.findall('([0-9a-fA-F]+): ([0-9a-fA-F]+) ([0-9a-fA-F]+)', dif)
for offset,orig,new in m:
o, orig, new = int(offset,16), int(orig, 16), int(new, 16)
print("%08X: %02X %02X" % (o,orig,new))
if revert:
if code[o]==new:
code = code[:o]+bytes(c_uint8(orig))+code[o+1:]
else:
raise Exception("patched byte at %s is not %02X" % (offset, new))
else:
if code[o]==orig:
code = code[:o]+bytes(c_uint8(new))+code[o+1:]
else:
raise Exception("original byte at %s is not %02X" % (offset, orig))
open(file,'wb').write(code)
def main():
if sys.version_info[0] < 3:
print("Python 3.0 or higher required.")
sys.exit(1)
if len(argv)<2:
print(" ")
print("Usage: %s <.dif file> [-revert]" % path_leaf(argv[0]))
print("Applies given .dif file to a binary; use -revert to revert patch.")
exit(0)
file, dif, revert = "", argv[1], False
diff = open(dif,'r')
for i, line in enumerate(diff):
if i == 2:
file = line.replace('\n', '').replace('\r', '')
break
diff.close()
if len(argv)>2:
revert = True
print("Reverting patch %r on file %r" % (dif, file))
else:
print("Patching file %r with %r" % (file, dif))
try:
patch(file, dif, revert)
print("Done")
except Exception as e:
print("Error: %s" % str(e))
exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment