Recently I found a Ghidra plugin that did not have a build for the current version for Ghidra I was using, and this motivated me to figure out how to build a plugin from its source. After looking around, I did not find many writeups on building existing plugins. This writeup covers both building out the development environment that could be used for writing plugins and extending Ghidra itself and then how to compile the plugin.
Create Build Environment
The first thing you will need to do is create a development environment for compiling the plugin. I found this fantastic article from Void Start Security describing creating a Ghidra development environment using the ghidra-builder Docker container and helper scripts. I made a fork for the repo, integrating the article’s changes and other enhancements. This makes it pretty to create an image used moving forward. Here are the commands I used.
# Clone the repository $ git clone https://github.com/suidroot/ghidra-builder.git $ cd ghidra-builder # Build the Docker image $ docker-tpl/build
After the Docker image build completed, you will have two options building the plugin; you can build against the Dev source tree or the Public release. First, I will cover the Public build preparation steps.
Prepare for a Public Build
Building a plugin against the current Public build is pretty straightforward. First, you will download the current archive from the NSA Github and extract it to a folder you will create named out in the ghidra-builder folder structure. In my example, I saved the file to the ‘Downloads‘ folder in my home directory. The example commands I ran are:
# Starting in the root of the ghidra-builder folder $ mkdir out && cd out # Downloaded the current Public release to Downloads $ cp ~/Downloads/ghidra_10.1.1_PUBLIC_20211221.zip . $ unzip ghidra_10.1.1_PUBLIC_20211221.zip Archive: ghidra_10.1.1_PUBLIC_20211221.zip .... snip...
The following section covers creating a development archive of Ghidra.
Prepare for a Dev Build
To make a Dev build of a plugin, you will first need to make a development build of Ghidra. The script build_ghidra.sh (part of this container) automatically clones from the GitHub repository, builds the source and places an archive in the out folder.
$ cd workdir $ ../docker-tpl/run ./build_ghidra.sh
After the build of Ghidra has been completed successfully, you will need to expand the archive created by the build into the out folder.
$ cd out/ $ ls ghidra_10.1.1_DEV_20220103_linux_x86_64.zip $ unzip ghidra_10.1.1_DEV_20220103_linux_x86_64.zip Archive: ghidra_10.1.1_DEV_20220103_linux_x86_64.zip creating: ghidra_10.1.1_DEV/ ... snip ... inflating: ghidra_10.1.1_DEV/Extensions/Ghidra/ghidra_10.1.1_DEV_20220103_SleighDevTools.zip creating: ghidra_10.1.1_DEV/Ghidra/Extensions/ $ cd ..
Now that we have the environment setup, we can build the plugin from its source.
Build the plugin
I initially found these instructions in wrongbaud’s posts about plugin development. In the out directory, you will need to clone or download the source of the plugin you are building. The connect to a shell in the Docker container and navigate into the source directory for the plugin. Then set the location of the Ghidra build’s directory you prepared earlier in a shell environment variable. Finally, execute the gradle command to build the plugin.
$ cd out $ git clone https://github.com/felberj/gotools.git Cloning into 'gotools'... remote: Enumerating objects: 146, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (3/3), done. remote: Total 146 (delta 0), reused 1 (delta 0), pack-reused 143 Receiving objects: 100% (146/146), 38.12 KiB | 424.00 KiB/s, done. Resolving deltas: 100% (45/45), done. $ ../docker-tpl/run /bin/bash +++ dirname ../docker-tpl/run ++ cd ../docker-tpl ++ pwd + start_dir=/home/locutus/src/ghidra-builder/docker-tpl + build_command=/bin/bash + image=dukebarman/ghidra-builder + docker run -it -v /home/locutus/src/ghidra-builder/workdir:/files -w /files --user dockerbot:dockerbot --rm dukebarman/ghidra-builder sh -c /bin/bash dockerbot@c7310895154d:/files$ cd gotools/ dockerbot@c7310895154d:/files/gotools$ export GHIDRA_INSTALL_DIR=/files/out/ghidra_10.1.1_DEV/ dockerbot@c7310895154d:/files/gotools$ gradle Welcome to Gradle 7.3! .... snip .... BUILD SUCCESSFUL in 56s 7 actionable tasks: 7 executed dockerbot@c7310895154d:/files/gotools$ ls dist/ ghidra_10.1.1_DEV_20220103_gotools.zip
Now you have built the plugin for the version of Ghidra! You can install the zip archive in the version of Ghidra you are running that you built for or are using.