Skip to content

cmpf

cmpf (C++ source included) is a cute little tool for finding the differences between a number files. It's a command line tool that takes three parameters, the names of two files to compare and the name of the so called mask file.

When you run the tool the first time it compares the two files and dumps the offsets of the bytes where the files differ to stdout. At the same time it creates the mask file which is used for consecutive comparisons. The mask file is just a file filled with 'C' and 'U' bytes that indicate whether the bytes at the same offset during the comparison were the same or not.
If you want to add another file to the comparison you re-run the tool with the parameters 1st file, 3rd file and mask file. Now the mask file exists and is considered in the comparison. Only bytes that were unchanged during the first comparison and have now changed are printed to stdout.

To make it simple: After n consecutive runs of the tool the bytes that were unchanged n-1 times but changed during the last comparison are printed to stdout.

What's the use of this tool? It makes it very easy to find RAM addresses during NES ROM hacking. Here's an example: I want to find the RAM byte where your health points are stored in Super Mario Bros II.

For this purpose I dump the RAM to a file three times (the careful reader recognizes a new feature in FCEUXD SP 1.05 here). The screenshots below show the game situation of the three dumps.







In the first and second screenshot Toad has full health points, in the third screenshot Toad was hit by a monster and lost one health point.

Now I can run cmpf twice. Let's assume at this point that the three RAM dump files are called 1.ram, 2.ram and 3.ram.

First execution: cmpf 1.ram 2.ram mask
Second execution: cmpf 1.ram 3.ram mask

And here's the output I'm getting. I've successfully reduced the number of possible RAM addresses from 2048 down to only 38. And all of that in less than one minute. Pretty cool, right?
00000068 03 01
0000006E 01 02
00000085 00 7C
00000093 03 01
000000BE 01 00
000000C4 00 10
00000220 AF B7
00000224 AF B7
00000228 BF C7
0000022C BF C7
00000241 FB D0
00000242 41 01
00000245 B8 D2
00000247 10 77
00000251 FB D0
00000252 41 01
00000254 F8 BF
00000255 B8 D2
00000257 10 77
00000260 F8 B7
00000272 01 41
00000285 B8 D6
00000287 10 EB
000002A1 FB D0
000002A2 41 01
000002A5 B8 D2
000002A7 10 77
0000040B 80 00
00000426 00 FE
00000444 05 04
000004C2 1F 0F
00000608 00 04
0000060A 00 81
0000060D 00 08
00000618 05 06
0000061A 05 06
000006F6 00 01
000006F9 03 07

For those wondering: The offset where the health is stored is 0x000004C2 which was 0x1F in the first two RAM dump files and changed to 0x0F in the last dump file.

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

Luiz Carlos Jr. on :

Sp,
I admire your enthusiasm and your work!
Thankz by the info and the post!

Regards, Luiz

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
BBCode format allowed
Form options

Submitted comments will be subject to moderation before being displayed.