Overview
A few weeks ago, we saw that a number of folks had developed Model Context Protocol (MCP) servers to provide the ability for Large Language Models (LLMs) to interact with various pieces of software. At this time, a project called AbletonMCP had been developed that enabled AI (specifically LLM Agents or MCP Clients) to interact with Ableton (one of the standards of Digital Audio Workstations) and was able to create an entire song on its own using this software. Seeing this, we had the idea of developing an MCP server to perform malware analysis. Having had prior experience with Binary Ninja’s Python API, we wanted to write an MCP server with Binary Ninja. We then familiarized ourselves with the architectural concepts of MCP servers and wrote an HTTP REST API for the MCP server to interface directly with Binary Ninja. To our surprise (as others discovered as well) the server does fairly well at recognizing and reverse engineering functions. This provides a great interface for asking questions about a Binary Ninja database, marking up code and adding comments to provide functionality insights.
What is an MCP Server and Why Do You Care?
As per the official documentation MCP is an open protocol that standardizes how applications provide context to LLMs. Think of MCP like a USB-C port for AI applications. Just as USB-C provides a standardized way to connect your devices to various peripherals and accessories, MCP provides a standardized way to connect AI models to different data sources and tools
. In this case, we wanted the MCP server to be able to communicate with an open instance of Binary Ninja, so we wrote a plugin for Binary Ninja to be able to start an HTTP server that would receive connections, provide responses and provide a basic interface to push/pull information from the database. The overall architecture looks like this:
This interface allows the LLM Agent to list functions, get cross references to functions, retrieve function pseudocode, retrieve function disassembly, rename functions, rename variables and add comments to code.
BinjaLattice MCP Workflow
In order to start the server, copy the lattice_server_plugin.py to your Binary Ninja plugins directory and start Binary Ninja. This will provide a Start Lattice Protocol
entry in the Plugins menu dropdown. Select this dropdown entry to start the HTTP REST API. Once started, an API key will be pseudo-randomly generated and printed in the Binary Ninja Log interface, along with a log indicating that the server has started:
[agent] API key: ffffffffffffffffffffffffffffffff
[agent] Server started on localhost:9000
Command-Line Testing
For testing the server, you can use the lattice_client.py
that provides a command-line interface to interact with the HTTP REST API without having to use the MCP server. The client provides an interactive interface for ease of use:
jmag@static:~/tools/binja-lattice-mcp$ python3 lattice_client.py --username user --password ffffffffffffffffffffffffffffffff -i
INFO:lib.lattice:Authentication successful
BinjaLattice Client Menu:
1. Get Binary Information
2. Get Function Context by Address
3. Get Function Context by Name
4. Update Function Name
5. Update Variable Name
6. Add Comment to Function
7. Add Comment to Address
8. Reconnect to Server
9. Get All Function Names
10. Get Function Disassembly
11. Get Function Pseudocode
12. Get Function Variables
13. Get Cross References to Function
14. Exit
Enter your choice (1-14):
For example, the number 9
can be used to get all function names:
Enter your choice (1-14): 9
{
"status": "success",
"function_names": [
{
"name": "_init",
"address": 16384
},
...
]
}
MCP Client
For our MCP client we used Cursor, which provides support for MCP servers and an agent-based chat interface that can be used to interact with the MCP server and multiple LLMs. To interface with the MCP server, we use stdio
communication (avoiding yet another HTTP server). In order to allow Cursor to interact with the MCP server, you have to:
- Create a Python virtual environment, install required dependencies (requests and the MCP package)
- Modify the MCP server configuration to point to your virtual environment’s Python binary and your mcp_server.py
- Add the API key provided in the Binary Ninja log as an environment variable:
{
"mcpServers": {
"binja-lattice-mcp": {
"command": "/home/jmag/tools/binja-lattice-mcp/test-env/bin/python",
"args": ["/home/jmag/tools/binja-lattice-mcp/mcp_server.py"],
"env": {
"BNJLAT": "ffffffffffffffffffffffffffffffff"
}
}
}
}
Once saved, the MCP server will become active within Cursor (or your respective MCP client) and MCP functions will become available:
You will also see in Binary Ninja that authentication is successful with the provided API key:
[ScriptingProvider] 127.0.0.1 - - [08/Apr/2025 11:10:00] "POST /auth HTTP/1.1" 200 -
All of this is outlined in detail in the README.
Results
We conducted a number of tests with BinjaLattice MCP against multiple malware analysis scenarios:
- Analysis of a fully marked up Binary Ninja database for automated report generation
- Fully automated analysis from a single function to its sub-functions
The first scenario worked extremely well, as the LLMs and Cursor agent simply queried the database for function code and their respective function calls. Here is an example:
The second scenario worked well for identifying basic functionality, identifying known cryptographic functions and identifying custom cryptographic functions. Here’s an example:
Finally, we were able to perform analysis of multiple sub-functions from a starting function, have it summarize their functionality and even generate a working Yara rule based on the functionality identified:
Despite the rule being functional, it created byte-based strings that were not valid and were missing bytes. Despite this, the rule matches on the malware being analyzed due to multiple conditions being met (similar to how a human would write the Yara rule).
Limitations and Future Work
The current MCP server does not have the ability to access global variables. The testing conducted also revealed that LLMs struggle with calculation and use of hexadecimal and integer addresses. Because of this, we opted to use function names instead of addresses for function-based information retrieval and function-based updates. We will be submitting the BinjaLattice MCP server to the Binary Ninja plugin manager and adding additional functionality for accessing global marked data throughout the database. We will also explore extending this functionality further to see what can be accomplished.
Conclusion
Despite the major hype, there does appear to be applications of MCP servers in the fields of reverse engineering and malware analysis. They provide a quick and simple way to interface both with reverse engineering databases and LLMs to provide insight and markups during the reverse engineering process. They are by no means replacements for human interaction, as they typically require human oversight during the analysis process. They are also limited by context windows and can be cost prohibitive if leading LLMs are used during the analysis process.
Acknowledgements
Many folks have been working on MCP servers to perform reverse engineering:
- Mx-Iris who wrote the first IDA MCP server that we observed during our research
- itsszn who was the first to demo the ability for an MCP server to be with Binary Ninja
- mrexodia who implemented a robust IDA MCP server that is easily extensible
- LaurieWired who implemented an MCP server for Ghidra and released a video on it
- Sergei Frankoff who demonstrated its use with IDA for malware analysis and did a stream with mrexodia
- fosdick and Known Rabbit who implemented similar MCP servers over the past couple of weeks
Full Demo
Here’s a small demo of BinjaLattice MCP reverse engineering custom encryption functions and summarizing the results: