Security Research

Reversing Malware
with AI_

Using Claude + GhidraMCP to autonomously reverse engineer binaries through natural language commands.

Claude AI
Ghidra MCP
Reverse Engineering

The Art of Malware Reversing

Reversing malware is an art that's hard to master. It requires a very unique set of skills to read and understand binary machine code, and many techniques which malware employs that might seem normal to unsuspecting eyes. As daunting as it sounds, it becomes easier with experience.

This write-up explores reversing malware with the help of AI — specifically using Claude and the Ghidra MCP Server — to see how far automation can take us.

Stack: Claude (multimodal LLM) + GhidraMCP Server (Model Context Protocol bridge to Ghidra).
Reference: LaurieWired/GhidraMCP on GitHub.

GhidraMCP System Design

GhidraMCP is a two-component system that allows LLMs to interact with Ghidra for reverse engineering. Each component has a distinct responsibility, keeping integration clean and extensible.

① Ghidra Plugin (Java)

  • Runs inside Ghidra as native plugin
  • Embedded HTTP server (port 8080)
  • 30+ REST API endpoints
  • FunctionManager / symbol access
  • Decompile & disassemble code
HTTP
REST

② Python MCP Bridge

  • FastMCP framework server
  • Translates MCP ↔ HTTP
  • 30+ mapped tool definitions
  • stdio transport (Claude Desktop)
  • SSE transport (Cline)

Endpoint Reference

CategoryEndpointsDescription
Listing/methods /classes
/imports /exports
List programme elements
Code Retrieval/decompile_function
/disassemble_function
Get function code
Modification/rename_function_by_address
/set_function_prototype
Rename and modify functions
Comments/set_decompiler_comment
/set_disassembly_comment
Annotate views
Cross-references/xrefs_to /xrefs_fromCall graph XREFs
Programme Structure/strings /data /segmentsStrings, data, memory

Request / Response Flow

LLM Prompt
"What functions are in this binary?"
MCP Client
Calls list_methods() tool
Python Bridge
HTTP GET → localhost:8080/methods
Ghidra Plugin
Queries FunctionManager, returns function names
LLM Response
Analysis returned to the user

Getting It Running

Install Ghidra Plugin

  1. 1
    File → Install Extension on Ghidra's main window
  2. 2
    Click + in top-right of the Install Extension window
  3. 3
    Select the GhidraMCP plugin zip file and confirm
  4. 4
    Restart Ghidra to activate the extension
  5. 5
    Open a binary in CodeBrowser → File → Configure → check Developer Options → enable GhidraMCPPlugin

Start the Python Bridge

# Install dependencies pip install fastmcp requests # Run the MCP bridge python3 bridge_mcp_ghidra.py

Configure Claude Desktop

Navigate to Options → File → Settings → Developer. Specify the path to bridge_mcp_ghidra.py and arguments. Restart Claude Desktop. When the indicator shows running, you're ready.

Claude Desktop — MCP server status: ghidra running
Claude Desktop MCP running

Cracking a CrackMe

A CrackMe binary from crackmes.one ("CrackMePlease") was the test subject. After loading into Ghidra and running the initial auto-analysis, prompting began.

Step 1 — Enumerate Strings

A simple natural-language prompt triggered the list_strings tool automatically. Claude surfaced ROT+1 encoded strings, hex blobs, and keywords like "password", "prank", "cryptedkey" — immediately flagging suspicious patterns.

Claude listing strings via list_strings() MCP tool
Claude listing strings

Step 2 — Binary Overview: ROT+1 Cipher

Claude's full binary analysis revealed the binary stores all user-visible strings Caesar-shifted by +1. A ROT_decode() helper subtracts 1 from each character at runtime — meaning "fantasticClock711" is the decoded decoy password stored as "gboubtujdDmpdl822".

Binary Analysis — ROT+1 cipher and obfuscated string table
Binary analysis ROT cipher

Step 3 — The Decoy & SHA-256 Self-Hash XOR

Claude identified a two-layer defence. The first check is a deliberate red herring — entering "fantasticClock711" returns "Just kidding. It's not that easy". The real check computes SHA-256 of the binary's own .text section and uses it as a rolling XOR key to decrypt the actual password.

First check (decoy) and SHA-256 self-hash XOR mechanism explained
Decoy and SHA-256 XOR check

Step 4 — Anti-Tamper Design

Claude's insight on why patching fails: modifying any byte in .text changes the SHA-256 hash, which changes the XOR key, which changes the decrypted password. Brute-force patching is therefore self-defeating.

Anti-tamper design — why patching the binary breaks the solution
Anti-tamper explanation

Step 5 — Solver Methodology

Asked to produce a solve script, Claude architected a multi-step offline approach: load the unmodified PE, locate the .text section, compute SHA-256, XOR-decrypt the embedded ciphertext, and output the password.

"give me steps to solve it" — Claude's solver methodology
Solver methodology
Step-by-step solve guide with XOR decryption logic
Step by step solver

Raw Size vs Virtual Size

The first run of the generated script produced a garbled success message. The bug: it used raw_size (includes file padding) instead of virtual_size (the loaded in-memory region the binary actually hashes).

Bug: SizeOfRawData = 0x210c00 includes alignment padding and produces the wrong SHA-256 hash, leading to an incorrect XOR key and garbage output.
First run — wrong hash using raw_size (garbled output)
First run wrong hash

After sharing the incorrect output, Claude immediately self-diagnosed the issue — identifying that the binary uses VirtualSize for hashing, not SizeOfRawData. The fix was applied in one turn.

Fixed run — correct hash using VirtualSize (password: 58040d5b5c)
Fixed run correct password
Fix: Switch to VirtualSize = 0x210bdd → correct SHA-256 → correct XOR decryption → valid password 58040d5b5c.

CrackMe Solved

Running the binary with the extracted password confirms the solve — the crackme prints its success message and exits cleanly.

CrackMe solved — "Hurrayyy! You did it!!!"
CrackMe solved terminal

What This Changes

Faster than manual analysis for average engineers
30+
MCP tools for automated RE workflows
0
Lines of RE code written manually in this walkthrough

Trying GhidraMCP with Claude was fascinating. Although the challenge was simple, it would take an average reverse engineer five times longer to solve without this tool; experts can do it in minutes.

The ability to automate analysis with AI-generated scripts streamlines bulk sample processing and saves considerable time compared to manual reverse engineering. Malware reversing is tough — veteran engineers spend hours debugging and examining machine code without source access.

Despite these difficulties, learning reverse engineering remains crucial for tackling complex binaries, and AI significantly accelerates the process.

Takeaway: AI doesn't replace the reverse engineer — it compresses time-to-insight dramatically, freeing analysts to focus on novel, high-complexity behaviours that automation can't yet reason about.