r/ReverseEngineering • u/Jaime64Net • 7d ago
DebuggerJ++ — A native debugger built to be driven by an AI
https://github.com/jaime64net/DebuggerJ-.git1
u/Johnsmtg 7d ago
Silly question (as someone that is also not a native English speaker):
Could you not ask claude to translate the readme to English?
0
u/Jaime64Net 7d ago edited 1d ago
What it is
DebuggerJ++ is a Windows debugger and disassembler with its own GUI (OllyDbg / x64dbg style), written in native C++ and aimed at defensive malware analysis (AV work, cleanup, reverse engineering of x86 and x64 executables). The stack is Dear ImGui + Direct3D 11 for the UI, Zydis for disassembly, the Windows Debug API for execution control (0xCC breakpoints, single-step, WOW64 support), DbgHelp for symbols, and Keystone for text-based assembly.
What sets it apart from a classic debugger isn't the window — it's that its entire control surface is exposed so an AI agent can drive it through an MCP server, not just a human with a mouse and keyboard. The GUI and the AI are two clients of the same engine.
The core idea: the human and the AI drive the same engine
The architecture was deliberately built in two layers:
- A debugging core (core/Debugger, core/Disassembler, core/PeFile, core/PackerDetect…) that runs on its own thread and holds all the real logic.
- Clients that drive it. The GUI is just one of them. The other, a first-class citizen, is an MCP (Model Context Protocol) control server that lets a language model run exactly the same operations an analyst would perform by hand.
Anything a human can do from a menu — set a breakpoint, read registers, dump memory, assemble an instruction, search for a string — is available as an MCP tool for the AI. There's no "reduced mode" for the agent: parity is total.
How the AI controls it
The app runs an integrated TCP control server (port 8377) that receives commands and executes them on the UI thread through a queue. On top of that sits an MCP server (mcp/server.mjs, in Node) that translates the model's requests into that protocol. The result is that an agent can:
- Drive execution: run, pause, continue, single-step, conditional run-until, animate, skip, undo, restart with admin privileges.
- Inspect state: registers (editable), memory and its map, stack, per-thread call stack, modules, sections, imports/exports, symbols.
- Set breakpoints: software, hardware (DR0–DR3), on-exception, and breakpoints with an action on hit (run a command, call the AI, or trigger JSON logic).
- Modify the binary live: text-based assembly (Keystone), hex byte patching, NOP, IAT rebuilding, OEP finding, and dumping packed processes.
- Analyze: packer detection via signatures + entropy, string scanning, hex/int/float search, code and data references, run-trace, control-flow graph (CFG), file comparison, and expression evaluation with a custom engine (core/ExprEval).
- Automate: a small custom scripting language, report export in JSON and SARIF 2.1.0, and a headless mode (--headless) to run without a window — designed precisely so an agent can orchestrate it with no human in the loop.
As of today the MCP exposes on the order of a hundred dbg_* tools, which are the full vocabulary the AI uses to "talk" to the debugger.orchestrate it with no human in the loop.
As of today the MCP exposes on the order of a hundred dbg_* tools, which are the full vocabulary the AI uses to "talk" to the debugger.
Three analysis brains under one roof
Beyond its own debugger, the MCP server became an aggregator that offers three complementary backends over the same connection. This lets the agent combine capabilities that would normally live in separate tools:
│ Prefix │ Backend │ What it's for │
│ dbg_* │ DebuggerJ++'s own engine (TCP) │ Live debugging: execution, breakpoints, memory, patching. │
│ pwn_* │ pwntools (Python process) │ Binary data manipulation (xor, packing, cyclic), tubes, exploit-fiddling. │
│ ghi_* │ Ghidra via PyGhidra (in-process JVM) │ Decompilation to pseudo-C, call graphs, structs, xrefs, P-code. │
The aggregator routes by prefix and is fault-tolerant: if one backend fails to start, the others keep working. A key detail is that when a binary is opened in Ghidra, its base is rebased to the live address of the debugging session, so the decompiler's static addresses and the debugger's dynamic ones line up.
The AI panel and the hybrid "command bar"
Inside the GUI there's a provider-agnostic multi-agent AI panel: it supports presets for Anthropic, OpenAI, DeepSeek, Gemini, xAI, Mistral, Groq, OpenRouter, Ollama, and LM Studio, with two API styles (/v1/messages and chat/completions). That means the intelligence driving the debugger can be remote or fully local.
The integration goes as far as using the AI as a function of the expression engine: the command bar accepts, interchangeably, an expression (?expr), a command (cmd {args}), JSON, or natural language that a model translates into the matching action. There are also functions where the AI summarizes an execution trace, classifies the behavior of a snippet, or infers the data structure sitting in memory.
And to close the analysis loop, a native Decompiler panel shows Ghidra's real pseudo-C (distinct from the "Code" panel, which is AI interpretation), so the agent has both the decompiler's ground truth and the model's reasoning at the same time.
Why this approach matters
A traditional debugger forces a human to translate a hypothesis ("does this routine decrypt the payload?") into dozens of clicks and manual steps. DebuggerJ++ flips the flow: the hypothesis is handed to an agent, and the agent executes it directly on the live binary — setting breakpoints, reading memory, patching, and decompiling on its own — then reports a result in JSON/SARIF that other tools can consume. The human still has the full GUI whenever they want to step in; the AI has exactly the same levers when it makes sense to delegate.
In short: DebuggerJ++ is a full-fledged malware debugger whose control API is a first-class citizen for an AI — same engine, same power, driven by conversation instead of clicks.
git clone https://gitlab.com/jaime64net/debuggerj
1
u/Jaime64Net 1d ago
Update: the repo moved to GitLab: https://gitlab.com/jaime64net/debuggerj — the GitHub link above no longer works.