Today while trying to track down a stray byte I accidentally edited in a binary file I’m hacking, I decided to write my own utility to help in the endeavour.

IPS is a popular file format for representing binary file patches. You can read about the specifics here. Unfortunately, I couldn’t find any utilities that would show the contents of an IPS file in a human-readable format. To be fair, since IPS files just contain hunks of binary data, it’s not exactly easy to make the format human-readable.

But at the very least, one should be able to see a list of hunks, their positions in the file, and the contents of the hunk. A way to compare how these hunks look before and after the patch, given a binary file target, would also be handy.

So I created a utility that does these things. Meet ipsnect. Or possibly IPSnect. I’m not sure which looks better. And yes, the name is just a terrible pun on “ips” and “inspect”.

You can find the utility on its project page on GitHub.

Sample Output

After the Castlevania 3 hack was completed, another ROMhacker became interested in combining the hack with their own hack. This didn’t end up happening, because it was difficult to bridge the versions (mine was for the Japanese ROM, theirs was for the American). For my Castlevania 1 hack, which you can read about here, I use ipsnect in order to comment the individual bytes modified for the benefit of any future hackers interested looking to extend my hack or apply it to their own hack. Here’s what it looks like (current version), if you’re curious:

====== IPS summary ======
This file explains, for any other ROMhackers,
the exact changes made by the IPS file.

This file was generated by IPSnect and
commented manually.
(https://github.com/nstbayless/ipsnect)
===== hunk summary ======
hunks: 4
regular hunks: 4
RLE hunks:     0
sum of hunk lengths: x000000F8 bytes (248 bytes)
========= hunks =========

# 1. Modifies the Jump Table entries for
# Simon's step dispatch. 3C BA and F7 BA are
# the little-endian addresses for the new
# jump and stair-climbing code. Note that
# the original code is still accessed via
# a JMP by the new code.
regular hunk on bytes x01937E-x019385 (8 bytes)
3C BA 11 95 39 95 F7 BA
^  ^              ^  ^

# 2. This is the code that runs when Simon falls
# off of a cliff. Note that it calls additional
# code (see hunk 4 below) as a subroutine.
regular hunk on bytes x0193DA-x0193E8 (15 bytes)
A5 11 8D 88 04 EA A9 01 8D 6C 04 EA 4C E4 BA2

# 3. Originally this code calculated which direction
# Simon should move in while being knocked back.
# Now it jumps to a subroutine in hunk 4 (below).
regular hunk on bytes x01971B-x019722 (8 bytes)
20 9F BA EA EA EA EA EA

# 4. Contains several functions which are invoked
# in the hunks above. Was originally empty
# space in the ROM file (FF).
regular hunk on bytes x01BA4C-x01BB24 (217 bytes)
20 CC BA D0 4C AC 50 04 A5 F7 29 03 D0 07 A9 80
8D 84 05 D0 22 A2 00 4A 90 0A 8E 50 04 A2 81 8E
84 05 B0 09 E8 8E 50 04 A2 82 8E 84 05 AD 34 04
C9 00 F0 03 8C 50 04 A5 F7 29 80 D0 14 AD 14 05
D0 0F AD DC 04 C9 95 30 08 20 90 BA A9 17 8D 88
04 4C 82 94 A9 01 8D 14 05 A9 A2 8D DC 04 60 FF
FF FF FF A5 45 F0 1E 20 CC BA D0 19 AD DC 04 C9
B3 10 12 AD 14 05 F0 0D A5 F7 29 03 F0 06 C9 03
D0 02 A5 00 60 AD 50 04 18 69 01 49 03 60 FF FF
A5 45 F0 02 A5 18 C9 05 60 85 49 AE 50 04 E8 8E
84 05 A9 07 8D 6C 04 60 20 CC BA D0 EC A9 00 8D
4C 05 D0 EC AD F8 04 F0 E7 D0 A0 20 CC BA F0 03
4C 86 95 A5 F5 29 80 F0 F7 AD 34 04 D0 F2 20 0C
94 A9 01 8D 6C 04 4C 82 94

```