A blog on reverse engineering technology and reverse engineering technology.
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.
Potentially delete the version (or all) folders in ~/.ghidra/
(careful they are hidden inside too!) to make sure no previous configuration is loaded instead.
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.
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.
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
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.
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.
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
Choose File -> New -> Project from Existing Sources
and select the ghidra
folder that is the root of the checked out git repository.
Choose Eclipse
from Import project from external model
. The resulting project has more information than if importing from Gradle
.
Leave the defaults in the next screen, or change them if you know what you are doing. I don’t.
Import all Eclipse projects
Use the default code style of IntelliJ. The eclipse files do not seem to contain one.
Select 11
as your project SDK. The home path should be something that explicitly contains java-11-openjdk
so it does not break when your system updates to a newer Java version.
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.
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.
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.