## Ghidra Advanced Development Class

Topics

- Ghidra and Eclipse Background
- Development and Extensions
- Program API vs Flat Program API
- Scripting
- Plugins
- Ghidra GUI Components
- Handling Binary Formats
- Writing Analyzers
- Writing Binary Loaders
- Writing File System Loaders
- Writing Languages: Sleigh
- Building your Extension

## What is Ghidra?

What is Ghidra?

- Integrated environment for software reverse engineering ("IDE" for SRE)
- Developed by NSA Research
- Written almost entirely in Java
- Some native code (C/C++, Objective-C, Assembly)

What is Ghidra?

- Consists of six major parts

- Programs
- Plugins
- Scripts
- Tools
- Project Manager
- Server

Programs

- Information stored about a binary/executable in a Ghidra database

- Symbols
- Bytes / Memory
- References
- Instructions / Data
- Comments
- ...etc.

Plugins

- Each plugin provides a specific functionality
- All plugins communicate within the tool
- Users can choose which plugins are active
- Users can write their own plugins
- Written in Java
- Preferred IDE is Eclipse with GhidraDev

- Others possible, but not supported

Scripts

- Can be written in Java or Python
- Extensible to other JVM-based languages
- Simplifies Ghidra programming API
- Full API is still available
- Run-time compilation for fast dev cycles
- Preferred IDE is Eclipse with GhidraDev

- Ghidra provides very basic editor without Eclipse
- Others possible, but not supported

Tools

- Collection of plugins and state
- Ghidra includes pre-configured tools

- Code Browser
- Version Tracker

- Extensions may provide more

Project Manager

- Manages projects, tools, and data for a particular group of programs
- Programs must be imported into a project before work can be done
- Project configurations are saved for future use

Server

- Used when multiple users want to collaborate on the same project
- Provides network shared repository
- Provides user access control
- Keeps revision history (like Subversion)
- Supports check-in, check-out, history
- Does not support branching

Why Use Ghidra?

- Tools can dynamically share data
- Designed to handle large data sets
- Supports teaming
- Highly configurable environment
- Highly extensible via plugins and scripts
- Multi-platform (Linux, Mac, Windows)

How to Install Ghidra

- Install the required version of Java
- Extract the Ghidra distribution .zip
- For development, install a supported version of Eclipse
- See the documentation for version requirements

## What is Eclipse?

Eclipse

- Integrated Development Environment (IDE)

- Java, C/C++, Python, and more!

- Can be used for script development
- Can be used for extension development

Eclipse

- To integrate with Ghidra:

- Install the GhidraDev plugin
- Connect Ghidra to GhidraDev/Eclipse
- GhidraDev is distributed with Ghidra
- See "GhidraDev_README.html"

Eclipse

- Eclipse Java Editor Tips and Tricks (1/3)

- Open Type: Ctrl Shift T

- Allows you to find a class without knowing the package

- Organize Imports: Ctrl Shift O

- Automatically fixes import statements

- Navigate to: F3

- Navigate to the class, method, variable, etc., at the current cursor location

Eclipse

- Eclipse Java Editor Tips and Tricks (2/3)

- Type Hierarchy: F4

- Show inheritance hierarchy of current class/interface

- Find References to: Ctrl Shift G

- Finds all references to the item at current cursor location

- Toggle Comments: Ctrl /

- Comment or uncomment the selection

Eclipse

- Eclipse Java Editor Tips and Tricks (3/3)

- Outline View: Ctrl O

- Lists members of the class

- Code Completion: Ctrl Space

- Displays a list of matches to complete the current expression

- Quick Fix: Ctrl 1

- Offer corrections to most problems (errors, warnings, etc.)

Eclipse

- Provides templates and common tasks for Ghidra development
- GhidraDev New Ghidra Module Project
- GhidraDev New Ghidra Script
- GhidraDev Export Ghidra Module Extension

Lab 1

- Launch Ghidra through Eclipse in debug mode

## Development

Development

- Every piece of Ghidra is extensible

- Plugins, Scripts, Analyzers, Fields, Importers, Exporters, etc.

- Extensible components implement ExtensionPoint

- List suffix in ExtensionPoint.manifest

- Create a New Ghidra Module Project...

- You may be prompted to locate Ghidra

## Anatomy of an Extension Project

Extension Project

- MyExtension/

- src/main/java/
- src/main/help/
- src/main/resources/
- ghidra_scripts/
- data/
- lib/
- os/
- extension.properties
- Module.manifest

Extension Project
src/main/java/
src/main/resoures/

- Hold the Java source for this extension
- Packaged into a .jar file
- Add src/test/java/ manually to include unit tests

- Unit tests are not included in the .jar file

Extension Project
src/main/help/

- Holds online help for this extension
- Contains the table of contents to append
- Contains the CSS and HTML contents
- Java help does not support the latest HTML/CSS. Please preview using the help viewer rather than your browser.

Extension Project
ghidra_scripts/

- Holds scripts for this extension
- Expect the user to copy and modify scripts
- Unpacked as source to the file system on installation
- May provide examples to use an extension's API

Extension Project
data/

- Holds data files for this extension
- Will not end up inside the .jar file
- Will be present in the distribution .zip file
- Unpacked to the file system on installation
- Allows user to easily edit or append data compared to resources in the .jar

Extension Project
lib/

- Holds external Java dependencies for this extension
- When working in Eclipse, the contents of this directory must be manually added to the class path of the Eclipse project
- Optional

- This directory may be deleted if there are no external dependencies

Extension Project
os/

- Holds native components for this extension
- Optional

- This directory may be deleted if there are no native components

- NEVER EVER USE JNI!

- Communicate with a native process using sockets, I/O stream, etc.

Extension Project

- os/
  - linux64/
  - Linux x86_64 natives
  - osx64/
  - Mac OSX x86_64 natives
  - win64/
  - Windows x64 natives

Lab 2

- Create a new Ghidra module project
- From the Eclipse menu bar, select:

- GhidraDev New Ghidra Module Project

- In the "Module name" field, enter "gadc"
- Click the "Finish" button to complete

## Program API

High-Level Classes

Note: this diagram is not complete.

## Flat vs. Program API

Program API

- Ghidra Program API

- Object-Oriented
- Very deep
- Can change from version to version

- Program

- Listing

- Instructions
- Data
- Functions
- Comments

- Memory

- Memory Blocks
- Bytes

- Symbol Table

- Symbols

- Reference Manager

- References

- Memory
- Stack
- External

- ...etc.

Flat Program API

- Flat
- Provides access to most common features
- Is not complete
- Will not change on you*

Flat Program API
public class FlatProgramAPI { FlatProgramAPI(Program) analyze() clear...() create...() find...() get...() remove...() save() set...() to...() }

## Scripting

Scripting

- Script Manager

- Script Category Tree

- Displays dynamic tree of categories

- Script Table

- Displays name, description, key binding

- Filter

- Matches filter to name or description
- Wildcard and case-insensitive

Scripting

- Script Directories

- Allows management of script directories
- Default directories

- HOME/ghidra_scripts/
- INSTALL/Features/Base/ghidra_scripts/
- Each other module/ghidra_scripts/

- Useful for sharing scripts in multi-user

Scripting

- GhidraScript API

public abstract class GhidraScript extends FlatProgramAPI { ask...() create...() get...() goto...() print...() run...() to...() }
Scripting

- Sample script template in Java

- Must fill in the TODO areas
- Create a description
- Fill in the `run()` method

//TODO add description here //TODO add metadata here public class MyScript extends GhidraScript { public void run() throws Exception { //TODO add code here } }
Scripting

- Script Meta-data

- Special tags in header comment
- Describe the script
- All are optional
- Handle all the messy Java GUI stuff (buttons, menus, etc.)
- Do not insert blank lines between meta-data

Scripting

- Script Meta-data

- `@category`

- The category path for the script
- Levels are separated by "."
- Example

- `@category A.B.C`

Scripting

- Script Meta-data

- `@keybinding`

- Default key binding for a script
- Format is `[ctrl] [alt] [shift] [A-Z,0-9,F1-F12]` and is case-sensitive
- Examples

- `@keybinding L`
- `@keybinding ctrl alt shift F1`
- `@keybinding ctrl shift COMMA`

Scripting

- Script Meta-data

- `@menupath`

- Top-level menu path for a script
- Use with caution!

- Overcrowded menu
- Collide with system action

- Example

- `@menupath File.Run.My Script`

Scripting

- Script Meta-data

- `@toolbar`

- Image for top-level toolbar button to launch this script
- Searches for image in script directories and then Ghidra installation directory
- Also use with caution! (same issues as `@menupath`)
- Example

- `@toolbar myScriptImage.gif`

Scripting

- Script State (1/3)

- `currentProgram`

- The current active open program

- `currentAddress`

- The current address of the location of the cursor

- `currentLocation`

- The program location of the cursor

Scripting

- Script State (2/3)

- `currentSelection`

- The current selection or `null` if no selection exists

- `currentHighlight`

- The current highlight or `null` if no highlight exists

- `state`

- Provides place to store environment variables
- Static and non-static

Scripting

- Script State (3/3)

- `monitor`

- Allows script writer to inform user

- messages and progress

- Allows user to cancel script
- Always use inside loops

while (!monitor.isCancelled()) { ... }
Console

- Provides a place to dump information
- Any text representing a symbol or address can be navigated by double-clicking
- Example

- Run PropagateExternalParametersScript.java

## Scripting Lab

Lab 3

- Create a new Java script: Lab3Script.java
- Set the description
- Set category: Category A.Category B
- Set key binding: Alt Shift 6
- Set menu path: Script My Class Script
- Set toolbar button: Info.png
- Change the body of the `run()` method to: println("Hello class");
- Save it
- Run it

Lab 3 Answer
//It prints "Hello class" to the console. //@category Category A.Category B //@keybinding alt shift 6 //@menupath Script.My Class Script //@toolbar Info.png import ghidra.app.script.GhidraScript; public class Lab3Script extends GhidraScript { @Override public void run() throws Exception { println("Hello class"); } }
Lab 4

- Create new script that will ask for an integer and print the current program's name that many times to the console

Lab 4 Answer
//Ask for an integer and print the current //program’s name that many times to the console //@category GADC import ghidra.app.script.GhidraScript; public class Lab4Script extends GhidraScript { @Override public void run() throws Exception { int n = askInt("How Many Times?", "N"); for (int i = 0; i < n; ++i) { if (monitor.isCancelled()) { break; } println(i + ". " + currentProgram.getName()); Thread.sleep(1000); } } }
Lab 5

- Write a script that will search for instructions that move a scalar into a register
- Pull the scalar from the instruction and create an EOL comment in the form:

- setting [register] = [value]

Lab 5 Answer
//This script searches through all instructions that are //moving a scalar into a register //and sets an EOL comment in the form "[register] = [value]" //@category GADC import ghidra.app.script.GhidraScript; import ghidra.program.model.lang.Register; import ghidra.program.model.listing.Instruction; import ghidra.program.model.scalar.Scalar; public class Lab5Script extends GhidraScript { @Override public void run() throws Exception { for (Instruction instruction = getFirstInstruction(); instruction != null; instruction = getNextInstruction()) { if ( monitor.isCancelled() ) { break; } if (instruction.getNumOperands() != 2) { continue; } Object[] opObjects0 = instruction.getOpObjects(0); if (opObjects0.length != 1 || !(opObjects0[0] instanceof Register)) { continue; } Object[] opObjects1 = instruction.getOpObjects(1); if (opObjects1.length != 1 || !(opObjects1[0] instanceof Scalar)) { continue; } Register register = (Register) opObjects0[0]; Scalar scalar = (Scalar) opObjects1[0]; String comment = "[" + register.getName() + "]=[" + scalar.toString(16, false, false, "", "") + "]"; setEOLComment(instruction.getMinAddress(), comment); } } }

## Headless Scripting

Headless Scripting

- Ghidra can be run from the command line without invoking the user interface
- Can be run on one or more programs
- Any script that does not invoke the GUI can be run in headless mode
- See analyzeHeadlessREADME.html

## Plugins

Plugins

- Must extend Plugin class
- Can provide and consume services
- Can provide actions

- Extend DockingAction

- Can provide GUIs

- Extend ComponentProvider

Plugins

- Must provide a plugin description

- Use the @PluginInfo annotation

- In constructor

- Register provided service implementations

- In `init()`

- Retrieve services consumed
- Create actions

- In `dispose()`

- Release resources

ProgramPlugin

- Extends Plugin class
- Adds helper methods for events

- Program activated/deactivated
- Location changes
- Selection changes
- Highlight changes

Lab 6

- Create a plugin: AdvancedGhidraClassPlugin
- Extend ProgramPlugin
- Apply the @PluginInfo annotation
- Restart Ghidra
- Verify plugin displays in the "Configure" dialog

## Docking Windows

GUIs

- Ghidra has custom docking window components
- We recommend you use our components

- GTable, GTree, GComboBox
- Provide:

1. Custom filtering
2. Event handling
3. Threaded models
4. Navigation
5. Look-and-feel

Docking Windows

- Allow users to customize the layout of components within a tool
- Title bar
- Local toolbar
- Menu icon
- Close button
- Arranging components

- Mouse cursor provides feedback
- Components can be stacked, docked, or floating

Actions

- Right mouse actions are context sensitive

- This is determined by the plugin author

- List of actions that appear will change based on where the cursor is located
- User can assign/override key bindings

Tables

- Use GTable
- Filters
- Columns
- Export to CSV

Trees

- Use GTree
- Filters
- Lazy loading to support large data

Lab 7

- Add a global action to the plugin
- Make the action popup a dialog message
- Use Ghidra’s dialog class OptionDialog

## Component Provider

ComponentProvider

- Managed GUI component in the tool
- Created and added to the tool by the plugin myComponent = new MyComponent(...); tool.addComponent(this, myComponent);
- Components can be permanent or transient

- Permanent - are always available in Window menu and closing just hides them (e.g., Listing)
- Transient - created on the fly and when closed are destroyed and removed from Window menu (e.g., Search Results)

- See ComponentProviderAdapter class

Lab 8

- Create a ComponentProvider that contains only a JLabel
- Update your previously-created plugin to add this component to the tool
- Override the `programActivated()` method to update the label with the name of the active program

Lab 9

- Add a local action to the component provider
- Make the action toogle the label's background color between red and blue

Lab 10 (Optional)

- Add a GTable to the component
- Change the global action to search for instructions that move a scalar into a register
- Populate the table with the search results (include an address column at minimum)

## Handling Binary Formats

Binary Formats

- Included formats:

- ELF, PE, Mach-O, and more!

- What is needed for a new format?

- Data structure to parse the format
- Analyzers to annotate the binary format
- Loader for Ghidra's importer
- Language, if not currently supported

A Toy Format
The "Ghidra Format" (see ghidra.h): struct ghidra_header { char magic[6]; // magic number identifier unsigned byte cputype; // cpu specifier unsigned short nsections; // number of sections unsigned short nsymbols; // number of symbols unsigned int flags; // flags }; struct ghidra_section { // for 32-bit architectures char name[16]; // name of this section unsigned int addr; // memory address of this section unsigned int size; // size in bytes of this section unsigned int offset; // file offset of this section unsigned int flags; // flags (section type and attributes }; struct ghidra_symbol { // for 32-bit architectures char name[25]; // name of this symbol unsigned int addr; // memory address of this symbol unsigned short type; // type of this symbol };
Lab 11

- Create classes to parse Ghidra format binaries
- Each class must have a constructor that takes a BinaryReader parameter
- Each class must implement StructConverter
- In this lab, you will need to create:

1. class GhidraFormatHeader
2. class GhidraFormatSection
3. class GhidraFormatSymbol
4. class GhidraFormatConstants

- See ghidra.h for detailed definitions
- For examples, see Img3* classes

## Analyzers for Raw Binary Files

Analyzers

- Must implement the Analyzer interface

// Display name, input type, priority String getName(); AnalyzerType getAnalysisType(); AnalysisPriority getPriority(); // Called for changes to analyzer inputs boolean added(...); boolean removed(...); // Register and react to user options void registerOptions(...); void optionsChanged(...);
Lab 12

- Create an analyzer to annotate a raw Ghidra format binary

- Place header data structures in listing

## Loaders

Loaders

- Must implement Loader interface

- Consider AbstractProgramLoader

package ghidra.app.util.opinion; // By convention public class MyLoader implements Loader { Collection<LoadSpec> findSupportedLoadSpecs(...); List<DomainObject> load(...); ... }

- Must update the .opinion file for each processor supported by the format

Lab 13

- Create a loader for Ghidra format binaries
- Be sure to update the .opinion files:

- x86.opinion
- PowerPC.opinion
- ARM.opinion

Lab 14

- Write an analyzer that searches for instructions that move a scalar into a register
- Pull the scalar from the instruction and create an EOL comment in the form:

- setting [register] = [value]

- Note: you already did this in a script!

## File System Loaders

File System Viewer

- Provides an alternative importer
- Allows importing many programs from a single archive or image
- Extensible using GFileSystem interface

- Consider GFileSystemBase class

File System Viewer

- Drills down into file systems, including nested file systems
- Extract files
- Import binaries
- Perform static analysis
- View as text
- View as image (i.e., picture)

Lab 15

- Create a GFileSystem for OSX Universal Binary (UBI), also known as Fat Binary

- See FatHeader

- Ghidra already contains code to parse this format
- Use these parser classes to implement a GFileSystem to open universal binary files

Lab 16

- Put several universal binaries into a .zip file
- Verify the File System Browser plugin can handle nested universal binaries

## Sleigh

Sleigh

- Used to disassemble binary into assembly
- Used to decompile assembly into C
- Decompiler optimizes
- Can be applied to any binary, assuming:

- Sleigh language with pCode exists
- See GhidraInstall/Ghidra/Processors

- Performs data type propagation
- Commit parameter / return types
- Decompiler Parameter ID analyzer

Lab 17

- Change `R2` in the 8051 language to `R2D2`

- GhidraInstall/Ghidra/Processors/8051/data/languages/8051_main.sinc

- Restart Ghidra
- Import any program as a raw binary and select 8051 as the language
- Verify the register is changed

## Making a Build of Your Extension

Making a Build

- From Eclipse:

- Select GhidraDev Export Ghidra Module Extension in the menu bar
- Select your module from the "Ghidra module project" drop-down
- Click the "Finish" button

Making a Build (alt)

- You must have a compatible version of Gradle installed
- From the command line (bash):

cd /path/to/extension export GHIDRA_INSTALL_DIR=/path/to/ghidra gradle extensionDistZip #Substitute extension name

- Output goes into build/distributions/
- Gradle supports incremental builds: It only rebuilds what has changed since last build
- Use the `clean` task first if you want to rebuild everything

Lab 18

- Build your extension!