Chinese version: README_zh.md
An MCP server for Windows reverse engineering. It exposes PE triage, Ghidra-backed inspection, DLL/COM profiling, runtime evidence ingestion, Rust/.NET recovery, source-like reconstruction, and LLM-assisted review as reusable MCP tools for any tool-calling LLM.
- Universal Windows PE coverage: EXE, DLL, COM-oriented libraries, Rust-native samples, and .NET assemblies all have dedicated profiling or recovery paths.
- Recover-first design: when Ghidra function extraction is empty or degraded, the server can continue with
.pdataparsing, boundary recovery, symbol recovery, and imported function definitions. - Observable Ghidra runs: command logs, runtime logs, staged progress, project/log roots, and parsed Java exception summaries are surfaced through high-level outputs.
- Runtime-aware reconstruction: static evidence, trace imports, memory snapshots, and semantic review artifacts can all be correlated back into reconstruct and report workflows.
- LLM-assisted review layers: function naming, function explanation, and module reconstruction review are exposed as structured MCP flows instead of ad hoc prompts.
- Queue-friendly orchestration: long-running workflows return
job_id, progress, andpolling_guidanceso MCP clients can wait efficiently instead of burning tokens on tight polling loops.
This iteration adds a stronger first-pass static analysis layer before deep reverse engineering:
static.capability.triageusescapa-style behavior classification to answer what a sample appears capable of, not just what strings or imports it contains.pe.structure.analyzemergespefileandLIEFstyle structural parsing into one canonical PE summary with backend-specific detail blocks.compiler.packer.detectadds compiler, protector, and packer attribution with setup-aware degradation when Detect It Easy is unavailable.workflow.triage,report.summarize, andreport.generatenow consume these results directly, including artifact provenance, static scope selection, and compare/baseline support.
sample.ingeststatic.capability.triagepe.structure.analyzecompiler.packer.detectworkflow.triagereport.summarize
ghidra.analyzeworkflow.function_index_recoverworkflow.reconstruct
workflow.reconstructworkflow.semantic_name_reviewworkflow.function_explanation_reviewworkflow.module_reconstruction_review
This project is meant to be a reusable reverse-engineering tool surface, not a pile of one-off local scripts.
It is designed to help MCP clients:
- triage Windows PE samples quickly
- inspect imports, exports, strings, packers, runtime hints, and binary role
- use Ghidra when available for decompile, CFG, search, and reconstruction
- recover usable function indexes when Ghidra function extraction fails
- surface actionable setup guidance when Java, Python extras, or Ghidra are missing
- expose richer Ghidra diagnostics, command logs, and stage/progress metadata when analysis fails
- correlate static evidence, runtime traces, memory snapshots, and semantic review artifacts
- export source-like reconstruction output with optional build and harness validation
sample.ingestsample.profile.getstatic.capability.triagepe.structure.analyzecompiler.packer.detectpe.fingerprintpe.imports.extractpe.exports.extractpe.pdata.extractdll.export.profilecom.role.profilestrings.extractstrings.floss.decodeyara.scanruntime.detectpacker.detectbinary.role.profilesystem.setup.guide
ghidra.healthghidra.analyzecode.functions.listcode.functions.rankcode.functions.searchcode.function.decompilecode.function.disassemblecode.function.cfgcode.functions.reconstruct
code.functions.smart_recoverpe.symbols.recovercode.functions.definerust_binary.analyzeworkflow.function_index_recover
dotnet.metadata.extractdotnet.types.listdotnet.reconstruct.export
dynamic.dependenciessandbox.executedynamic.trace.importdynamic.memory.importattack.mapioc.exportreport.summarizereport.generateartifacts.listartifact.readartifacts.difftool.help
code.function.rename.preparecode.function.rename.reviewcode.function.rename.applycode.function.explain.preparecode.function.explain.reviewcode.function.explain.applycode.module.review.preparecode.module.reviewcode.module.review.applycode.reconstruct.plancode.reconstruct.export
These are the main orchestration entrypoints for MCP clients.
Fast first-pass triage for PE samples. Use this when you want a quick answer before deeper recovery.
workflow.triage now combines:
- fingerprint and runtime hint extraction
- import and string triage
- YARA matches
- static capability triage
- canonical PE structure summary
- compiler/packer attribution
Long-running static pipeline for deeper analysis and ranking. Supports async job mode.
The main high-level reconstruction workflow.
It can:
- run binary preflight
- detect Rust-oriented samples
- profile DLL lifecycle, export dispatch, callback surface, and COM activation hints
- auto-recover a function index when Ghidra function extraction is missing or degraded
- export native or .NET reconstruction output
- optionally validate build and run the generated harness
- tune export strategy based on role-aware preflight for native Rust, DLL, and COM-oriented samples
- return structured setup guidance when Java, Ghidra, or optional dependencies are not ready
- expose stage-oriented progress metadata for queued and foreground runs
- carry runtime and semantic provenance through the result
High-level recovery chain for hard native binaries:
code.functions.smart_recoverpe.symbols.recovercode.functions.define
Use this when Ghidra analysis exists but function extraction is empty or degraded.
High-level semantic naming review workflow for external LLM clients. It can prepare evidence, request model review through MCP sampling when available, apply accepted names, and optionally refresh reconstruct/export output. When export refresh runs, the workflow now carries the same ghidra_execution summary used by workflow.reconstruct, including project root, log root, command/runtime log paths, progress stages, and parsed Java exception context.
High-level explanation workflow for external LLM clients. It can prepare evidence, request structured explanations, apply them, and optionally rerun reconstruct/export. Export refresh results also surface ghidra_execution so explanation-heavy review chains still expose Ghidra project/log context and progress metadata.
High-level module review workflow for external LLM clients. It can prepare reconstructed modules for review, request structured module refinements through MCP sampling when available, apply accepted module summaries and guidance, and optionally refresh reconstruct/export output. When export refresh runs, the workflow also carries ghidra_execution so module-level review chains expose Ghidra project/log context and progress metadata just like reconstruct and function-level review workflows.
This server does not assume Ghidra is always able to recover functions correctly.
For difficult native samples, especially Rust, Go, or heavily optimized binaries, the recovery path is:
ghidra.analyze- if Ghidra post-script extraction fails, use
pe.pdata.extract - recover candidate function boundaries with
code.functions.smart_recover - recover names with
pe.symbols.recover - import the recovered boundaries with
code.functions.define - continue with
code.functions.list,code.functions.rank,code.functions.reconstruct, orworkflow.reconstruct
This means function_index readiness is tracked separately from decompile and cfg readiness.
Most high-level tools support explicit scope control so clients can choose between all history and the current session.
Runtime evidence selection:
evidence_scope=allevidence_scope=latestevidence_scope=sessionwithevidence_session_tag
Semantic naming / explanation / module-review selection:
semantic_scope=allsemantic_scope=latestsemantic_scope=sessionwithsemantic_session_tag
Comparison-aware outputs are also supported through:
compare_evidence_scopecompare_evidence_session_tagcompare_semantic_scopecompare_semantic_session_tag
This allows MCP clients to ask not only "what is the current result?" but also "what changed compared with the previous evidence or semantic review session?"
Static-analysis artifact selection:
static_scope=allstatic_scope=lateststatic_scope=sessionwithstatic_session_tag
Static baseline comparison:
compare_static_scopecompare_static_session_tag
This server supports multiple structured review layers for MCP clients with tool calling and optional sampling:
- function naming review
- function explanation review
- module reconstruction review
Each layer follows the same pattern:
- prepare a structured evidence bundle
- optionally ask the connected MCP client to perform a constrained review through sampling
- apply accepted results as stable semantic artifacts
- rerun reconstruct/export/report workflows against explicit semantic scope
Long-running workflows support queued execution and background completion:
workflow.deep_staticworkflow.reconstructworkflow.semantic_name_reviewworkflow.function_explanation_reviewworkflow.module_reconstruction_review
Use these with:
task.statustask.canceltask.sweep
Queued workflow responses and task.status now include polling_guidance.
When a long-running Ghidra or reconstruct job is still queued/running, MCP
clients should prefer one client-side sleep/wait using that recommendation
instead of repeated immediate polling.
If a client starts using the server before Python, dynamic-analysis extras, or Ghidra are configured, use:
system.healthdynamic.dependenciesghidra.healthsystem.setup.guide
These return structured setup actions and required user inputs so an MCP client can explicitly ask for:
python -m pip install ...JAVA_HOMEGHIDRA_PATH/GHIDRA_INSTALL_DIRGHIDRA_PROJECT_ROOT/GHIDRA_LOG_ROOTCAPA_RULES_PATHDIE_PATH- optional dynamic-analysis extras such as Speakeasy/Frida dependencies
For runtime API tracing and behavioral analysis, install Frida:
pip install frida frida-toolsEnvironment Variables (optional - auto-detected when frida is in PATH):
FRIDA_SERVER_PATH- Path to Frida server binary for USB/remote device analysisFRIDA_DEVICE- Device ID or "usb" for USB device selection (default: local spawn)
Pre-built Scripts are included in frida_scripts/:
api_trace.js- Windows API tracing with argument loggingstring_decoder.js- Runtime string decryptionanti_debug_bypass.js- Anti-debug detection neutralizationcrypto_finder.js- Cryptographic API detectionfile_registry_monitor.js- File/registry operation tracking
See [docs/EXAMPLES.md](./docs/EXAMPLES.md#场景 -9-frida-运行时 instrumentation) for usage examples.
Stable Features (Production Ready):
- PE triage and static analysis (
static.capability.triage,pe.structure.analyze,compiler.packer.detect) - Ghidra-backed inspection with full execution visibility
- DLL/COM profiling (
dll.export.profile,com.role.profile) - Rust and .NET recovery paths
- Source-like reconstruction with LLM-assisted review layers
- Runtime evidence ingestion and correlation
Frida Dynamic Instrumentation - Completed implementation, awaiting release:
frida.runtime.instrument- Spawn and attach mode instrumentationfrida.script.inject- Pre-built and custom script injectionfrida.trace.capture- Canonical trace schema with filtering/aggregation- Full integration with
dynamic.trace.import,report.generate,report.summarize - 101 unit tests + integration test coverage
- Comprehensive documentation in
docs/EXAMPLES.md
Test Coverage: All 101 tests passing including Frida instrumentation suite.
For the new static triage foundation, the most common optional requirements are:
flare-capapefilelief- a downloaded capa rules bundle referenced by
CAPA_RULES_PATH - Detect It Easy CLI referenced by
DIE_PATH
For Ghidra 12.0.4, the server expects Java 21+ and will report explicit Java compatibility hints through:
ghidra.healthsystem.healthsystem.setup.guide
When Ghidra commands fail, the server now persists command logs and, when available, Ghidra runtime logs. Normalized diagnostics include Java exception summaries and remediation hints instead of only returning exit code 1.
The bundled ghidra_scripts/ directory is resolved from the installed package
or repository root, not from the current working directory. This prevents
ExtractFunctions.py / ExtractFunctions.java lookup failures when the server
is launched from a different folder.
High-level outputs now expose a structured ghidra_execution block instead of hiding Ghidra details behind generic success/failure states.
You can now see:
- which analysis record was selected
- whether the result came from the best ready analysis or only the latest attempt
- project path, project root, and log root
- persisted command logs and runtime logs
- function extraction status and script name
- staged progress metadata
- parsed Java exception summaries when Ghidra fails
This summary is surfaced through:
workflow.reconstructworkflow.semantic_name_reviewwhen export refresh runsworkflow.function_explanation_reviewwhen export refresh runsworkflow.module_reconstruction_reviewwhen export refresh runsreport.summarizereport.generate
bin/ npm CLI entrypoint
dist/ compiled TypeScript output
ghidra_scripts/ Ghidra helper scripts used by the server
helpers/DotNetMetadataProbe/ .NET metadata helper project
src/ TypeScript MCP server source
tests/ unit and integration tests
workers/ Python worker, YARA rules, dynamic helpers
install-to-codex.ps1 local Codex MCP install helper
install-to-copilot.ps1 local GitHub Copilot MCP install helper
install-to-claude.ps1 local Claude Code MCP install helper
docs/QUALITY_EVALUATION.md evaluation checklist for regression and release readiness
Required:
- Node.js 18+
- npm 9+
- Python 3.9+
Optional but strongly recommended:
- Ghidra for native decompile and CFG features
- .NET SDK for
dotnet.metadata.extract - Clang for reconstruct export validation
- Python packages from
requirements.txt - Python worker packages from
workers/requirements.txt
Install JavaScript dependencies:
npm installInstall Python worker dependencies:
python -m pip install -r requirements.txt
python -m pip install -r workers/requirements.txt
python -m pip install -r workers/requirements-dynamic.txtBuild:
npm run buildRun tests:
npm testStart locally:
npm start{
"mcpServers": {
"windows-exe-decompiler": {
"command": "node",
"args": ["/absolute/path/to/repo/dist/index.js"],
"cwd": "/absolute/path/to/repo",
"env": {
"GHIDRA_PATH": "C:/path/to/ghidra",
"GHIDRA_INSTALL_DIR": "C:/path/to/ghidra"
}
}
}
}- Codex:
install-to-codex.ps1 - Claude Code:
install-to-claude.ps1 - GitHub Copilot:
install-to-copilot.ps1
Related docs:
By default, runtime state is stored under the user profile instead of the current working directory:
- Windows workspace root:
%USERPROFILE%/.windows-exe-decompiler-mcp-server/workspaces - SQLite database:
%USERPROFILE%/.windows-exe-decompiler-mcp-server/data/database.db - File cache:
%USERPROFILE%/.windows-exe-decompiler-mcp-server/cache - Audit log:
%USERPROFILE%/.windows-exe-decompiler-mcp-server/audit.log - Ghidra project root:
%ProgramData%/.windows-exe-decompiler-mcp-server/ghidra-projects - Ghidra log root:
%ProgramData%/.windows-exe-decompiler-mcp-server/ghidra-logs - Bundled Ghidra scripts: resolved from the installed package root
You can override these with environment variables or the user config file:
%USERPROFILE%/.windows-exe-decompiler-mcp-server/config.jsonWORKSPACE_ROOTDB_PATHCACHE_ROOTAUDIT_LOG_PATHGHIDRA_PROJECT_ROOTGHIDRA_LOG_ROOT
For local IDE clients such as VS Code or Copilot, prefer local file paths:
{
"tool": "sample.ingest",
"arguments": {
"path": "E:/absolute/path/to/sample.exe"
}
}Use bytes_b64 only when the client cannot access the same filesystem as the server.
The published package includes:
- compiled
dist/ - the CLI entrypoint in
bin/ - Python workers and YARA rules
- Ghidra helper scripts
- the .NET metadata helper source
- MCP client install scripts
It excludes:
- tests
- local workspaces
- caches
- generated reports
- scratch documents and internal progress notes
Pre-publish checklist:
- Update the version in
package.json. - Run
npm run release:check. - Inspect
npm run pack:dry-run. - Log in with
npm login. - Publish with
npm publish --access public.
GitHub automation included in this repository:
For GitHub Actions publishing, configure the NPM_TOKEN repository secret.
This project is for analysis workflows, not live malware operations.
Current strengths:
- PE triage and classification support
- reverse-engineering evidence extraction
- IOC and ATT&CK export
- runtime evidence import and correlation
- source-like reconstruction and review
Current non-goals:
- original source recovery for complex native binaries
- guaranteed malware family attribution from static evidence alone
- fully automatic unpacking for every packer
- high-confidence semantic recovery of every function in heavily optimized code
- Contributor guide:
CONTRIBUTING.md - Quality evaluation notes:
docs/QUALITY_EVALUATION.md - Example benchmark corpus:
examples/benchmark-corpus.example.json - Security policy:
SECURITY.md
{
"mcpServers": {
"windows-exe-decompiler": {
"command": "npx",
"args": ["-y", "windows-exe-decompiler-mcp-server"],
"env": {
"GHIDRA_PATH": "C:/path/to/ghidra",
"GHIDRA_INSTALL_DIR": "C:/path/to/ghidra"
}
}
}
}Released under the MIT license. See LICENSE.