Alex Rivera | Logout

Calculating Binary Data Similarity

Asked 2009-02-24T00:21:08.490
39

I've seen a few questions here related to determining the similarity of files, but they are all linked to a particular domain (images, sounds, text, etc). The techniques offered as solutions require knowledge of the underlying file format of the files being compared. What I am looking for is a method without this requirement, where arbitrary binary files could be compared without needing to understand what type of data they contain. That is, I am looking to determine the similarity percentage of two files' binary data.

To give a little more detail for you to work with, even though this is potentially applicable to many things, I do have a specific problem that I'm working on. I also currently have a working solution, but I don't think that it is ideal. There are probably many optimizations in terms of the comparison method, and storing the results. Hopefully some people here will be able to give me some new ideas. I will probably edit in some information about my current method after a couple of days, but I don't want to bias peoples' thoughts about the problem by telling you how I'm already doing it.

The problem I'm working on is clone detection for video game ROM images. For those that don't have experience with emulation, ROMs are dumps of the data on game cartridges. A ROM "clone" is typically a modified version of the same game, the most common type being a translated version. For example, the Japanese and English versions of the original Final Fantasy for the NES are clones. The games share almost all of their assets (sprites, music, etc), but the text has been translated.

There are currently several groups that work on maintaining lists of clones for the various systems, but as far as I can tell, this is all done manually. What I am attempting to do is find a method to detect similar ROM images automatically and objectively, based on data similarity instead of "these seem like the same game

Edit
Report

2 Answers

12

You might want to look at bsdiff, which is a binary diffing/patching system. There is also a thesis with lots of theory.

answered 2009-02-24T00:30:42.850
2

The difficulty here is that since you are dealing with executable code, simple changes can propagate across the entire ROM. The addresses and offsets for ALL values can change with the addition of a single variable or no-op instruction. That will make even block-based hashing worthless.

A quick-and-dirty solution would be to hack up a solution with difflib (or the equivalent w/ your favorite language), since it gets you a sliding comparison that can deal with data addition or removal. Split the ROM into executable and data sections (if possible). The data section can be compared directly and a similarity ratio calculated, though you'll still have problems w/ addresses or offsets.

The executable section is more interesting. Read up on the machine's asm format, take the executable and split it into a sequence of opcodes. Leave the opcode and register parts, but mask off the "payload" / "immediate" parts (where it loads the variable addresses). Hand the resulting info to the similarity ratio calculator too.

The unfortunate part is that this is still an O(n^2) operation on the number of ROMs you track, but that can be alleviated with (incremental) clustering or a frequency-based comparison order to reduce the amount of comparisons needed.

answered 2009-03-08T19:47:22.783

Your Answer