![]() |
|
#1
|
|||
|
|||
|
Adding a run_jeb_script tool to JEB's MCP server
Hi yall. I was needing to integrate jeb more deeply with the powerful AI tools and I found that i needed to have an extra tool that JEB still dosnt provide run_jeb_script
Disclaimer: this whole project was vibe coded Im not gonna lie to you. I just cared about the result and how to improve my rev eng workflow. Let me know if you find issues or proposals and I will be happy to help. I hope you can get some value out of this at least the idea. JEB 5.40 ships with an MCP server (File → Start/Stop the MCP Server). It works, but it exposes a fixed list of 20 tools and provides no way to run arbitrary code. If the model needs something not on that list, you're stuck. This small autorun script (JebMcpRunScript.py) goes into: < JebHome >\scripts\ It registers a 21st tool, named run_jeb_script, directly on JEB’s MCP server. The model gets full access to JEB’s Python API — no bridge, no sidecar, same SSE endpoint, just one extra tool. ------------------------------------------------------------ The 20 Built‑In Tools (Reference) Code:
get_project_information project name, artifacts, units list_units / get_unit_description walk the project tree list_code_items / list_code_strings items and strings of a code unit get_type_information resolve a type decompile_code_item class/method to pseudo-code get_disassembly_snippet disasm around an address list_cross_references xrefs to an address list_apk_resources / get_apk_text_artifact APK resource access find_dynamic_library locate a .so loaded by DEX list_comments / set_comments inline comment R/W rename_code_items / rename_pseudo_code_variables renaming bulk_auto_rename_dex_items bulk de-obfuscation create_dex_package / move_dex_item_to_package DEX package ops get_ui_fragment_information current UI selection Useless the moment you want something like: find every call to Cipher.getInstance("DES") and dump them as JSON That’s not a tool — that’s a script. ------------------------------------------------------------ What `run_jeb_script` Does Input: Code:
{ "code": "string" }
Code:
ctx IClientContext engctx IEnginesContext prj first IRuntimeProject (or None) If it’s a block, assign to result. print() output is captured. Example: find all callsites of System.exit Code:
from com.pnfsoftware.jeb.core import RuntimeProjectUtil
from com.pnfsoftware.jeb.core.units.code.android import IDexUnit
dex = RuntimeProjectUtil.findUnitsByType(prj, IDexUnit, False)[0]
hits = []
for m in dex.getMethods():
for ins in (m.getInstructions() or []):
if 'System;->exit' in ins.format(None):
hits.append('%s @ 0x%x' % (m.getSignature(False), ins.getOffset()))
result = hits
Setup Copy the script: Code:
copy JebMcpRunScript.py C:\JEB\scripts\ Code:
JEB MCP server: http://localhost:8425/mcp Located McpSyncServer via field:bD.GJ Registered tool "run_jeb_script" on JEB MCP server. Code:
claude mcp add --transport sse --scope user jeb http://localhost:8425/mcp Code:
{
"mcpServers": {
"jeb": { "type": "sse", "url": "http://localhost:8425/mcp" }
}
}
------------------------------------------------------------ Optional: Feed Claude the JEB API Docs JEB ships: Code:
C:\JEB\doc\apidoc_md.zip Code:
mkdir .jeb-docs cd .jeb-docs unzip C:\JEB\doc\apidoc_md.zip Code:
The JEB Python API reference is in .jeb-docs/. Consult it before writing run_jeb_script calls. How the Tool Is Attached (The Interesting Part) McpSyncServer.addTool(SyncToolSpecification) exists in the embedded SDK. We just need to locate the live instance — but it’s private, obfuscated, and renamed every release. The script tries 5 strategies (fallback order): 1. Public getters (getMcpServer, getServer, …) 2. Declared field by type io.modelcontextprotocol.server.McpSyncServer 3. Same, but for McpAsyncServer, wrapped into a sync server 4. Bounded BFS through reachable fields/collections (depth ≤ 4, ≤ 20k visits, skipping JDK/Jetty) 5. Static‑field scan on JebMcpServerInstance Each candidate is validated via: - isInstance using the classloader - presence of addTool(SyncToolSpecification) The winning strategy is logged; failures are logged too for debugging future JEB changes. ------------------------------------------------------------ Caveats Code:
- Toggling MCP via menu spawns a new server → re-run the script. - Engines config must have LoadPythonPlugins = true (default in 5.40). - MCP tool calls run on a worker thread; UI work must use ctx.runOnUiThread(). - Security: this is arbitrary code execution on localhost. Same trust model as JEB’s own MCP. CPython 3 Note JEB 5.40 adds Java Embedded Python (CPython 3.x). Jython 2.7 remains default and is what runs at autorun stage. This plugin stays on Jython for now; CPython dispatch could be added later. ------------------------------------------------------------ Troubleshooting Code:
Autorun doesn't fire:
Enable LoadPythonPlugins in bin\jeb-engines.cfg
Port 8425 already taken:
JEB auto-increments; check console for actual port
Tool disappears after toggling MCP:
Run File → Scripts → JebMcpRunScript again
"Could not locate McpSyncServer":
JEB internals changed; console logs show which strategies failed
Uninstall Code:
del C:\JEB\scripts\JebMcpRunScript.py ------------------------------------------------------------ Folder Contents Code:
JebMcpRunScript.py ← drop into <JebHome>\scripts\ apidoc_md.zip ← JEB’s Python API docs README.MD |
| The Following User Says Thank You to NULL0B For This Useful Post: | ||
niculaita (06-07-2026) | ||
![]() |
| Thread Tools | |
| Display Modes | |
|
|