Ruby, Kotlin, Groovy, Clojure, and JShell support for Ghidra.
Check out the
releases page
for the latest release build of the plugin. After downloading, you can
install this in Ghidra by going to File->Install Extensions...
, choosing
the Add Extension
option, and then navigating to the downloaded zip file.
You'll be prompted to restart Ghidra for the new extension to be active.
You will then need to activate the plugin before using it. You might get
prompted to do this next time you open the CodeBrowser tool, in which case you
can simply select OK. Otherwise, you can manually activate it by opening the
CodeBrowser tool, going to File->Configure...
, and selecting the RubyDragon
plugin for Ruby, the KotlinDragon
plugin for Kotlin, the JShellDragon
plugin
for the Java interpreter, and the ClojureDragon
plugin for Clojure. They
should appear in the Ghidra Core
listing, but you can check the Configure All Plugins
option if you aren't able to find them.
If you need to remove a language plugin, you can do so by unchecking the box in
the configuration dialog in the CodeBrowser tool. If you want to remove the
extension as a whole, you'll also need to uncheck it in the Install Extensions
menu from the project browser, and finally restart Ghidra. You may also need to
manually delete the folder from your
.ghidra/<ghidrainstall>/Extensions
folder to completely remove it,
particularly if you want to load the plugin via the Eclipse plugin for
development.
Once the RubyDragon plugin is enabled, you will be able to open an interactive
Ruby session from the CodeBrowser tool by going to Window->Ruby
, or by
clicking on the Ruby icon in the toolbar. This is a IRB session provided by
JRuby.
The same environmental variables provided in Java and Python scripts are also available in this session along with a few extras, as the following global variables:
$current_address
$current_api
$current_data
$current_function
$current_highlight
$current_instruction
$current_location
$current_program
$current_selection
The $current_api
variable is an instance of FlatProgramAPI
created with
$current_program
. This has many (but not all) of the convenience functions
that would be available within a GhidraScript
instance.
Many classes provided by Ghidra can be automatically imported into the
interactive terminal so you don't need to use java_import
statements to use
them. If you want to customize this you can modifiy the auto-import.xml
data
file in the installation. To enable this feature (it does impact startup time)
then you can enable the relevant option in the Ruby Dragon Interpreters
category. This is done for all other languages as well, using the same data
file.
You can also write scripts in Ruby, much the same way as you would with Java or
Python. Ruby will be available as a new script type, and you can see several
example scripts in the Examples.Ruby
directory of the Script Manager that
show basic usage of both JRuby and Ghidra basics. Scripts also have an
additional global variable $script
that provides access to the RubyScript
instance for them.
The same global variables available in the interactive sessions are also provided for scripts to use in the same manner.
You can also find help directly in the Ghidra help menu (press F1
) on the
Ghidra Functionality->Scripting->Ruby Interpreter
page.
If you want to install gems to be available in your interactive interpreter or scripts, then you'll need to take a few extra steps, depending on how isolated you want the gem environment to be.
If you're using something like rvm to manage your Ruby environment, then you can
simply rely on this to have already set the GEM_PATH
environment variable to
point to your gem installation. For maximum success however, you should switch
to a JRuby installation, ideally of the same version as packaged in RubyDragon,
and let rvm point to a gemset within that.
If you want the Ghidra gem set to be specific to Ghidra, or if you don't have a
Ruby environment outside of Ghidra to point to, you can choose a location on
your own and set the GEM_PATH
environment variable to point to that. To
install new gems to the path, invoke the version of gem
from the bundled JRuby
jar like so, changing version and paths as needed. Here the gem path will be set
to ~/ghidra_gems
# from a shell environment
java -jar ~/.ghidra/.ghidra_10.2_PUBLIC/Extensions/RubyDragon/lib/jruby-complete-9.3.9.0.jar -S gem install -i ~/ghidra_gems wrapture
REM from a windows command line
java -jar %USERPROFILE%\.ghidra\.ghidra_10.2_PUBLIC\Extensions\RubyDragon\lib\jruby-complete-9.3.9.0.jar -S gem install -i %USERPROFILE%\ghidra_gems wrapture
Once this is done, you can require the wrapture
gem (or whatever you chose
to install) from scripts and the interactive terminal.
If you don't want to create an environment variable in your global
configuration, you'll need to mess with the script used to launch Ghidra in
order to set GEM_PATH
appropriately. You can do this by adding a set
command in launch.bat
or launch.sh
(depending on your OS). For Windows
systems, you'll also need to remove the /I
parameter from the start
command used to launch Ghidra so that the environment variable is passed on.
Kotlin is used in much the same way as the Ruby toolset with some obvious
differences, such as being provided by the KotlinDragon
plugin and being
reached from the Window->Kotlin
menu option. The built in variables for
scripts and the interpreter window in Kotlin are the same as Java:
currentAddress
currentAPI
currentData
currentFunction
currentHighlight
currentInstruction
currentLocation
currentProgram
currentSelection
Kotlin scripts use a kts
extension as they are interpreted as scripts rather
than being compiled to java first.
Groovy follows the same patterns as the other languages, being provided in the
GroovyDragon
plugin and reachable from the Window->Groovy
menu option. It
has the same built-in variables that the others provide:
currentAddress
currentAPI
currentData
currentFunction
currentHighlight
currentInstruction
currentLocation
currentProgram
currentSelection
Clojure follows the same patterns as the other languages, being provided in the
ClojureDragon
plugin and the menu item Window->Clojure
.
The Clojure interpreter and scripts also have bindings that make the state
information available to them, within the ghidra
namespace. They are:
ghidra/current-address
ghidra/current-api
ghidra/current-data
ghidra/current-function
ghidra/current-highlight
ghidra/current-instruction
ghidra/current-location
ghidra/current-program
ghidra/current-selection
ghidra/current-api
is provided as the instance of FlatProgramAPI
created
with currentProgram
, as with the other interpreters. The automatic import of
Ghidra classes is also done in the ghidra
namespace.
And, as with Ruby, a ghidra/script
binding is available within scripts that
provides access to the underlying ClojureScript
instance. Unlike Ruby however,
this variable does not allow access to protected fields or private methods.
These are instead injected into the ghidra
namespace as well. For example, to
access the TaskMonitor
for a script, you can simply reference ghidra/monitor
to do things like update the progress. The Clojure Ghidra Basics script has an
example of this type of access. Those familiar with the Python scripting
interface may recognize this paradigm, as it is the same there.
The JShell plugin provides an interactive Java interpreter by JShell, a Java REPL included in Java. It provides the same built in variables that are available in Java scripts:
currentAddress
currentAPI
currentData
currentFunction
currentHighlight
currentInstruction
currentLocation
currentProgram
currentSelection
This interpreter is especially handy when writing Java scripts, as it allows you to iteratively test snippets of code from the script without needing to do any sort of conversion to other languages like Python or Kotlin.
Right now, the easiest way to contribute is to post any suggestions or try it out and open an issue if you have any problems. Head over to the issue list to join the discussion!
If you're feeling adventurous, you can add an example script in your language
of choice. This could be an equivalent to one of the scripts that come packaged
with Ghidra, or it could be all new! Just be sure you add a test for it in the
Github Action workflow so that it isn't broken later on. Check out the
ghidra_scripts
folder to see what's there now, and perhaps draw some
inspiration on what you could add.
Or, if all of that is a bit much, just give us a shoutout at #GhidraRubyDragon on Twitter with your thoughts!