Skip to content
KitploitKITPLOIT
工具漏洞利用博客
Log in
提交
工具漏洞利用博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

订阅源联系隐私© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
JNISleuth-MCP — 自动化 Android JNI RegisterNatives 恢复、剥离的 ARM64 .so 类型重建、OLLVM BR X8 反混淆器,以及面向 Jadx、Ghidra 和 IDA Pro 9.0 的通用 LLM/MCP 桥接。 | Kitploit
工具/GitHubGitHub/nighthawkk/jnisleuth-mcp
Android安全静态分析动态分析 (沙盒)逆向工程恶意软件分析移动安全二进制分析AI 辅助逆向
GitHubnighthawkk/jnisleuth-mcp

JNISleuth-MCP

自动化 Android JNI RegisterNatives 恢复、剥离的 ARM64 .so 类型重建、OLLVM BR X8 反混淆器,以及面向 Jadx、Ghidra 和 IDA Pro 9.0 的通用 LLM/MCP 桥接。

查看仓库
2382天前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

🕵️‍♂️ JNISleuth-MCP

弥合 Android 逆向工程中 Java 与原生代码之间的鸿沟。
自动化 RegisterNatives 恢复、剥离后的 ARM64 .so 类型重建,以及统一的 Jadx + Ghidra 或 IDA MCP 服务器,用于 AI 辅助的恶意软件分析。

Platform Ghidra MCP Native Engine License

快速开始 • 工作原理 • MCP 工具 • 隐蔽 Dobby 代理 • 路线图


⚡ 为什么选择 JNISleuth-MCP?

现代 Android 恶意软件、银行木马、间谍软件和商业加壳工具将其核心逻辑(C2 加密、密钥派生、环境检查和漏洞利用例程)隐藏在**剥离符号的 C/C++ 原生库(lib*.so)**中。

在跨 JNI 边界进行逆向分析时,分析人员会遇到三道障碍:

  1. 交叉引用断裂: 在 classes.dex 中声明的 native 方法不使用标准的 Java_com_pkg_Class_method 符号。相反,它们通过 JNIEnv->RegisterNatives() 在混淆的 JNI_OnLoad 内部于运行时动态绑定。
  2. 反编译盲区: 在 Ghidra 或 IDA 中打开剥离符号的 .so 会显示数千个未命名的 sub_XXXX 函数,其中 JNIEnv* 虚表调用看起来像原始指针运算((**(code **)(*param_1 + 0x538))(param_1, param_2))。
  3. AI 上下文割裂: 现有的 Ghidra MCP 和 Jadx MCP 服务器各自为政——LLM 无法追踪从 Java 中的 Android BroadcastReceiver 一直到 libnative-lib.so 中 ARM64 加密例程的数据流。

JNISleuth-MCP 消除了上下文切换。 它自动恢复静态和动态的 RegisterNatives 绑定,在 Ghidra 中重新为剥离符号的 ARM64 函数赋予类型,并提供一个统一的 模型上下文协议(MCP) 服务器,将 DEX 字节码与原生汇编连接起来。

能力标准 Jadx / Ghidra MCPJNISleuth-MCP
解析标准 Java_* 导出✅✅
静态恢复剥离符号的 RegisterNatives 结构体数组(.rodata / .data.rel.ro + JNI_OnLoad CFG)❌✅
通过 Dobby 在设备上隐蔽采集 RegisterNatives(绕过反 Frida 检测)❌✅
在 Ghidra 中自动应用 JNIEnv* 虚表类型并重建 Call*Method / GetStringUTFChars❌✅
单次调用跨边界数据流(Java 调用方 ➔ JNI 桥接 ➔ 反编译的 ARM64 C++)❌✅

🏗️ 架构与工作原理

flowchart LR
    subgraph Input["📦 Target APK / Malware"]
        DEX["classes*.dex"]
        ELF["Stripped lib/*.so (ARM64)"]
    end

    subgraph Harvester["🔍 Stage 1: JNI Bridge Harvester"]
        StaticScan["Static ELF & DEX Scanner\n(LIEF + Capstone + Heuristic Triplets)"]
        DobbyAgent["Stealth Native Agent\n(C++ / NDK / Dobby Inline Hook)"]
    end

    subgraph GhidraEngine["⚙️ Stage 2: Ghidra Headless Reconstructor"]
        Renamer["Function Renamer & Signature Applier"]
        VTable["JNIEnv* VTable & Struct Propagator"]
    end

    subgraph MCPServer["🤖 Stage 3: Unified FastMCP Server"]
        CrossGraph["Cross-Boundary Callgraph\n(Jadx Java + Ghidra C/ARM64)"]
        CallbackTrace["Upcall Tracer\n(Native -> Java Reflection)"]
    end

    DEX --> StaticScan
    ELF --> StaticScan
    ELF -. "Packed / OLLVM?" .-> DobbyAgent
    StaticScan --> Renamer
    DobbyAgent -- "register_natives.json" --> Renamer
    Renamer --> VTable
    VTable --> CrossGraph
    VTable --> CallbackTrace

🎬 实际效果演示

1. CLI 静态 + 动态 RegisterNatives 恢复

对带有已剥离原生库的 APK 运行 jnisleuth scan:

$ jnisleuth scan --apk samples/banker_dropper.apk --arch arm64-v8a

[*] Parsing 3 DEX files... Found 14 declared `native` methods across 4 classes.
[*] Inspecting lib/arm64-v8a/libcore-crypto.so (Stripped ELF, 0 exported Java_* symbols)
[*] Running static JNINativeMethod triplet scanner on .rodata / .data.rel.ro...
    [+] Resolved 11/14 methods via static struct table @ 0x0004d210
[!] 3 methods unresolved (constructed dynamically on stack in JNI_OnLoad).
[*] Launching headless Dobby collector on device (emulator-5554)...

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
┃ Java Class & Method                      ┃ JNI Signature        ┃ .so Offset (ARM64)  ┃ Resolution Mode  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
│ com.dropper.Core#initEngine              │ (Landroid/content/.. │ libcore.so+0x001a40 │ Static (.rodata) │
│ com.dropper.Core#decryptPayload          │ ([BLjava/lang/Stri.. │ libcore.so+0x0023c8 │ Static (.rodata) │
│ com.dropper.Core#signC2Beacon            │ (Ljava/lang/String.. │ libcore.so+0x003f10 │ Dynamic (Dobby)  │
│ com.dropper.net.SocketBridge#connectRaw  │ (Ljava/lang/String.. │ libcore.so+0x004890 │ Dynamic (Dobby)  │
└──────────────────────────────────────────┴──────────────────────┴─────────────────────┴──────────────────┘
[+] Synced 14 function signatures and JNIEnv* types to Ghidra project: banker_dropper.gpr

2. Ghidra 中的前后对比

使用 JNISleuth-MCP 之前(FUN_000123c8):

long FUN_000123c8(long *param_1, undefined8 param_2, undefined8 param_3, undefined8 param_4) {
  char *pcVar1;
  long lVar2;
  pcVar1 = (char *)(**(code **)(*param_1 + 0x548))(param_1, param_4, 0);
  lVar2 = (**(code **)(*param_1 + 0x5c0))(param_1, param_3, 0);
  sub_00014a00(lVar2, pcVar1);
  (**(code **)(*param_1 + 0x550))(param_1, param_4, pcVar1);
  return param_3;
}

在 JNISleuth-MCP 之后(Java_com_dropper_Core_decryptPayload):

jbyteArray Java_com_dropper_Core_decryptPayload(
    JNIEnv *env, jobject thiz, jbyteArray encryptedData, jstring rc4KeyStr) 
{
  const char *key_utf = (*env)->GetStringUTFChars(env, rc4KeyStr, NULL);
  jbyte *payload_bytes = (*env)->GetByteArrayElements(env, encryptedData, NULL);
  rc4_crypt_buffer(payload_bytes, key_utf);
  (*env)->ReleaseStringUTFChars(env, rc4KeyStr, key_utf);
  return encryptedData;
}

🤖 通用 LLM 与 MCP 支持(适用于任何模型)

JNISleuth-MCP 100% 与模型无关。你可以通过标准的模型上下文协议(stdio JSON-RPC 2.0)将其连接到任何云端或本地 LLM,或导出原生的 OpenAI / Gemini / Ollama 函数调用 schema:

  • 云端 LLM 与智能体: Google Gemini CLI、OpenAI / ChatGPT Desktop / Codex CLI、Cursor、Windsurf、Cline、Roo Code、Claude Desktop / Claude Code
  • 本地 / 自托管 LLM: Ollama、vLLM、LM Studio、OpenWebUI、Continue.dev(DeepSeek-R1、Qwen-2.5-Coder、Llama-3.3)
  • 自定义 Python 智能体 SDK: 直接导出工具 schema(jnisleuth llm-tools --format openai|gemini|mcp),适用于 LangChain、LlamaIndex、LiteLLM、OpenAI SDK 或 google-genai。
工具名称描述
resolve_apk_jni_map(apk_path)从 DEX 中提取所有 native 声明,并将其映射到 lib/*.so 中精确的 ELF 文件偏移(通过导出符号、静态 .rodata 三元组或动态跟踪导入)。
get_cross_boundary_slice(java_method)在单个统一响应中返回反编译的 Java 调用方(通过 Jadx)以及带类型的、反编译的 C/ARM64 实现(通过 Ghidra/IDA)。
trace_jni_upcalls(so_name, fn_offset)列出在原生 ARM64 函数及其被调用方内部调用的每个 Java 反射回调(FindClass、GetMethodID、CallObjectMethod、SetByteArrayRegion)。
sync_ghidra_jni_types(trace_json)将 JNIEnv*、JavaVM*、JNINativeMethod 结构体以及恢复的函数签名直接应用到活动或无头 Ghidra 项目中。
sync_ida_jni_types(trace_json)将 JNIEnv*、JavaVM*、JNINativeMethod C 头文件、恢复的函数原型以及 OLLVM fl_JN 代码交叉引用应用到 IDA Pro 9.0(idalib / idapyswitch / idat64)。
resolve_ollvm_indirect_branches(so_name, fn_offset)解析 JNI_OnLoad 中的 OLLVM CSEL + BR X8 状态机分发器和 .rodata 跳转表,并可选地用直接的 B.<cond> / B 指令修补 ELF 二进制文件。
extract_jni_onload_strings(so_name)转储 .init_array 和 JNI_OnLoad 内部由栈构造和 XOR 解密的字符串。

🥷 隐蔽 Dobby 智能体(反 RASP 与加壳模式)

许多野外 Android 恶意软件家族和商业保护器一旦在 /proc/self/maps 中检测到 frida-agent.so、gum-js-loop 线程,或 libc.so 中被修改的函数序言,就会立即崩溃或退出。

JNISleuth-MCP 包含一个可选的零 Frida 原生收集器(agent-native/),使用 C++20 和 ARM64 汇编编写,基于 Dobby:

  • 函数中部 Hook: 将 Hook 放置在 ArtMethod::RegisterNative / JNIEnvExt::RegisterNatives 分发路径内部,而非导出桩的第一条指令,从而规避基本的序言完整性扫描器。
  • 基址归一化: 使用 dladdr() 和链接器 soinfo 遍历来自动减去 ASLR 偏移并记录确定性的文件偏移(libfoo.so + 0x23c8),即使加壳器在 JNI_OnLoad 之后取消映射 ELF 节头也能正常工作。

🚀 2 分钟快速上手

前置条件

  • Python 3.10+(pip install uv)
  • Ghidra 11.0+(GHIDRA_INSTALL_DIR)或 IDA Pro 9.0+(IDA_INSTALL_DIR / idapyswitch)
  • 已安装 Jadx CLI 并位于 $PATH 中
  • (可选) Android NDK r26+ 与 ADB,用于动态 Dobby 收集
下载工具