Reversing Technology

A blog on reverse engineering technology and reverse engineering technology.


Ghidra Dev without Eclipse Part 2: Editing and Building From Source

This post will cover building and starting Ghidra as a dev version from the git. This is slightly different to what is explained in the official development setup which relies on the Eclipse plugins for some step. It assumes Ghidra 9.1 due to some features introduced in that version that make the setup significantly easier.

Setup Dev setup without any IDE

Potentially delete the version (or all) folders in ~/.ghidra/ (careful they are hidden inside too!) to make sure no previous configuration is loaded instead.

Initial Setup

The initial setup is the same as explained in the dev guide. Follow it to the point that you can run the following commands without gradle failing:

git clone --depth=1 git@github.com:NationalSecurityAgency/ghidra.git
cd ghidra
gradle --init-script gradle/support/fetchDependencies.gradle init
gradle prepDev
gradle buildNatives_linux64 # or whatever your OS is
gradle eclipse

You can add --parallel to all the gradle commands which can significantly speed up the download and build tasks. This is especially relevant for the init task. This might potentially lead to weird issues like checksum errors, in those cases just delete the offending file and run the command again.

Building

The task to build the classes is the (default?) gradle task classes.

gradle classes --parallel

This will place the compiled classes into the build/ folder relative to the module root.

Running

This section was edited on 2022-09-20 to reflect some changes introduced by a specific commit that was part of Ghidra 10. Thanks to @_gipi_ for pointing out to me that this wasn’t working anymore!

The details and reasons behind this are explained in the post on the debug setup, though

New Way (Ghidra 10 and onwards)

The command to start java is:

java \
-Djava.system.class.loader=ghidra.GhidraClassLoader \
-DbinaryPath=build/classes/java/main:build/resources/main/:bin/default/:src/main/resources/ \
-cp ./Ghidra/Framework/Utility/build/classes/java/main/ \
ghidra.GhidraLauncher ghidra.GhidraRun

Add -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5009 to start the Java debug listener.

Old Way (Ghidra 9)

Now you can start Ghidra with the following java command:

java \
-Djava.system.class.loader=ghidra.GhidraClassLoader \
-DbinaryPath=build/classes/java/main:build/resources/main/:bin/default/:src/main/resources/ \
-Xbootclasspath/a:./Ghidra/Framework/Utility/build/classes/java/main/ \
-cp ./Ghidra/Framework/Utility/ \
ghidra.GhidraLauncher ghidra.GhidraRun

The -Xbootclasspath argument results in the GhidraClassLoader being loaded in a subtly different way, which somehow leads to this check returning true. This isn’t exactly intended behavior, but it works.

Add -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5009 to start the Java debug listener.

Integration into IntelliJ

Initial Setup

Same as above, except --depth=1 removed because you probably want the history for annotations.

git clone git@github.com:NationalSecurityAgency/ghidra.git
cd ghidra
gradle --init-script gradle/support/fetchDependencies.gradle init
gradle prepDev
gradle buildNatives_linux64 # or whatever your OS is
gradle eclipse

Import

You should now have the Ghidra source tree as a project in IntelliJ. IntelliJ should detect the Gradle build script and prompt you in the lower right corner. Click Import Gradle Project to import it so you can use the gradle tasks.

IntelliJ should now start indexing the source files.

Build

The default build button, the green hammer, will not work. IntelliJ tries to compile tests and ghidra_scripts which will fail because their imports cannot be resolved. I have not found a way to get IntelliJ to ignore them, but workaround is simple enough that I did not investigate this thoroughly.

IntelliJ can parse the gradle tasks and use them. The most important ones are:

classes

This builds the .class files of nearly everything. For some reason that doesn’t include the Version Tracking under some circumstances, if that is an issue change the directory to ./Ghidra/Features/VersionTracking and run gradle classes there. The .class files will be put into the build folder relative to the respective module root. This is not where a running instance of Ghidra expects them to be by default. For details and running Ghidra see the respective separate blogpost.

buildGhidra

Creates a .zip release like the ones downloadable from the website. This should work like a regular release build so if you cannot get something to work with the dev setup that works with the release setup, you can still use this to have a test release with custom fixes.

Conclusion

This setup allows you to easily read the source code of some release or commit and thus help you to understand how Ghidra works internally. Running and debugging will be the topic of the next blogpost.