The International Patching System (IPS) patch format is a historically popular distribution format for ROM hacks. It's a very simple format, and a number of tools exist for creating IPS patches from binary data. I wanted to be able to create IPS patches programatically in Python scripts, however, and no existing library provided that support. So I made one.
I got enough testing and polish done on the library that I chose to upload it to PyPI as a formal Python package. As such, a released version can be acquired by any Python user with pip install ips-util.
(Pretty much straight from the README.)
To create a patch, using existing source and target binary files:
> ips_util create "Super Mario World.smc" "Super Mario World [1337357_h4x_3v4r].smc" -o 1337_p47ch.ips
To apply a patch to a binary file:
> ips_util apply 1337_p47ch.ips "Super Mario World.smc" -o w00t.smc
To dump the contents of a patch:
> ips_util trace 1337_p47ch.ips
The package can also be used within Python scripts to build IPS patches manually, as follows:
from ips_util import Patch
def this_is_my_patch():
patch = Patch()
patch.add_record(0x1234, 999.to_bytes(2, byteorder='little')) # Max out some stat
patch.add_rle_record(0x5678, b'\xea', 0x10) # NOP out a bunch of code
with open('gavroche.ips', 'w+b') as f:
f.write(patch.encode())
The package includes unit tests (contained in the ips_util/tests/test_patch.py script) to verify design requirements and some common edge cases in IPS format:
test_patch_core)test_patch_padding)test_patch_truncation)test_patch_eof_edge_case)Patch.create() API)test_create_equal_length)test_create_padded_length)
test_create_padded_length_all_zero)test_create_truncated_length)test_create_eof_edge_case)test_create_address_overflow)test_create_size_overflow)
test_create_rle_size_overflow)