# Ghidra Plugin Architecture: How to Create Custom Extensions

> Learn the Ghidra plugin architecture to create custom extensions. Extend Ghidra's reverse-engineering capabilities by developing your own Java plugins using the PluginTool and PluginManager.

- Repository: [National Security Agency/ghidra](https://github.com/NationalSecurityAgency/ghidra)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Ghidra plugins are Java classes that extend `ghidra.framework.plugintool.Plugin`, declare metadata via the `@PluginInfo` annotation, and are loaded into a `PluginTool` by the `PluginManager` to extend the reverse‑engineering environment at runtime.**

The Ghidra plugin architecture is the modular foundation of the NationalSecurityAgency/ghidra codebase. It allows developers to add menus, UI panels, background analysis, and cross‑plugin services without modifying core Ghidra source. Every window you see in Ghidra—disassembly, decompiler, symbol tree—is implemented as a plugin using this same architecture.

## Core Components of the Ghidra Plugin Architecture

### Plugin Base Class and Lifecycle

Every extension must inherit from `ghidra.framework.plugintool.Plugin`, defined in [[`Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java). This abstract class defines the lifecycle hooks:

- **`init()`** – Called after construction; acquire services, create actions, and register UI components here.
- **`dispose()`** – Cleanup method invoked when the plugin is unloaded; release threads, listeners, and resources.
- **`readConfigState()` / `writeConfigState()`** – Persist user preferences across sessions.

The constructor must accept exactly one argument: `PluginTool`. The framework instantiates plugins via `PluginUtils.instantiatePlugin()`, which looks for this signature.

### PluginInfo Annotation Metadata

Static metadata is declared with `@PluginInfo`, located in [[`PluginInfo.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginInfo.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginInfo.java). The annotation tells the `PluginManager` how to treat the extension:

- **`status`** – `PluginStatus.RELEASED`, `STABLE`, `UNSTABLE`, or `HIDDEN`.
- **`packageName`** – Logical grouping (e.g., `"Developer"` or a custom package).
- **`category`** – Menu category shown in the **Manage Plugins** dialog.
- **`servicesProvided`** – Interfaces this plugin registers for other plugins to consume.
- **`servicesRequired`** – Interfaces this plugin needs from others; the manager resolves these before calling `init()`.
- **`eventsProduced`** / **`eventsConsumed`** – `PluginEvent` types for publish‑subscribe messaging.

### PluginTool and PluginManager

The `PluginTool` ([[`PluginTool.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginTool.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java)) is the running Ghidra window. It owns:

- **`PluginManager`** – Loads classes, resolves dependencies, and drives the lifecycle.
- **`ServiceManager`** – Registry for service interfaces.
- **`EventManager`** – Broadcasts `PluginEvent` objects to registered listeners.

When a tool starts, `PluginManager.installUtilityPlugins()` loads core plugins, then `addPlugins()` instantiates each class, calls `initServices()`, resolves dependencies recursively, orders plugins by service requirements, and finally invokes `init()`.

### Services and Events

**Services** are Java interfaces that decouple plugins. A plugin publishes a service via `registerServiceProvided()` (defined in [`Plugin.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Plugin.java)), and consumers retrieve it with `tool.getService(ServiceInterface.class)`. The `ServiceManager` ([[`ServiceManager.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ServiceManager.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java)) tracks these registrations.

**Events** extend `PluginEvent` ([[`PluginEvent.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginEvent.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java)). Plugins fire events with `firePluginEvent()` and receive them by listing the event class in `@PluginInfo(eventsConsumed)`. The `EventManager` ([[`EventManager.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/EventManager.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/EventManager.java)) handles delivery.

## How the Ghidra Plugin Architecture Loads Extensions

The loading sequence in `PluginManager` ensures that dependencies are satisfied before a plugin initializes:

1. **Tool creation** – `PluginTool` constructs a `PluginManager` instance.
2. **Utility plugin installation** – `installUtilityPlugins()` loads core plugins defined in the default package.
3. **Class instantiation** – `addPlugins()` calls `PluginUtils.instantiatePlugin()`, which invokes the `Plugin(PluginTool)` constructor.
4. **Service registration** – `initServices()` registers services declared in `@PluginInfo.servicesProvided`.
5. **Dependency resolution** – `resolveDependencies()` recursively ensures all `servicesRequired` are available.
6. **Initialization ordering** – `getPluginsByServiceOrder()` sorts plugins so providers initialize before consumers.
7. **Plugin initialization** – `init()` is called; plugins create UI actions, acquire services, and register `ComponentProvider` instances.
8. **Runtime** – The tool is ready; users can enable or disable plugins via the **Manage Plugins** dialog, triggering `dispose()` on removal.

## Creating a Custom Ghidra Extension: Step-by-Step Guide

### Step 1: Create the Plugin Class

Create a Java class that extends `Plugin` and annotate it with `@PluginInfo`. The constructor must accept a single `PluginTool` argument.

```java
package myghidra.plugins.myexample;

import ghidra.framework.plugintool.*;
import ghidra.framework.plugintool.util.PluginStatus;
import docking.action.builder.ActionBuilder;
import docking.action.DockingAction;
import ghidra.util.Msg;

@PluginInfo(
    status = PluginStatus.RELEASED,
    packageName = MyPluginPackage.NAME,
    category = "My Plugins",
    shortDescription = "Demo plugin for Ghidra",
    description = "Shows how to add a menu action and a simple service.",
    servicesProvided = { MyExampleService.class },
    servicesRequired = {},
    eventsConsumed = {},
    eventsProduced = {}
)
public class MyExamplePlugin extends Plugin {

    public MyExamplePlugin(PluginTool tool) {
        super(tool);
    }

    @Override
    protected void init() {
        registerServiceProvided(MyExampleService.class, new MyExampleServiceImpl());
        createAction();
    }

    private void createAction() {
        DockingAction helloAction = new ActionBuilder("Say Hello", getName())
                .menuPath("My Plugins", "Say Hello")
                .description("Shows a message dialog")
                .onAction(c -> Msg.showInfo(this, null,
                        "Hello from MyExamplePlugin", "Custom Ghidra plugin works!"))
                .buildAndInstall(getTool());
    }

    @Override
    protected void dispose() {
        // Cleanup resources here
    }
}

```

### Step 2: Define the Service Interface

Services allow other plugins to interact with your extension without tight coupling.

```java
package myghidra.plugins.myexample;

/**
 * Simple service that other plugins could call.
 */
public interface MyExampleService {
    String echo(String text);
}

```

### Step 3: Implement the Service

Provide the concrete implementation referenced in `init()`.

```java
package myghidra.plugins.myexample;

class MyExampleServiceImpl implements MyExampleService {
    @Override
    public String echo(String text) {
        return "Echo: " + text;
    }
}

```

### Step 4: Create a Plugin Package

The package descriptor groups related plugins for management in the UI.

```java
package myghidra.plugins.myexample;

import ghidra.framework.plugintool.PluginPackage;

/**
 * The package name that groups related plugins.
 */
public class MyPluginPackage extends PluginPackage {
    public static final String NAME = "MyExamplePackage";

    public MyPluginPackage() {
        super(NAME);
    }
}

```

### Step 5: Build and Deploy

Compile your extension as a Ghidra module:

1. Create a Gradle module directory (e.g., `Ghidra/Features/MyExamplePlugin/`).
2. Place source files under `src/main/java/`.
3. Add a `build.gradle` with `sourceSets.main.java.srcDirs = ['src/main/java']`.
4. Include the module in `settings.gradle`.
5. Run `gradle build` to produce the extension JAR.

Alternatively, package your classes into a JAR and place it in `Ghidra/Extensions/` or add it to the classpath manually.

### Step 6: Consume Services from Other Plugins

Once your plugin is loaded, other extensions can access its services:

```java
MyExampleService svc = getTool().getService(MyExampleService.class);
if (svc != null) {
    System.out.println(svc.echo("test"));
}

```

## Key Source Files in the Ghidra Plugin Architecture

Understanding the framework requires familiarity with these core files:

- [[`Plugin.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/Plugin.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java) – Abstract base class handling lifecycle, service registration (`registerServiceProvided`), and event firing (`firePluginEvent`).
- [[`PluginInfo.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginInfo.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginInfo.java) – Annotation interface defining metadata constants like `status`, `servicesProvided`, and `eventsConsumed`.
- [[`PluginManager.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginManager.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginManager.java) – Orchestrates loading via `addPlugins()`, resolves dependencies with `resolveDependencies()`, and orders initialization using `getPluginsByServiceOrder()`.
- [[`PluginTool.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginTool.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginTool.java) – The running tool window; owns `ServiceManager` and `EventManager`; provides `getService()` to plugins.
- [[`ServiceManager.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ServiceManager.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/ServiceManager.java) – Registry for service interfaces; handles `registerServiceProvided` and service lookup.
- [[`EventManager.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/EventManager.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/mgr/EventManager.java) – Broadcasts `PluginEvent` objects to listeners registered via `eventsConsumed`.
- [[`PluginEvent.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/PluginEvent.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java) – Base class for all inter-plugin messages.
- [[`ComponentProvider.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ComponentProvider.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/docking/ComponentProvider.java) – Base for dockable UI panels; plugins register these with `getTool().addComponentProvider()`.
- [[`ActionBuilder.java`](https://github.com/NationalSecurityAgency/ghidra/blob/main/ActionBuilder.java)](https://github.com/NationalSecurityAgency/ghidra/blob/master/Ghidra/Framework/Project/src/main/java/docking/action/builder/ActionBuilder.java) – Fluent API for creating menu items and toolbar buttons.

## Summary

- **Ghidra plugin architecture** is a Java-based framework where every feature is a plugin extending `ghidra.framework.plugintool.Plugin`.
- **Metadata** is declared via the `@PluginInfo` annotation, specifying status, services, events, and dependencies.
- **Lifecycle management** is handled by `PluginManager`, which resolves service dependencies, orders initialization, and calls `init()` and `dispose()`.
- **Inter-plugin communication** occurs through **services** (interfaces registered with `registerServiceProvided` and consumed via `tool.getService()`) and **events** (subclasses of `PluginEvent` fired with `firePluginEvent`).
- **UI integration** uses `ComponentProvider` for dockable windows and `ActionBuilder` for menu actions.
- **Deployment** requires compiling the plugin into a Ghidra module or JAR and enabling it via the **Manage Plugins** dialog.

## Frequently Asked Questions

### What is the Ghidra plugin architecture?

The Ghidra plugin architecture is a modular framework built on Java that allows developers to extend the reverse‑engineering environment at runtime. It defines a standard lifecycle for components (via the `Plugin` base class), a dependency‑injection mechanism for services, and an event system for loose coupling, all orchestrated by the `PluginManager` inside a `PluginTool`.

### How do I debug a Ghidra plugin during development?

Launch Ghidra from your IDE (IntelliJ IDEA or Eclipse) using the `GhidraLauncher` class with the `ghidra.GhidraRun` argument. Set breakpoints in your plugin’s `init()` method or action handlers. Because Ghidra loads plugins dynamically, you can use the **Manage Plugins** dialog to disable and re‑enable your plugin after recompiling, or use the **Script Manager** to run quick tests without restarting the tool.

### Can I write Ghidra plugins in Python instead of Java?

Yes, but with limitations. Ghidra’s primary plugin architecture is Java‑based, and core extensions must extend `Plugin`. However, Ghidra includes a Jython interpreter that allows you to write **scripts** (not full plugins) in Python 2.7. These scripts can access the Ghidra API, manipulate the program, and create temporary UI elements, but they cannot declare services or events in the same way as Java plugins. For deep integration into the Ghidra plugin architecture, Java is required.

### Where should I place my custom Ghidra extension files?

Place your compiled JAR or module directory inside the `Ghidra/Extensions/` directory of your Ghidra installation, or package it as a proper Ghidra module under `Ghidra/Features/` or `Ghidra/Processors/` if building from source. Ensure your JAR contains the compiled plugin class, any service interfaces, and the `PluginPackage` descriptor. After placement, restart Ghidra or open **File → Install Extensions**, then enable your extension in the **Manage Plugins** dialog under the category you specified in `@PluginInfo`.