reccmp
(recompilation comparison) is a collection of tools for decompilation projects. It was born from the decompilation of LEGO Island. Functions and data are matched based on comments in the source code. For example:
// FUNCTION: LEGO1 0x100b12c0
MxCore* MxObjectFactory::Create(const char* p_name)
{
// implementation
}
This allows you to automatically verify the accuracy of re-compiled functions, virtual tables, variable offsets and more. See here for the full syntax.
At the moment, C++ compiled to 32-bit x86 with old versions of MSVC (like 4.20) is supported. Work on support for newer MSVC versions is in progress - testing and bug reports are greatly appreciated. Other compilers, languages and architectures are not supported at the moment, but feel free to contribute if you wish to do so!
- (Recommended) Set up and activate a virtual Python environment in the directory of your recompilation project (this is different for different operating systems and shells).
- Install
reccmp
:pip install https://github.com/isledecomp/reccmp
The next steps differ based on what kind of project you have.
- Compile the C++ project.
- Run
reccmp-project detect --search-path path/to/folder/with/original/binaries
. - If there is no
reccmp-build.yml
after building: Navigate to the recompiled binaries folder and runreccmp-project detect --what recompiled
. - Look into
reccmp-project.yml
to see what the target is called. - Run
reccmp-reccmp --target <YOURTARGET>
. You should see a list of functions and others together with their match percentage.
- Run
reccmp-project create --originals path/to/original --scm
. This generates two filesreccmp-project.yml
andreccmp-user.yml
; the latter will automatically be added to the.gitignore
. - Annotate one function of your existing project as shown above and recompile. Note that the recompiled binary should have the same name file name as the original.
- Navigate to your recompiled binary and run
reccmp-project detect --what recompiled
. A filereccmp-build.yml
will be generated. This file should also be user-specific (see below on how to auto-generate this file by the build toolchain). - Look into
reccmp-project.yml
to see what the target is called. - Run
reccmp-reccmp --target <YOURTARGET>
from the same directory. If all goes well, you will see match percentage of the function you annotated above.
- Run
reccmp-project create --originals path/to/original/binary --cmake-project
- You will see a lot of new files. Set up your C++ compiler and compile the project defined by
CMakeLists.txt
, ideally into a sub-directory like./build
. Advice on building with old MSVC versions can be found at the LEGO Island Decompilation project. - Look into
reccmp-project.yml
to see what the target is called. - Navigate to the build directory and run
reccmp-reccmp --target <YOURTARGET>
.
All scripts will become available to use in your terminal with the reccmp-
prefix. Note that these scripts need to be executed in the directory where reccmp-build.yml
is located.
decomplint
: Checks the decompilation annotations (see above)- e.g.
reccmp-decomplint --module LEGO1 LEGO1
- e.g.
reccmp
: Compares an original binary with a recompiled binary, provided a PDB file. For example:- Display the diff for a single function:
reccmp-reccmp --target LEGO1 --verbose 0x100ae1a0
- Generate an HTML report:
reccmp-reccmp --target LEGO1 --html output.html
- Create a base file for diffs:
reccmp-reccmp --target LEGO1 --json base.json --silent
- Diff against a base file:
reccmp-reccmp --target LEGO1 --diff base.json
- Display the diff for a single function:
stackcmp
: Compares the stack layout for a given function that almost matches.- e.g.
reccmp-stackcmp --target BETA10 0x1007165d
- e.g.
roadmap
: Compares symbol locations in an original binary with the same symbol locations of a recompiled binaryverexp
: Verifies exports by comparing the exports of the original DLL and the recompiled DLLvtable
: Asserts virtual table correctness by comparing a recompiled binary with the original- e.g.
reccmp-vtable --target LEGO1
- e.g.
datacmp
: Compares global data found in the original with the recompiled version- e.g.
reccmp-datacmp --target LEGO1
- e.g.
There are existing scripts to import the information from the decompilation into Ghidra. See the relevant README for additional information.
We have established some best practices that have no impact on reccmp
's output, but have made a positive impact on the LEGO Island decompilation. We have listed them here for convenience.
Feel free to contribute to this project if you are interested! More information can be found at CONTRIBUTING.md.