ghidra

Framework

NationalSecurityAgency/ghidra

Ghidra is a software reverse engineering framework for analyzing compiled code.

Overview

Ghidra is a software reverse engineering (SRE) framework developed by the NSA. It provides disassembly, decompilation, graphing, and scripting, supporting many processor architectures and executable formats. Users can extend it with Java or Python plugins.

README Preview

\n\n# Ghidra Software Reverse Engineering Framework\nGhidra is a software reverse engineering (SRE) framework created and maintained by the \n[National Security Agency][nsa] Research Directorate. This framework includes a suite of \nfull-featured, high-end software analysis tools that enable users to analyze compiled code on a \nvariety of platforms including Windows, macOS, and Linux. Capabilities include disassembly, \nassembly, decompilation, graphing, and scripting, along with hundreds of other features. Ghidra \nsupports a wide variety of processor instruction sets and executable formats and can be run in both \nuser-interactive and automated modes. Users may also develop their own Ghidra extension components \nand/or scripts using Java or Python.\n\nIn support of NSA's Cybersecurity mission, Ghidra was built to solve scaling and teaming problems \non complex SRE efforts, and to provide a customizable and extensible SRE research platform. NSA has \napplied Ghidra SRE capabilities to a variety of problems that involve analyzing malicious code and \ngenerating deep insights for SRE analysts who seek a better understanding of potential \nvulnerabilities in networks and systems.\n\nIf you are a U.S. citizen interested in projects like this, to develop Ghidra and other \ncybersecurity tools for NSA to help protect our nation and its allies, consider applying for a \n[career with us][career].\n\n## Security Warning\n**WARNING:** There are known security vulnerabilities within certain versions of Ghidra.  Before \nproceeding, please read through Ghidra's [Security Advisories][security] for a better understanding \nof how you might be impacted.\n\n## Install\nTo install an official pre-built multi-platform Ghidra release:  \n* Install [JDK 21 64-bit][jdk]\n* Download a Ghidra [release file][releases]\n  - **NOTE:** The official multi-platform release file is named \n    `ghidra___.zip` which can be found under the "Assets" drop-down.\n    Downloading either of the file

FAQ (5)

Troubleshooting
How to fix Ghidra showing `MOV AX, DS` instead of `MOV DS, AX` for opcode `8E D8`?

This is a regression in Ghidra 12.1.3 and 12.1.4 caused by commit GP-7018. The x86 SLEIGH specification displays the segment register and general-purpose register in the wrong order for MOV opcode 0x8e.

To fix it locally, edit Ghidra/Processors/x86/data/languages/ia.sinc and change the affected constructor names from:

:MOV Rmr16,Sreg ... { Sreg = Rmr16; }
:MOV Rmr32,Sreg ... { Sreg = Rmr32(0); }
:MOV Rmr64,Sreg ... { Sreg = Rmr64(0); }

to:

:MOV Sreg,Rmr16 ... { Sreg = Rmr16; }
:MOV Sreg,Rmr32 ... { Sreg = Rmr32(0); }
:MOV Sreg,Rmr64 ... { Sreg = Rmr64(0); }

Only the displayed operand order changes; the semantic action must remain Sreg = ....

Then rebuild the x86 SLEIGH binaries from the Ghidra installation root:

support/sleigh -a Ghidra/Processors/x86

Restart Ghidra and reopen the program. The instruction for bytes 8e d8 should then disassemble correctly as MOV DS,AX. The fix was submitted in PR #9637, so upgrading to a release containing that fix is the permanent solution.

GitHub Issue #9635
Troubleshooting
How to fix the Sleigh decompiler error "Index 8 out of bounds for length 8" when an instruction has more than 8 operands?

Upgrade to Ghidra 11.0 or newer. This release includes commit 0e9c36b513c4d744fe6c6f7559c049ce1d65266f, which extends the maximum number of Sleigh/Pcode operands beyond the previous limit of 8. If you must use an older Ghidra version, reduce the pseudo-opcode definition to at most 8 operands as a workaround.

GitHub Issue #3243
Troubleshooting
How do I fix Ghidra decompiler error "Low-level Error: Forced merge caused intersection" for a 16-byte RDX:RAX return?

This occurs in Ghidra 12.1.2 when a callee has the default void signature but actually returns a 16-byte value in RDX:RAX, and the caller stores that value into an address-tied stack slot on only one conditional path. The decompiler reuses the stack slot as the call output and conflicts with the existing INDIRECT varnode.

Permanent fix: upgrade to a build containing GP-7136 (commit bb33bad196, fixed on master). The fix was not present in 12.1.2–12.1.4 or the 12.2 branch when the issue was reported.

Workaround in affected versions:
1. Open the callee function, such as ret_pair.
2. Edit its function signature/return type.
3. Define and assign a locked 16-byte struct return type, for example:

struct Pair16 {
       undefined8 a;
       undefined8 b;
   };

4. Set the calling convention to __stdcall and apply the signature.
5. Reopen the caller in the Decompiler.

If the return value is not needed, changing the callee's return type to void also avoids the crash. A call-site-only "Override Signature" to void(void) is not sufficient.

GitHub Issue #9700
Troubleshooting
How to fix Ghidra decompiler incorrectly removing reachable code with 'Removing unreachable block' on big-endian targets like 6809 or H8/300H?

This is a Ghidra 12.1.2 big-endian splitflow bug. When a register is split into independently used halves, such as 6809 D (A/B), the decompiler can swap the pieces' consume masks. The live piece is then treated as unused, replaced with zero, its branch is folded, and reachable code is deleted.

Temporary workaround: disable the decompiler's splitflow simplification rule and re-decompile. The warning should disappear and the live register half/conditional code should be restored.

Permanent fix: apply the PR "Preserve consume masks for big-endian register splits." In TransformVar::createReplacement(), keep using the converted big-endian storage offset only when constructing the replacement varnode address, but pass the original logical/significance offset to transferVarnodeProperties(). Then rebuild the native decompiler, or upgrade to a Ghidra release containing that fix.

Verify the result by confirming that the live half remains a variable, the data-dependent branch is retained, and code such as the post-loop STA store is no longer reported as unreachable.

GitHub Issue #9511
Troubleshooting
Why does the Ghidra error dialog hide the '<' character and show different text than the stack trace?

In Ghidra 9.1, the expandable error dialog renders plain-text messages as HTML without escaping them first. ErrLogExpandableDialog.getHTML() inserts the dialog message and each Throwable.getMessage() through addHTMLContent(), while addBR() only converts newlines to <br>. Therefore, text such as <= 64 can be interpreted as an HTML tag and disappear from the rendered dialog. The underlying message is still correct in the stack trace or log: Bit length must be >= 1 and <= 64.

Workaround: copy or read the full stack trace/log instead of relying on the rendered dialog message.

Permanent fix: HTML-escape every plain-text message before inserting it into the dialog, then convert newlines to <br>:

private static String escapePlainText(String s) {
    return s.replace("&", "&amp;")
            .replace("<", "&lt;")
            .replace(">", "&gt;");
}

Apply this to both the main message and Throwable.getMessage() in ErrLogExpandableDialog.getHTML(), rebuild Ghidra, or use a build that includes the fix titled "Escape plain-text messages in the expandable error dialog".

GitHub Issue #1322