Skip to content

malwarecakefactory/IDA_Malware_MCP_Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IDA Malware MCP Server

An MCP (Model Context Protocol) server for IDA Pro focused on malware analysis. This server enables Claude to analyze and rename functions/variables in IDA Pro through a structured interface.

Architecture

┌────────────────────────────────────┐    ┌────────────────────────────────────┐
│         Windows Host               │    │         Windows VM                 │
│                                    │    │                                    │
│  Claude Desktop ◄──► server.py ◄───┼────┼──► ida_plugin.py ◄──► IDA Pro     │
│              MCP/stdio        HTTP │    │        :13337                      │
└────────────────────────────────────┘    └────────────────────────────────────┘

Communication Flow

Claude <--MCP/stdio--> server.py <--HTTP/JSON-RPC--> ida_plugin.py <--IDAPython--> IDA Pro

Components

File Description
server.py MCP server with stdio transport. Parses ida_plugin.py AST to extract @jsonrpc functions and exposes them as MCP tools. Forwards calls via HTTP to IDA.
ida_plugin.py IDA Pro plugin. Runs HTTP server on 0.0.0.0:13337, handles JSON-RPC requests, executes IDAPython commands.
rpc.py @jsonrpc decorator registry. Functions decorated with @jsonrpc are automatically exposed via JSON-RPC.
sync.py @ida_sync decorator. Ensures IDAPython calls run on IDA's main thread using execute_sync.
install.py Helper script to copy plugin files to IDA's plugins directory.

Requirements

  • Python 3.11+
  • IDA Pro 8.3+ (9.x recommended) with Hex-Rays decompiler
  • Windows (for IDA Pro)

Python Dependencies

mcp>=1.0.0
httpx>=0.25.0

Installation

Step 1: Install Python Package (on Windows Host)

# Clone or download the repository
cd ida-malware-mcp

# Install in development mode
pip install -e .

Step 2: Install IDA Plugin (on Windows VM)

Option A: Automatic Installation

python -m ida_malware_mcp.install "C:\Program Files\IDA Pro 9.0\plugins"

Option B: Manual Installation

Copy these files to your IDA plugins directory:

C:\Program Files\IDA Pro 9.0\plugins\
└── ida_malware_mcp\
    ├── __init__.py
    ├── ida_plugin.py
    ├── rpc.py
    └── sync.py

Then create a loader file ida_malware_mcp_loader.py in the plugins directory:

"""IDA Malware MCP Plugin Loader"""
import sys
from pathlib import Path

plugin_dir = Path(__file__).parent / "ida_malware_mcp"
if str(plugin_dir) not in sys.path:
    sys.path.insert(0, str(plugin_dir))

from ida_malware_mcp.ida_plugin import PLUGIN_ENTRY

Step 3: Configure Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "ida-malware-mcp": {
      "command": "python",
      "args": ["-m", "ida_malware_mcp.server"],
      "env": {
        "IDA_MCP_URL": "http://192.168.x.x:13337/mcp"
      }
    }
  }
}

Replace 192.168.x.x with your VM's IP address.

Step 4: Configure Windows VM Firewall

Allow inbound connections on port 13337:

netsh advfirewall firewall add rule name="IDA MCP" dir=in action=allow protocol=tcp localport=13337

Step 5: Verify Setup

  1. Start IDA Pro and load a binary
  2. Check IDA Output window for: [IDA MCP] Server started on http://0.0.0.0:13337/mcp
  3. Test from host: curl http://<VM_IP>:13337/mcp

Available MCP Tools (58 Total)

Core Tools

Tool Description
get_analysis_guidelines() Call FIRST! Get mandatory workflow for batch analysis
complete_batch(batch_num, functions, findings, progress) Call after each batch! Logs results
check_connection() Verify IDA plugin is running and responsive
get_metadata() Get IDB info: filename, architecture, bitness, address range
list_functions(offset, count, filter?) List functions with pagination. Use filter="sub_" for unnamed functions
print_summary(summary) Print execution summary to IDA's Output window

Binary Structure Tools

Tool Description
get_entry_points() Get all entry points: main, TLS callbacks, exports
get_segments() List segments with permissions, entropy, and suspicious indicators
get_imports() Get imported functions grouped by DLL/module
get_exports() Get exported functions with ordinals
get_strings(min_length?, max_count?, filter?) Get strings with xref counts. Filter by substring

Function Analysis Tools

Tool Description
get_function_pseudocode(address) Get Hex-Rays decompiled code (falls back to disassembly if unavailable)
get_function_disassembly(address) Get assembly listing for a function
get_local_variables(func_address) List local variables with names and types
get_function_calls(address) Get all functions/APIs called by a function
get_function_callers(address) Get all functions that call this function
get_basic_blocks(address) Get CFG basic blocks with predecessors/successors
refresh_decompilation(address) Force Hex-Rays refresh after type changes
analyze_function_complete(address) Kitchen sink: decompile + disasm + variables + callees + callers + strings in one call
get_call_graph(address, depth?, direction?) Recursive call graph (callees, callers, or both) up to depth 10

Cross-Reference Tools

Tool Description
get_xrefs_to(address, max_count?) Get all references TO an address (callers, data refs)
get_xrefs_from(address, max_count?) Get all references FROM an address/function

Search Tools

Tool Description
search_bytes(pattern, max_results?) Search byte patterns with wildcards. E.g., "FC E8", "E8 ?? ?? ?? ??"
search_immediate(value, max_results?) Find immediate value usage (API hashes, constants)
find_potential_hashes(func_address?, max_results?) Find potential API hash constants (32-bit immediates) with disassembly
search_functions_regex(pattern, max_results?) Search function names with regex (e.g., "crypt|encrypt", "sub_14.*")
search_strings_regex(pattern, max_results?) Search strings with regex (e.g., "https?://", "password|secret")

Data Tools

Tool Description
get_bytes(address, size, format?) Extract raw bytes as hex/base64/array with auto-analysis hints
apply_struct(address, struct_name, is_pointer?) Apply structure type at address

Modification Tools

Tool Description
rename_function(address, new_name) Rename a function
set_name(address, new_name) Rename any address (functions, globals, data)
rename_local_variable(func_addr, old_name, new_name) Rename a local variable
batch_rename_locals(func_addr, renames[]) Batch rename multiple local variables
set_local_variable_type(func_addr, var_name, type_name) Set variable type (e.g., IMAGE_DOS_HEADER *)
set_function_prototype(address, prototype) Set full function signature
apply_callee_type(address, prototype) Apply prototype to indirect CALL (runtime-resolved APIs) — auto-strips SAL/MSDN formatting
get_callee_type(address) Read back callee type applied to a CALL instruction
set_comment(address, comment, is_repeatable?) Add disassembly comment at address
set_decompiler_comment(address, comment) Add comment in Hex-Rays pseudocode view
set_plate_comment(address, comment) Add banner comment above a function
create_function(address, end_address?) Create a function (useful for shellcode, missed code)
delete_function(address) Delete (undefine) a function boundary

Batch Operations

Tool Description
batch_rename_functions(renames[]) Rename multiple functions in one call
batch_set_comments(comments[]) Set comments at multiple addresses (regular, repeatable, anterior, posterior)
batch_set_variable_types(func_addr, type_changes[]) Set types of multiple local variables in one call

Struct/Enum Management

Tool Description
create_struct(name, fields?) Create a new structure with optional initial fields
add_struct_field(struct_name, field_name, field_type, offset?, size?) Add a field to an existing structure
get_struct_layout(struct_name) Get full structure layout with all fields, offsets, sizes
create_enum(name, members?, is_bitfield?) Create a new enum type
get_enum_members(enum_name) Get all members and values of an enum

Type Management Tools

Tool Description
list_local_types() List all types in Local Types window
declare_c_type(c_declaration) Add/update type from C declaration
ensure_pe_types() Create PE_BASE, PE_BASE64 unions and PE struct types

Malware Analysis Tools

Tool Description
find_anti_analysis() Detect anti-debugging, anti-VM, and anti-sandbox techniques
extract_iocs(max_results?) Extract IOCs: URLs, IPs, emails, file paths, registry keys, crypto wallets
analyze_api_chains(address?, max_depth?) Analyze API call chains and detect behavioral patterns (download+exec, injection, etc.)

Bookmark Tools

Tool Description
set_bookmark(address, description, slot?) Set a bookmark at an address
list_bookmarks() List all bookmarks with descriptions and context
delete_bookmark(slot) Delete a bookmark by slot number

Script Execution

Tool Description
run_script(code) Execute arbitrary IDAPython code. Set result variable to return data.

JSON-RPC Protocol

The IDA plugin accepts JSON-RPC 2.0 requests at http://<IP>:13337/mcp:

Request:

{
  "jsonrpc": "2.0",
  "method": "get_function_pseudocode",
  "params": ["0x140001000"],
  "id": 1
}

Response:

{
  "jsonrpc": "2.0",
  "result": {
    "address": "0x140001000",
    "name": "sub_140001000",
    "pseudocode": "int __fastcall sub_140001000(...) { ... }"
  },
  "id": 1
}

Adding New Tools

Add a function with @jsonrpc and @ida_sync decorators in ida_plugin.py:

@jsonrpc
@ida_sync
def my_new_tool(param1: str, param2: int) -> dict:
    """Description shown to Claude as tool description."""
    # Implementation using IDAPython
    ea = _parse_address(param1)
    # ... do something ...
    return {"result": "success", "data": "..."}

The function is automatically:

  1. Exposed via JSON-RPC in the IDA plugin
  2. Discovered by server.py via AST parsing
  3. Available as an MCP tool to Claude

Parameter Types

  • Use type hints for proper JSON Schema generation
  • str"type": "string"
  • int"type": "integer"
  • bool"type": "boolean"
  • list"type": "array"
  • dict"type": "object"
  • Optional parameters: use param: str | None = None

Address Parameters

Accept addresses as strings (hex 0x... or decimal), convert using _parse_address():

def my_tool(address: str) -> dict:
    ea = _parse_address(address)  # Handles "0x401000" or "4198400"

Example Workflows

Workflow 1: Initial Triage

Quick assessment of a suspicious binary:

1. get_metadata()                    → Get file info, architecture
2. get_segments()                    → Check for packed sections (high entropy, RWX)
3. get_imports()                     → Review API capabilities
4. get_strings(filter="http")        → Find C2 URLs
5. get_entry_points()                → Identify execution starting points

Workflow 2: Common Function Identification

Claude analyzes unnamed functions and identifies standard library functions:

1. list_functions(filter="sub_")     → Get unnamed functions
2. get_function_pseudocode(addr)     → Get decompiled code (or assembly fallback)
3. Claude analyzes the code          → Identifies strlen, memcpy, etc.
4. rename_function(addr, "mw_strlen")→ Apply rename with mw_ prefix
5. print_summary(summary)            → Display results in IDA

Naming Convention: mw_ + standard function name

  • mw_strlen, mw_strcpy, mw_memcpy, mw_memset
  • mw_xor_decrypt, mw_rc4_encrypt, mw_resolve_api_ror13

Workflow 3: API Hash Resolution

Identify and resolve API hash functions:

1. search_immediate("0x6A4ABC41")    → Find hash constant usage
2. get_function_callers(addr)        → Find the hash resolver function
3. get_function_pseudocode(resolver) → Analyze resolver logic
4. ensure_pe_types()                 → Create PE_BASE unions
5. set_local_variable_type(...)      → Apply proper types
6. rename_function(addr, "mw_resolve_api_ror13")

Workflow 4: Shellcode Analysis

Analyze embedded shellcode or shellcode samples:

1. search_bytes("FC E8")             → Find shellcode patterns (cld; call)
2. get_bytes(addr, 256)              → Extract shellcode bytes
3. get_function_pseudocode(addr)     → Get disassembly (auto-fallback)
4. get_basic_blocks(addr)            → Understand control flow
5. get_function_calls(addr)          → Find resolved API calls

Workflow 5: Encrypted String Decryption

Find and analyze string decryption routines:

1. get_strings()                     → Find encrypted/garbled strings
2. get_xrefs_to(string_addr)         → Find code referencing string
3. get_function_pseudocode(func)     → Analyze decryption logic
4. get_function_calls(func)          → Check for crypto APIs
5. rename_function(addr, "mw_decrypt_string")

Workflow 6: Call Graph Analysis

Understand function relationships:

1. get_call_graph(main_func, depth=3) → Full recursive call tree
2. analyze_function_complete(addr)     → Everything about one function in one call
3. get_function_callers(crypto_func)   → Who uses crypto?
4. get_xrefs_from(suspicious_func)     → All references (calls + data)

Workflow 7: Anti-Analysis Detection

Identify evasion techniques in malware:

1. find_anti_analysis()              → Detect anti-debug/VM/sandbox APIs
2. extract_iocs()                    → Pull out URLs, IPs, paths, registry keys
3. analyze_api_chains(addr)          → Find download+exec, injection patterns
4. search_functions_regex("crypt|encrypt|decrypt")  → Find crypto functions

Workflow 8: Structure Recovery

Define and apply custom structures:

1. create_struct("C2_CONFIG", [{"name": "magic", "type": "DWORD"}, ...])
2. add_struct_field("C2_CONFIG", "url", "BYTE", size=256)
3. apply_struct(addr, "C2_CONFIG")
4. refresh_decompilation(func_addr)  → See clean pseudocode
5. get_struct_layout("C2_CONFIG")    → Verify layout

Workflow 9: Batch Documentation

Efficiently document many functions:

1. list_functions(filter="sub_")     → Get unnamed functions
2. For each batch of 5:
   a. analyze_function_complete(addr) → Get everything about the function
   b. batch_rename_functions([...])   → Rename multiple functions at once
   c. batch_set_comments([...])       → Add comments at multiple addresses
   d. batch_set_variable_types(addr, [...]) → Fix types in bulk

Workflow 10: Custom Analysis via Script

Run arbitrary IDAPython when built-in tools aren't enough:

1. run_script("result = [hex(ea) for ea in idautils.Functions() if idc.get_func_attr(ea, idc.FUNCATTR_FLAGS) & 0x4]")
   → Find all library functions
2. run_script("import ida_bytes; result = ida_bytes.get_bytes(0x401000, 16).hex()")
   → Read raw bytes with full IDA API access

Troubleshooting

"Cannot connect to IDA plugin"

  1. Verify IDA Pro is running with a binary loaded
  2. Check IDA Output window for server startup message
  3. Test connectivity: curl http://<VM_IP>:13337/mcp
  4. Check Windows Firewall allows port 13337

"Decompilation failed" or shellcode analysis

  • get_function_pseudocode() automatically falls back to disassembly when Hex-Rays fails
  • Check the code_type field in response: "pseudocode" or "disassembly"
  • For shellcode, assembly output is expected and fully supported

Plugin not loading

  1. Check IDA's Output window for error messages
  2. Verify all plugin files are in the correct directory
  3. Ensure Python version matches IDA's embedded Python

Slow responses

  • Large binaries may take time for string/function enumeration
  • Use pagination: list_functions(offset=0, count=50)
  • Use filters: get_strings(filter="http", max_count=100)

Environment Variables

Variable Default Description
IDA_MCP_URL http://localhost:13337/mcp URL of the IDA plugin endpoint

Acknowledgments

This project builds upon and was inspired by:

  • mrexodia/ida-pro-mcp - The original IDA Pro MCP server that provided the foundational architecture for Claude-IDA integration via JSON-RPC.

  • bethington/ghidra-mcp - The Ghidra MCP server whose comprehensive toolset (179 tools) inspired many additions including struct/enum management, batch operations, malware analysis tools, bookmarks, and the kitchen-sink analyze_function_complete pattern.

  • herrcore's PE Header Union Trick - The PE_BASE/PE_BASE64 union technique for cleaner decompilation of PE parsing code and API hash resolvers.

  • Dump-GUY/ApplyCalleeTypeEx - The callee type application logic and prototype preprocessing pipeline (SAL annotation stripping, calling convention normalization, MSDN format handling) were ported from this modernized fork of Mandiant FLARE's ApplyCalleeType plugin (Apache-2.0).

License

MIT License

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages