Preserving Your Digital Sandcastles with an IDA Plugin
You might be wondering what sandcastles have to do with reverse engineering and IDA plugins. Bear with me here; it’s not as far off as you might think.
When we’re at the beach, building sandcastles can be a joyous, engrossing task. We invest time, effort, and creativity into constructing our tiny kingdoms. Yet, as we all know, the next wave or high tide can wash away all that hard work in an instant, leaving no trace of the intricate designs we’d assembled. Perhaps you have experienced this, or witnessed it happen to others.
In a similar vein, in the world of reverse engineering, we often spend countless hours disassembling, analyzing, and documenting functions in a piece of software. Just like the unrelenting ocean waves, software updates can sweep in and erase all our efforts. Imagine this: the game you’re reverse engineering updates on Steam, you load the latest .exe into IDA, and it feels as though you’re starting from scratch again. Wouldn’t it be great if we could ‘preserve’ the functions we’ve painstakingly reversed and named, just like saving our carefully built digital sandcastles?
Signatures are byte patterns found in memory, serving as an effective tool for identifying specific parts of a binary. These byte patterns, which can look something like
48 8B 1D ? ? ? ? ? ? ? 10 4C 8D 4D ? 4C, work as a sort of ‘fingerprint’ for a block of code. The power of signatures lies in their ability to remain consistent even when the base address of an application changes, or even sometimes when certain parts of the code are modified.
Consider an game that has regular updates. Each time you get a new version, the location of functions can change, making static addresses unreliable for identifying specific memory locations. This is where signatures come in: a particular byte pattern will remain the same across different instances of the application, even when the base address or some offsets change. This consistent pattern can be used to locate the same block of code reliably, making it an essential tool in reverse engineering.
While reverse engineering with IDA, there are various tools and plugins available to help us work with these signatures. A few examples include BinDiff, Diaphora, FLIRT Signatures, and Lumina.
This is a comparison tool for binary files that helps to discover differences in code and data. More details can be found in the BinDiff manual.
A sophisticated diffing tool for IDA, allowing you to compare two binaries to find similarities and differences. This is particularly useful when dealing with different versions of the same application or looking for shared code between two different applications. More details here.
FLIRT Signatures (Fast Library Identification and Recognition Technology)
These are sets of signatures, provided by IDA, for identifying standard library functions. This technology significantly reduces the amount of manual work required in identifying library code. More about FLIRT Signatures can be read on the IDA website.
Lumina is a service provided by Hex-Rays that collects and shares metadata about well-known functions, including their names, prototypes, comments, and operand types. The metadata can greatly improve the disassembly listing. What’s unique about Lumina is that IDA does not send actual byte patterns to the server; instead, it sends hash values, which are enough for Lumina to find the corresponding metadata. Users can choose to use the public Lumina server hosted by Hex-Rays, or set up their own private Lumina server. Currently, Lumina supports x86/x64, ARM, PowerPC, and MIPS files, with more to come in the future. Further information can be found on the Lumina page.
In this post, we’ve merely introduced these tools and their general use in handling signatures. We won’t delve into detailed usage instructions here. However, keep an eye out for future posts where I plan to dive deeper into some tool and how to effectively utilize them in your reverse engineering workflow.
IDA CFS Plugin
As beneficial as existing solutions can be, I found the need to create my own, particularly for dealing with substantial IDA databases. On occasion, working with large databases can lead to lockups and freezes when using other tools.
Increasingly, I found myself reverse engineering functions, naming them, and subsequently creating signatures. I stored these in a Notepad++ tab for future reference. Whenever I worked on a later version of the software, I would attempt to search for these signatures and name them again in a new database.
This workflow went on until my frustration prompted me to create a solution. The result was the creation of my own Signature File Format called CFS, short for Cra0 Function Signature. The format is straightforward, storing function names and corresponding signatures.
To facilitate the use of this format, I developed two basic plugins for IDA to handle the exporting and importing of these signatures. These allow you to export signatures of selected functions in IDA which then can be used to input them back into a new database. You can also edit the signatures with a text editor if you’re not happy with them.
Further work needs to be done to make these plugins more versatile, this is a starting point and works for my use case.
Step 1. Open an IDA database of your choice.
Step 2. In the Functions window, select the functions you want to preserve. Right-click and select Export Signatures. You will then be prompted to choose a name and a location to save the .cfs file.
Step 3. In another IDA instance, load the binary you’re working with. Go to File -> Load file -> CFS File… and select the .cfs file in the explorer window.
IDA will now perform pattern searches and apply what it finds. If a function doesn’t exist at a certain address, it will attempt to create and define it for you. This is particularly useful for unpacker dumps that scramble the binary or strip runtime information, making it harder for IDA to determine where functions start and end.
Note: By design, if there are multiple search hits for a certain pattern (which is quite likely to occur), the plugin will not rename or take any action; it will instead print that information in the console. Feel free to modify this behavior or raise an issue on GitHub.
Note 2: Functions that have been named (i.e., those not starting with
sub_) will not be renamed or affected.
Download the two python files and place them in your IDA installation’s
I hope you found this post useful. In a future article, I’ll guide you through the use of BinDiff and demonstrate how to create your own FLIRT library signatures with IDA. Until then, happy reversing! ✌️