-
Notifications
You must be signed in to change notification settings - Fork 1
GhidraPlugin_Development
Building and running the project requires at least JDK-11
and python 3.8
. Furthermore ghidra
needs to be installed.
The plugin is build using gradle. To get started simply set the GHIDRA_INSTALL_DIR
environment variable and run ./gradlew
.
This builds and packages the plugin. In addition to the compiled jar the python scripts inside the py_scripts
directory are also packaged.
The packaged plugin can then be found in the dist
directory. The package can then be installed through the ghidra GUI.
For development purposes the ./rebuild.sh
script can be used. It builds and installs the plugin automatically. Furthermore ghidra is started in development mode with logs visible in stdout/stderr.
This plugin consists of two major parts. The ghidra side is written in java and mainly provides the GUI. Since angr is can only be used with python3, the angr part is located in an external python script which is called via a java processbuilder. The communication between java and python is done through a yaml file. See the section below for the specification.
glitch_request:
mainOptions:
pathToBinary: "path/to/binary" # The path to the binary that should be loaded
angrBackend: "elf|mach-o|pe|blob" # The type of binary used
arch: "arch specification (e.g. arm)" # The system architecture of the binary
entryPoint: "0x00400000" # When using the blob backend the entrypoint needs to be specified
baseAddress: "0x00400000" # When using the blob backend angr needs to now at which address the binary needs to be loaded
useBlankState: false # Start execution at the address specified at "blankStateStartAt"
blankStateStartAt: ""
findOptions:
findAddress: "0x004007e4" # The Address angr searches for
avoidAddresses: [] # A list of addresses angr avoids
useCustomFindFunction: false # use a custom find function instead of the find address
customFindFunction: "" # The custom find function. See notebook section for an example. Can be a yaml multiline string to deal with escaping problems
stateModificationOptions:
memoryModifications: # A list of memory modifications
- address: "0x1FE" # Address which should be modified
value: "0x21435487" # Value which should be stored in "address"
length: 4 # The length of the value in bytes
glitchOptions:
instructions: # List of instructions at which a glitch should be tested
- address: "0x0040076c"
- address: "0x0040076e"
glitch_response:
contains a list of all instructions that led to a successful glitch.
- glitchAddress: '0x00400780' # The address of the glitch
paths: # The path toward the glitch
- blocks: # The path consists of multiple blocks
- address: '0x500010' # each block has a starting address
instructionAddrs: []
- address: '0x400650'
instructionAddrs: # each block can have multiple instructions. These are listed here
- '0x400650'
- '0x400654'
- '0x400658'
- '0x40065c'
instructionCount: 24 # sum of instructions over all blocks
- glitchAddress: '0x004007a0'
paths:
- blocks:
- address: '0x500010'
instructionAddrs: []
- address: '0x400650'
instructionAddrs:
- '0x400650'
- '0x400654'
- '0x400658'
- '0x40065c'
instructionCount: 46
The core of every plugin is the plugin class (GhidraFaultInjectorPlugin
) which extends ProgramPlugin
. Here all components needed for the plugin are initialised. For the fault-injector plugin two main components are initialised.
The GhidraFaultInjectorProvider
is responsible for the main GUI while the GhidraFaultInjectorListingContextAction
is responsible for creating the context menu that is shown in ghidras code view.
The main window is created in GhidraFaultInjectorProvider
. The window consists of a JTabbedPane
which creates a panel with multiple tabs which can be clicked to change the subpannel that is currently shown. For the fault-injector plugin two tabs were used, the glitch option
and the result tab which are created in the buildPanel
method. Each of the tabs consist of multiple panels. These panels can be found in the panels
package. Each panel extends the JPanel
class and contains a method to build the respective panel. In addition to that
the panels used in the glitch option tab have a getOptions method that collects all the input and returns it as an object. Each panel has an associated model which can be found in the model
package.
Since the number/features of available components in swing are quite small, Ghidra provides additional components that should be used if applicable. The VariableHeightPairLayout
component provides a layout option that makes it easy to create label/input field pairs.
Components like GCheckBox
or AddressInput
help with maintaining the ghidra look and feel.
In java swing the GUI runs on the same thread as the rest of the code which results in the GUI becoming unresponsive while a background task is running. Ghidra provides a task scheduler to solve this problem. Tasks run in a separate thread so the GUI stays responsive during long running tasks.
Currently the plugin uses one task. The FindGlitchTask
is responsible for writing/reading the yaml for communicating with the python part.
Furthermore the task creates a subprocess that runs the python script responsible for running angr.
Context actions are defined in the GhidraFaultInjectorListingContextAction
class which extends Ghidras ListingContextAction
class. Inside the class multiple context actions can be added. They all follow the same scheme. First a ListingContextAction
with an implemented
actionPerformed
method is created. actionPerformed
defines what action should be performed when the context action is clicked. Next the context action has to be assigned to a menu path. This is done as follows:
contextAction.setPopupMenuData(new MenuData(new String[]{
MENUNAME,
"Path",
"TO Action"
}));
Lastly the contextAction needs to be added to the plugin to become available: pluginTool.addAction(setBlankStateAddress);