@jshookmcp/jshook 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -5
- package/README.zh.md +36 -5
- package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-CqGDXmfc.mjs} +160 -54
- package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-BdjRfNx7.mjs} +5 -5
- package/dist/ConsoleMonitor-DykL3IAw.mjs +2269 -0
- package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-ETyy0xyo.mjs} +1 -1
- package/dist/DetailedDataManager-HT49OrvF.mjs +217 -0
- package/dist/EventBus-DFKvADm3.mjs +141 -0
- package/dist/EvidenceGraphBridge-318Oi0Lf.mjs +153 -0
- package/dist/{ExtensionManager-D5-bO9D8.mjs → ExtensionManager-BDMsY2Dz.mjs} +27 -13
- package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-BN4UQWnX.mjs} +1 -1
- package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-Cc2AFq1Y.mjs} +3 -3
- package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-DruMgsgj.mjs} +21 -21
- package/dist/HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs +566 -0
- package/dist/InstrumentationSession-DLH0vd-z.mjs +244 -0
- package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CMtviNW_.mjs} +3 -3
- package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-ITgb_NMi.mjs} +81 -78
- package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-CiL7Z3ey.mjs} +50 -21
- package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-D9Lkovvn.mjs} +20 -56
- package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-BBlAixF5.mjs} +1 -1
- package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-DMQ44gen.mjs} +16 -16
- package/dist/PageController-BPJNqqBN.mjs +431 -0
- package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-K7wN8Z-w.mjs} +10 -7
- package/dist/PrerequisiteError-TuyZIs6n.mjs +20 -0
- package/dist/ProcessRegistry-zGg12QbE.mjs +74 -0
- package/dist/ResponseBuilder-CJXWmWNw.mjs +143 -0
- package/dist/ReverseEvidenceGraph-C02-gXOh.mjs +269 -0
- package/dist/ScriptManager-ZuWD-0Jg.mjs +3003 -0
- package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-D-z0umeT.mjs} +2 -2
- package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-Cav5AVSL.mjs} +9 -6
- package/dist/ToolCatalog-5OJdMiF0.mjs +582 -0
- package/dist/ToolError-jh9whhMd.mjs +15 -0
- package/dist/ToolProbe-DbCFGyrg.mjs +45 -0
- package/dist/ToolRegistry-B9krbTtI.mjs +180 -0
- package/dist/ToolRouter.policy-BGDAGyeH.mjs +344 -0
- package/dist/TraceRecorder-B41Z5XBj.mjs +1286 -0
- package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-C2kjj0ze.mjs} +19 -13
- package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-CKrGOTpo.mjs} +3 -3
- package/dist/WorkflowEngine-DJ6M4opp.mjs +569 -0
- package/dist/analysis-BHeJW2Nb.mjs +1234 -0
- package/dist/antidebug-BRKeyt27.mjs +1081 -0
- package/dist/artifactRetention-CPXkUJXp.mjs +598 -0
- package/dist/artifacts-DkfosXH3.mjs +59 -0
- package/dist/authorization-schema-DRqyJMSk.mjs +31 -0
- package/dist/betterSqlite3-DLSBZodi.mjs +74 -0
- package/dist/binary-instrument--V3MAhJ4.mjs +971 -0
- package/dist/bind-helpers-ClV34xdn.mjs +42 -0
- package/dist/boringssl-inspector-Bo_LOLaS.mjs +180 -0
- package/dist/browser-Dx3_S2cG.mjs +4369 -0
- package/dist/capabilities-CcHlvWgK.mjs +33 -0
- package/dist/concurrency-Drev_Vz9.mjs +41 -0
- package/dist/{constants-CCvsN80K.mjs → constants-CDZLOoVv.mjs} +105 -48
- package/dist/coordination-DgItD9DL.mjs +259 -0
- package/dist/debugger-RS3RSAqs.mjs +1288 -0
- package/dist/definitions-BEoYofW5.mjs +47 -0
- package/dist/definitions-BRaefg3u.mjs +365 -0
- package/dist/definitions-BbkvZkiv.mjs +96 -0
- package/dist/definitions-BtWSHJ3o.mjs +17 -0
- package/dist/definitions-C1gCHO0i.mjs +43 -0
- package/dist/definitions-CDOg_b-l.mjs +138 -0
- package/dist/definitions-CVPD9hzZ.mjs +54 -0
- package/dist/definitions-Cea8Lgl7.mjs +94 -0
- package/dist/definitions-DAgIyjxM.mjs +10 -0
- package/dist/definitions-DJA27nsL.mjs +66 -0
- package/dist/definitions-DKPFU3LW.mjs +25 -0
- package/dist/definitions-DPRpZQ96.mjs +47 -0
- package/dist/definitions-DUE5gmdn.mjs +18 -0
- package/dist/definitions-DYVjOtxa.mjs +26 -0
- package/dist/definitions-DcYLVLCo.mjs +37 -0
- package/dist/definitions-Pp5LI2H4.mjs +27 -0
- package/dist/definitions-j9KdHVNR.mjs +14 -0
- package/dist/definitions-uzkjBwa7.mjs +258 -0
- package/dist/definitions-va-AnLuQ.mjs +28 -0
- package/dist/encoding-DJeqHmpd.mjs +1079 -0
- package/dist/evidence-graph-bridge-DcYizFk2.mjs +136 -0
- package/dist/{factory-CibqTNC8.mjs → factory-C90tBff6.mjs} +41 -56
- package/dist/flat-target-session-Dgax2Cy3.mjs +29 -0
- package/dist/graphql-CoHrhweh.mjs +1197 -0
- package/dist/handlers-4jmR0nMs.mjs +898 -0
- package/dist/handlers-BAHPxcch.mjs +789 -0
- package/dist/handlers-BOs9b907.mjs +2600 -0
- package/dist/handlers-BWXEy6ef.mjs +917 -0
- package/dist/handlers-Bndn6QvE.mjs +111 -0
- package/dist/handlers-BqC4bD4s.mjs +681 -0
- package/dist/handlers-BtYq60bM2.mjs +276 -0
- package/dist/handlers-BzgcB4iv.mjs +799 -0
- package/dist/handlers-CRyRWj2b.mjs +859 -0
- package/dist/handlers-CVv2H1uq.mjs +592 -0
- package/dist/handlers-Dl5a7JS4.mjs +572 -0
- package/dist/handlers-Dx2d7jt7.mjs +2537 -0
- package/dist/handlers-Dz9PYsCa.mjs +2805 -0
- package/dist/handlers-HujRKC3b.mjs +661 -0
- package/dist/handlers.impl-XWXkQfyi.mjs +807 -0
- package/dist/hooks-B1B8NRHL.mjs +898 -0
- package/dist/index.mjs +491 -259
- package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
- package/dist/maintenance-PRMkLVRW.mjs +835 -0
- package/dist/manifest-67Bok-Si.mjs +58 -0
- package/dist/manifest-6lNTMZAB2.mjs +87 -0
- package/dist/manifest-B2duEHiH.mjs +90 -0
- package/dist/manifest-B6EY9Vm8.mjs +57 -0
- package/dist/manifest-B6nKSbyY.mjs +95 -0
- package/dist/manifest-BL8AQNPF.mjs +106 -0
- package/dist/manifest-BSZvJJmV.mjs +47 -0
- package/dist/manifest-BU7qzUyX.mjs +418 -0
- package/dist/manifest-Bl62e8WK.mjs +49 -0
- package/dist/manifest-Bo5cXjdt.mjs +82 -0
- package/dist/manifest-BpS4gtUK.mjs +1347 -0
- package/dist/manifest-Bv65_e2W.mjs +101 -0
- package/dist/manifest-BytNIF4Z.mjs +117 -0
- package/dist/manifest-C-xtsjS3.mjs +81 -0
- package/dist/manifest-CDYl7OhA.mjs +66 -0
- package/dist/manifest-CRZ3xmkD.mjs +61 -0
- package/dist/manifest-CoW6u4Tp.mjs +132 -0
- package/dist/manifest-Cq5zN_8A.mjs +50 -0
- package/dist/manifest-D7YZM_2e.mjs +194 -0
- package/dist/manifest-DE_VrAeQ.mjs +314 -0
- package/dist/manifest-DGsXSCpT.mjs +39 -0
- package/dist/manifest-DJ2vfEuW.mjs +156 -0
- package/dist/manifest-DPXDYhEu.mjs +80 -0
- package/dist/manifest-Dd4fQb0a.mjs +322 -0
- package/dist/manifest-Deq6opGg.mjs +223 -0
- package/dist/manifest-DfJTafJK.mjs +37 -0
- package/dist/manifest-DgOdgN_j.mjs +50 -0
- package/dist/manifest-DlbMW4v4.mjs +47 -0
- package/dist/manifest-DmVfbH0w.mjs +374 -0
- package/dist/manifest-Dog6Ddjr.mjs +109 -0
- package/dist/manifest-DvgU5FWb.mjs +58 -0
- package/dist/manifest-HsfDBs7j.mjs +50 -0
- package/dist/manifest-I8oQHvCG.mjs +186 -0
- package/dist/manifest-NvH_a-av.mjs +786 -0
- package/dist/manifest-cEJU1v0Z.mjs +129 -0
- package/dist/manifest-wOl5XLB12.mjs +112 -0
- package/dist/modules-tZozf0LQ.mjs +10635 -0
- package/dist/mojo-ipc-DXNEXEqb.mjs +640 -0
- package/dist/network-CPVvwvFg.mjs +3852 -0
- package/dist/{artifacts-BbdOMET5.mjs → outputPaths-um7lCRY3.mjs} +219 -216
- package/dist/parse-args-B4cY5Vx5.mjs +39 -0
- package/dist/platform-CYeFoTWp.mjs +2161 -0
- package/dist/process-BTbgcVc6.mjs +1306 -0
- package/dist/proxy-r8YN6nP1.mjs +192 -0
- package/dist/registry-Bl8ZQW61.mjs +34 -0
- package/dist/response-CWhh2aLo.mjs +34 -0
- package/dist/server/plugin-api.mjs +2 -2
- package/dist/shared-state-board-BoZnSoj-.mjs +586 -0
- package/dist/sourcemap-BIDHUVXy.mjs +934 -0
- package/dist/ssrf-policy-Dsqd-DTX.mjs +166 -0
- package/dist/streaming-Dal6utPp.mjs +725 -0
- package/dist/tool-builder-BHJp32mV.mjs +186 -0
- package/dist/transform-DRVgGG90.mjs +1011 -0
- package/dist/types-Bx92KJfT.mjs +4 -0
- package/dist/wasm-BYx5UOeG.mjs +1044 -0
- package/dist/webcrack-Be0_FccV.mjs +747 -0
- package/dist/workflow-BpuKEtvn.mjs +725 -0
- package/package.json +82 -49
- package/dist/ExtensionManager-CPTJhHFg.mjs +0 -2
- package/dist/ToolCatalog-Bq4V2sbJ.mjs +0 -67201
- package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-jJFy20G-.mjs} +0 -0
- package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-BWmPgQsv.mjs} +0 -0
- package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-K3V4vGsw.mjs} +0 -0
- package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-nnMvEohD.mjs} +0 -0
- package/dist/{types-BBjOqye-.mjs → types-DDBWs9UP.mjs} +1 -1
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { n as toolLookup } from "./registry-Bl8ZQW61.mjs";
|
|
2
|
+
import { n as defineMethodRegistrations } from "./bind-helpers-ClV34xdn.mjs";
|
|
3
|
+
import { t as tool } from "./tool-builder-BHJp32mV.mjs";
|
|
4
|
+
//#region src/server/domains/binary-instrument/definitions.ts
|
|
5
|
+
const binaryInstrumentTools = [
|
|
6
|
+
tool("binary_instrument_capabilities", (t) => t.desc("Report binary instrumentation backend availability.").query()),
|
|
7
|
+
tool("frida_attach", (t) => t.desc("Attach Frida to a local target and open a session.").string("target", "Process name, PID, or binary path to attach to").required("target")),
|
|
8
|
+
tool("frida_enumerate_modules", (t) => t.desc("Enumerate modules for an attached Frida session.").string("sessionId", "Session id returned by frida_attach").required("sessionId").query()),
|
|
9
|
+
tool("ghidra_analyze", (t) => t.desc("Analyze a binary and return metadata.").string("binaryPath", "Path to the binary file").number("timeout", "Optional timeout in milliseconds for headless analysis").required("binaryPath")),
|
|
10
|
+
tool("generate_hooks", (t) => t.desc("Generate a Frida interceptor script for a list of symbols.").array("symbols", { type: "string" }, "Symbol names to hook").object("options", {
|
|
11
|
+
includeArgs: {
|
|
12
|
+
type: "boolean",
|
|
13
|
+
description: "Emit argument logging on function entry"
|
|
14
|
+
},
|
|
15
|
+
includeRetAddr: {
|
|
16
|
+
type: "boolean",
|
|
17
|
+
description: "Emit return-address logging on function entry"
|
|
18
|
+
}
|
|
19
|
+
}, "Optional Frida hook generation flags").required("symbols")),
|
|
20
|
+
tool("unidbg_emulate", (t) => t.desc("Emulate a native function with Unidbg when available.").string("binaryPath", "Path to the binary file").string("functionName", "Function name to emulate").array("args", { type: "string" }, "Optional string arguments forwarded to emulation").required("binaryPath", "functionName")),
|
|
21
|
+
tool("frida_run_script", (t) => t.desc("Execute a Frida JavaScript snippet inside an attached Frida session.").string("sessionId", "Session id returned by frida_attach").string("script", "Frida JavaScript to execute").required("sessionId", "script")),
|
|
22
|
+
tool("frida_detach", (t) => t.desc("Detach from a Frida session and clean up resources.").string("sessionId", "Session id returned by frida_attach").required("sessionId")),
|
|
23
|
+
tool("frida_list_sessions", (t) => t.desc("List all active Frida sessions.").query()),
|
|
24
|
+
tool("frida_generate_script", (t) => t.desc("Generate a Frida hook script from a template.").string("target", "Target binary or module name").string("template", "Hook template type: trace, intercept, replace, log").string("functionName", "Function name to generate hook for").required("target", "template")),
|
|
25
|
+
tool("get_available_plugins", (t) => t.desc("List installed binary analysis plugins.").query()),
|
|
26
|
+
tool("ghidra_decompile", (t) => t.desc("Decompile a specific function using Ghidra headless analysis.").string("binaryPath", "Path to the binary file").string("functionName", "Function name to decompile").required("binaryPath", "functionName")),
|
|
27
|
+
tool("ida_decompile", (t) => t.desc("Decompile a function using IDA Pro via plugin bridge.").string("binaryPath", "Path to the binary file").string("functionName", "Function name to decompile").required("binaryPath", "functionName")),
|
|
28
|
+
tool("jadx_decompile", (t) => t.desc("Decompile an APK class or method using JADX via plugin bridge.").string("apkPath", "Path to the APK file").string("className", "Fully qualified class name").string("methodName", "Method name to decompile").required("apkPath", "className")),
|
|
29
|
+
tool("unidbg_launch", (t) => t.desc("Launch a shared library in Unidbg.").string("soPath", "Path to the .so library file").string("arch", "Architecture: arm or arm64").required("soPath")),
|
|
30
|
+
tool("unidbg_call", (t) => t.desc("Call a JNI function in a running Unidbg emulator session.").string("sessionId", "Session id from unidbg_launch").string("functionName", "JNI function name to call").required("sessionId", "functionName")),
|
|
31
|
+
tool("unidbg_trace", (t) => t.desc("Get an execution trace from an Unidbg session (full/basic/instruction modes).").string("sessionId", "Session id from unidbg_launch").required("sessionId")),
|
|
32
|
+
tool("export_hook_script", (t) => t.desc("Export generated hook templates as a complete, runnable Frida script.").string("hookTemplates", "JSON array of hook template objects")),
|
|
33
|
+
tool("frida_enumerate_functions", (t) => t.desc("Enumerate exported functions for a specific module in a Frida session.").string("sessionId", "Session id returned by frida_attach").string("moduleName", "Module name to enumerate exports from").required("sessionId", "moduleName").query()),
|
|
34
|
+
tool("frida_find_symbols", (t) => t.desc("Search for symbols matching a pattern in a Frida session using ApiResolver.").string("sessionId", "Session id returned by frida_attach").string("pattern", "Symbol search pattern (e.g. \"exports:*libssl*SSL*\")").required("sessionId", "pattern").query())
|
|
35
|
+
];
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/server/domains/binary-instrument/manifest.ts
|
|
38
|
+
const DOMAIN = "binary-instrument";
|
|
39
|
+
const DEP_KEY = "binaryInstrumentHandlers";
|
|
40
|
+
const registrations = defineMethodRegistrations({
|
|
41
|
+
domain: DOMAIN,
|
|
42
|
+
depKey: DEP_KEY,
|
|
43
|
+
lookup: toolLookup(binaryInstrumentTools),
|
|
44
|
+
entries: [
|
|
45
|
+
{
|
|
46
|
+
tool: "binary_instrument_capabilities",
|
|
47
|
+
method: "handleBinaryInstrumentCapabilities"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
tool: "frida_attach",
|
|
51
|
+
method: "handleFridaAttach"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
tool: "frida_enumerate_modules",
|
|
55
|
+
method: "handleFridaEnumerateModules"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
tool: "ghidra_analyze",
|
|
59
|
+
method: "handleGhidraAnalyze"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
tool: "generate_hooks",
|
|
63
|
+
method: "handleGenerateHooks"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
tool: "unidbg_emulate",
|
|
67
|
+
method: "handleUnidbgEmulate"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
tool: "frida_run_script",
|
|
71
|
+
method: "handleFridaRunScript"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
tool: "frida_detach",
|
|
75
|
+
method: "handleFridaDetach"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
tool: "frida_list_sessions",
|
|
79
|
+
method: "handleFridaListSessions"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
tool: "frida_generate_script",
|
|
83
|
+
method: "handleFridaGenerateScript"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
tool: "get_available_plugins",
|
|
87
|
+
method: "handleGetAvailablePlugins"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
tool: "ghidra_decompile",
|
|
91
|
+
method: "handleGhidraDecompile"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
tool: "ida_decompile",
|
|
95
|
+
method: "handleIdaDecompile"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
tool: "jadx_decompile",
|
|
99
|
+
method: "handleJadxDecompile"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
tool: "unidbg_launch",
|
|
103
|
+
method: "handleUnidbgLaunch"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
tool: "unidbg_call",
|
|
107
|
+
method: "handleUnidbgCall"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
tool: "unidbg_trace",
|
|
111
|
+
method: "handleUnidbgTrace"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
tool: "export_hook_script",
|
|
115
|
+
method: "handleExportHookScript"
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
tool: "frida_enumerate_functions",
|
|
119
|
+
method: "handleFridaEnumerateFunctions"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
tool: "frida_find_symbols",
|
|
123
|
+
method: "handleFridaFindSymbols"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
});
|
|
127
|
+
async function ensure(ctx) {
|
|
128
|
+
const { BinaryInstrumentHandlers } = await import("./handlers-CRyRWj2b.mjs");
|
|
129
|
+
const { GhidraAnalyzer, HookGenerator } = await import("./binary-instrument--V3MAhJ4.mjs").then((n) => n.t);
|
|
130
|
+
let handlers = ctx.getDomainInstance(DEP_KEY);
|
|
131
|
+
if (!handlers) {
|
|
132
|
+
handlers = new BinaryInstrumentHandlers(ctx, new GhidraAnalyzer(), new HookGenerator());
|
|
133
|
+
ctx.setDomainInstance(DEP_KEY, handlers);
|
|
134
|
+
}
|
|
135
|
+
return handlers;
|
|
136
|
+
}
|
|
137
|
+
const manifest = {
|
|
138
|
+
kind: "domain-manifest",
|
|
139
|
+
version: 1,
|
|
140
|
+
domain: DOMAIN,
|
|
141
|
+
depKey: DEP_KEY,
|
|
142
|
+
profiles: ["full"],
|
|
143
|
+
ensure,
|
|
144
|
+
registrations,
|
|
145
|
+
workflowRule: {
|
|
146
|
+
patterns: [/\b(frida|ghidra|ida|unidbg|jadx|binary|disassemb|decompil|dump\s?so)\b/i, /(binary|native|so|dll|elf|apk).*(analyze|hook|instrument|decompile)/i],
|
|
147
|
+
priority: 88,
|
|
148
|
+
tools: [
|
|
149
|
+
"frida_attach",
|
|
150
|
+
"ghidra_analyze",
|
|
151
|
+
"generate_hooks",
|
|
152
|
+
"unidbg_launch"
|
|
153
|
+
],
|
|
154
|
+
hint: "Binary analysis pipeline: attach Frida → decompile (Ghidra/IDA/JADX) → generate hook scripts → emulate with Unidbg."
|
|
155
|
+
},
|
|
156
|
+
prerequisites: {
|
|
157
|
+
frida_attach: [{
|
|
158
|
+
condition: "plugin_frida_bridge must be installed and frida-server reachable",
|
|
159
|
+
fix: "Install @jshookmcpextension/plugin-frida-bridge; launch frida-server on the target"
|
|
160
|
+
}],
|
|
161
|
+
frida_run_script: [{
|
|
162
|
+
condition: "A Frida session must be active",
|
|
163
|
+
fix: "Call frida_attach before running a script"
|
|
164
|
+
}],
|
|
165
|
+
ghidra_analyze: [{
|
|
166
|
+
condition: "plugin_ghidra_bridge must be installed with Ghidra headless available",
|
|
167
|
+
fix: "Install @jshookmcpextension/plugin-ghidra-bridge and configure Ghidra path"
|
|
168
|
+
}],
|
|
169
|
+
ida_decompile: [{
|
|
170
|
+
condition: "plugin_ida_bridge must be installed",
|
|
171
|
+
fix: "Install @jshookmcpextension/plugin-ida-bridge and provide IDA Pro license"
|
|
172
|
+
}],
|
|
173
|
+
jadx_decompile: [{
|
|
174
|
+
condition: "plugin_jadx_bridge must be installed",
|
|
175
|
+
fix: "Install @jshookmcpextension/plugin-jadx-bridge"
|
|
176
|
+
}],
|
|
177
|
+
unidbg_launch: [{
|
|
178
|
+
condition: "Java 17+ and unidbg JAR must be reachable",
|
|
179
|
+
fix: "Install JDK 17+ and download unidbg from its official release"
|
|
180
|
+
}],
|
|
181
|
+
generate_hooks: [{
|
|
182
|
+
condition: "Ghidra analysis output required",
|
|
183
|
+
fix: "Run ghidra_analyze first and pass the output to generate_hooks"
|
|
184
|
+
}]
|
|
185
|
+
},
|
|
186
|
+
toolDependencies: [{
|
|
187
|
+
from: "process",
|
|
188
|
+
to: "binary-instrument",
|
|
189
|
+
relation: "uses",
|
|
190
|
+
weight: .6
|
|
191
|
+
}]
|
|
192
|
+
};
|
|
193
|
+
//#endregion
|
|
194
|
+
export { manifest as default };
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { t as logger } from "./logger-Dh_xb7_2.mjs";
|
|
2
|
+
import { t as createProgressDebouncer } from "./EventBus-DFKvADm3.mjs";
|
|
3
|
+
import { n as toolLookup, t as ensureBrowserCore } from "./registry-Bl8ZQW61.mjs";
|
|
4
|
+
import { t as coreTools } from "./definitions-CDOg_b-l.mjs";
|
|
5
|
+
//#region src/modules/deobfuscator/LLMDeobfuscator.ts
|
|
6
|
+
/** Maximum code snippet size sent to the LLM (chars) to avoid token overflow */
|
|
7
|
+
const MAX_CODE_SNIPPET = 2e3;
|
|
8
|
+
/** Maximum number of identifiers to send in one request */
|
|
9
|
+
const MAX_IDENTIFIERS = 20;
|
|
10
|
+
var LLMDeobfuscator = class {
|
|
11
|
+
constructor(bridge) {
|
|
12
|
+
this.bridge = bridge;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if the underlying sampling bridge supports LLM delegation.
|
|
16
|
+
*/
|
|
17
|
+
isAvailable() {
|
|
18
|
+
return this.bridge.isSamplingSupported();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Use the client's LLM to suggest meaningful names for obfuscated identifiers.
|
|
22
|
+
*
|
|
23
|
+
* @param code - The obfuscated code snippet (truncated to MAX_CODE_SNIPPET)
|
|
24
|
+
* @param identifiers - Array of obfuscated identifier names to rename
|
|
25
|
+
* @returns Map of old → new names, or `null` if sampling unavailable/failed
|
|
26
|
+
*/
|
|
27
|
+
async suggestVariableNames(code, identifiers) {
|
|
28
|
+
if (!this.bridge.isSamplingSupported()) {
|
|
29
|
+
logger.debug("LLMDeobfuscator: sampling not available, skipping name suggestion");
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const trimmedIds = identifiers.slice(0, MAX_IDENTIFIERS);
|
|
33
|
+
const trimmedCode = code.slice(0, MAX_CODE_SNIPPET);
|
|
34
|
+
const userMessage = [
|
|
35
|
+
"Given this obfuscated JavaScript code, suggest meaningful variable/function names",
|
|
36
|
+
`for these identifiers: ${trimmedIds.join(", ")}`,
|
|
37
|
+
"",
|
|
38
|
+
"```javascript",
|
|
39
|
+
trimmedCode,
|
|
40
|
+
"```",
|
|
41
|
+
"",
|
|
42
|
+
"Respond ONLY with a valid JSON array of objects with fields:",
|
|
43
|
+
" { \"original\": \"<old_name>\", \"suggested\": \"<new_name>\", \"confidence\": \"high\"|\"medium\"|\"low\" }",
|
|
44
|
+
"",
|
|
45
|
+
"Rules:",
|
|
46
|
+
"- Use camelCase for variables/functions, PascalCase for classes",
|
|
47
|
+
"- If uncertain, use confidence \"low\"",
|
|
48
|
+
"- If the name is already meaningful, keep it and mark confidence \"high\""
|
|
49
|
+
].join("\n");
|
|
50
|
+
const result = await this.bridge.sampleText({
|
|
51
|
+
systemPrompt: "You are an expert JavaScript reverse engineer. You specialize in deobfuscation and renaming obfuscated identifiers to semantically meaningful names. Output only valid JSON.",
|
|
52
|
+
userMessage,
|
|
53
|
+
maxTokens: 256,
|
|
54
|
+
temperature: .3,
|
|
55
|
+
modelHint: "haiku"
|
|
56
|
+
});
|
|
57
|
+
if (!result) return null;
|
|
58
|
+
return this.parseNameSuggestions(result, trimmedIds);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Use the client's LLM to infer the purpose of a function from its code.
|
|
62
|
+
*
|
|
63
|
+
* @param code - The function's code snippet
|
|
64
|
+
* @returns A brief description of the function's purpose, or null
|
|
65
|
+
*/
|
|
66
|
+
async inferFunctionPurpose(code) {
|
|
67
|
+
if (!this.bridge.isSamplingSupported()) return null;
|
|
68
|
+
const trimmedCode = code.slice(0, MAX_CODE_SNIPPET);
|
|
69
|
+
return (await this.bridge.sampleText({
|
|
70
|
+
systemPrompt: "You are a JavaScript reverse engineer. Analyze code and describe its purpose in one concise sentence.",
|
|
71
|
+
userMessage: `What does this function do?\n\n\`\`\`javascript\n${trimmedCode}\n\`\`\`\n\nRespond with a single sentence.`,
|
|
72
|
+
maxTokens: 100,
|
|
73
|
+
temperature: .2,
|
|
74
|
+
modelHint: "haiku"
|
|
75
|
+
}))?.trim() ?? null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parse the LLM's JSON response into structured name suggestions.
|
|
79
|
+
* Robust against malformed output.
|
|
80
|
+
*/
|
|
81
|
+
parseNameSuggestions(rawResponse, expectedIds) {
|
|
82
|
+
try {
|
|
83
|
+
const jsonMatch = rawResponse.match(/\[[\s\S]*\]/);
|
|
84
|
+
if (!jsonMatch) {
|
|
85
|
+
logger.warn("LLMDeobfuscator: no JSON array found in LLM response");
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
89
|
+
if (!Array.isArray(parsed)) return [];
|
|
90
|
+
const expectedSet = new Set(expectedIds);
|
|
91
|
+
return parsed.filter((item) => typeof item === "object" && item !== null && typeof item.original === "string" && typeof item.suggested === "string").filter((item) => expectedSet.has(item.original)).map((item) => ({
|
|
92
|
+
original: item.original,
|
|
93
|
+
suggested: item.suggested,
|
|
94
|
+
confidence: [
|
|
95
|
+
"high",
|
|
96
|
+
"medium",
|
|
97
|
+
"low"
|
|
98
|
+
].includes(item.confidence) ? item.confidence : "low"
|
|
99
|
+
}));
|
|
100
|
+
} catch (error) {
|
|
101
|
+
logger.warn("LLMDeobfuscator: failed to parse LLM response:", error);
|
|
102
|
+
return [];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region src/server/domains/analysis/manifest.ts
|
|
108
|
+
const DOMAIN = "core";
|
|
109
|
+
const DEP_KEY = "coreAnalysisHandlers";
|
|
110
|
+
const t = toolLookup(coreTools);
|
|
111
|
+
let globalContext = null;
|
|
112
|
+
/**
|
|
113
|
+
* Analysis-domain bind helper that threads `_meta.progressToken` into
|
|
114
|
+
* a throttled `onProgress` callback — same pattern as memory/manifest.ts.
|
|
115
|
+
*/
|
|
116
|
+
function bindWithProgress(invoke) {
|
|
117
|
+
return (deps) => {
|
|
118
|
+
const handler = deps[DEP_KEY];
|
|
119
|
+
return (args) => {
|
|
120
|
+
const meta = args._meta;
|
|
121
|
+
let onProgress;
|
|
122
|
+
if (meta?.progressToken !== void 0 && globalContext) onProgress = createProgressDebouncer(globalContext.eventBus, meta.progressToken);
|
|
123
|
+
return invoke(handler, {
|
|
124
|
+
...args,
|
|
125
|
+
onProgress
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const b = bindWithProgress;
|
|
131
|
+
async function ensure(ctx) {
|
|
132
|
+
const { Deobfuscator, AdvancedDeobfuscator, ObfuscationDetector, CodeAnalyzer, CryptoDetector, HookManager } = await import("./modules-tZozf0LQ.mjs").then((n) => n.t);
|
|
133
|
+
const { CoreAnalysisHandlers } = await import("./analysis-BHeJW2Nb.mjs");
|
|
134
|
+
globalContext = ctx;
|
|
135
|
+
await ensureBrowserCore(ctx);
|
|
136
|
+
if (!ctx.deobfuscator || !ctx.advancedDeobfuscator || !ctx.obfuscationDetector || !ctx.analyzer || !ctx.cryptoDetector || !ctx.hookManager || !ctx.coreAnalysisHandlers) {
|
|
137
|
+
if (!ctx.deobfuscator) ctx.deobfuscator = new Deobfuscator();
|
|
138
|
+
if (!ctx.advancedDeobfuscator) ctx.advancedDeobfuscator = new AdvancedDeobfuscator();
|
|
139
|
+
if (!ctx.obfuscationDetector) ctx.obfuscationDetector = new ObfuscationDetector();
|
|
140
|
+
if (!ctx.analyzer) ctx.analyzer = new CodeAnalyzer();
|
|
141
|
+
if (!ctx.cryptoDetector) ctx.cryptoDetector = new CryptoDetector();
|
|
142
|
+
if (!ctx.hookManager) ctx.hookManager = new HookManager();
|
|
143
|
+
if (!ctx.coreAnalysisHandlers) ctx.coreAnalysisHandlers = new CoreAnalysisHandlers({
|
|
144
|
+
collector: ctx.collector,
|
|
145
|
+
scriptManager: ctx.scriptManager,
|
|
146
|
+
deobfuscator: ctx.deobfuscator,
|
|
147
|
+
advancedDeobfuscator: ctx.advancedDeobfuscator,
|
|
148
|
+
obfuscationDetector: ctx.obfuscationDetector,
|
|
149
|
+
analyzer: ctx.analyzer,
|
|
150
|
+
cryptoDetector: ctx.cryptoDetector,
|
|
151
|
+
hookManager: ctx.hookManager
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
return ctx.coreAnalysisHandlers;
|
|
155
|
+
}
|
|
156
|
+
const manifest = {
|
|
157
|
+
kind: "domain-manifest",
|
|
158
|
+
version: 1,
|
|
159
|
+
domain: DOMAIN,
|
|
160
|
+
depKey: DEP_KEY,
|
|
161
|
+
profiles: ["workflow", "full"],
|
|
162
|
+
ensure,
|
|
163
|
+
workflowRule: {
|
|
164
|
+
patterns: [/(deobfuscate|deobfusc|beautify|analyze).*(javascript|js|script|code)/i, /(反混淆|美化|分析).*(javascript|js|脚本|代码)/i],
|
|
165
|
+
priority: 85,
|
|
166
|
+
tools: [
|
|
167
|
+
"deobfuscate",
|
|
168
|
+
"extract_function_tree",
|
|
169
|
+
"llm_suggest_names"
|
|
170
|
+
],
|
|
171
|
+
hint: "JavaScript analysis workflow: collect -> deobfuscate -> inspect function tree | LLM-powered naming"
|
|
172
|
+
},
|
|
173
|
+
prerequisites: { collect_code: [{
|
|
174
|
+
condition: "Browser must be launched",
|
|
175
|
+
fix: "Call browser_launch or browser_attach first"
|
|
176
|
+
}] },
|
|
177
|
+
registrations: [
|
|
178
|
+
{
|
|
179
|
+
tool: t("collect_code"),
|
|
180
|
+
domain: DOMAIN,
|
|
181
|
+
bind: b((h, a) => h.handleCollectCode(a))
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
tool: t("search_in_scripts"),
|
|
185
|
+
domain: DOMAIN,
|
|
186
|
+
profiles: [
|
|
187
|
+
"search",
|
|
188
|
+
"workflow",
|
|
189
|
+
"full"
|
|
190
|
+
],
|
|
191
|
+
bind: b((h, a) => h.handleSearchInScripts(a))
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
tool: t("extract_function_tree"),
|
|
195
|
+
domain: DOMAIN,
|
|
196
|
+
bind: b((h, a) => h.handleExtractFunctionTree(a))
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
tool: t("deobfuscate"),
|
|
200
|
+
domain: DOMAIN,
|
|
201
|
+
bind: b((h, a) => h.handleDeobfuscate(a))
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
tool: t("understand_code"),
|
|
205
|
+
domain: DOMAIN,
|
|
206
|
+
profiles: [
|
|
207
|
+
"search",
|
|
208
|
+
"workflow",
|
|
209
|
+
"full"
|
|
210
|
+
],
|
|
211
|
+
bind: b((h, a) => h.handleUnderstandCode(a))
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
tool: t("detect_crypto"),
|
|
215
|
+
domain: DOMAIN,
|
|
216
|
+
profiles: [
|
|
217
|
+
"search",
|
|
218
|
+
"workflow",
|
|
219
|
+
"full"
|
|
220
|
+
],
|
|
221
|
+
bind: b((h, a) => h.handleDetectCrypto(a))
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
tool: t("manage_hooks"),
|
|
225
|
+
domain: DOMAIN,
|
|
226
|
+
bind: b((h, a) => h.handleManageHooks(a))
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
tool: t("detect_obfuscation"),
|
|
230
|
+
domain: DOMAIN,
|
|
231
|
+
profiles: [
|
|
232
|
+
"search",
|
|
233
|
+
"workflow",
|
|
234
|
+
"full"
|
|
235
|
+
],
|
|
236
|
+
bind: b((h, a) => h.handleDetectObfuscation(a))
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
tool: t("webcrack_unpack"),
|
|
240
|
+
domain: DOMAIN,
|
|
241
|
+
bind: b((h, a) => h.handleWebcrackUnpack(a))
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
tool: t("clear_collected_data"),
|
|
245
|
+
domain: DOMAIN,
|
|
246
|
+
bind: b((h) => h.handleClearCollectedData())
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
tool: t("get_collection_stats"),
|
|
250
|
+
domain: DOMAIN,
|
|
251
|
+
bind: b((h) => h.handleGetCollectionStats())
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
tool: t("webpack_enumerate"),
|
|
255
|
+
domain: DOMAIN,
|
|
256
|
+
bind: b((h, a) => h.handleWebpackEnumerate(a))
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
tool: t("llm_suggest_names"),
|
|
260
|
+
domain: DOMAIN,
|
|
261
|
+
bind: bindWithProgress(async (_h, args) => {
|
|
262
|
+
if (!globalContext) return { content: [{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: JSON.stringify({
|
|
265
|
+
success: false,
|
|
266
|
+
error: "Server context not initialized"
|
|
267
|
+
})
|
|
268
|
+
}] };
|
|
269
|
+
const deob = new LLMDeobfuscator(globalContext.samplingBridge);
|
|
270
|
+
if (!deob.isAvailable()) return { content: [{
|
|
271
|
+
type: "text",
|
|
272
|
+
text: JSON.stringify({
|
|
273
|
+
success: false,
|
|
274
|
+
error: "Sampling not supported by this client",
|
|
275
|
+
hint: "The connected MCP client does not declare sampling capabilities. Try using Claude Desktop or another sampling-capable client."
|
|
276
|
+
})
|
|
277
|
+
}] };
|
|
278
|
+
const code = typeof args.code === "string" ? args.code : "";
|
|
279
|
+
const identifiers = Array.isArray(args.identifiers) ? args.identifiers.filter((id) => typeof id === "string") : [];
|
|
280
|
+
const suggestions = await deob.suggestVariableNames(code, identifiers);
|
|
281
|
+
return { content: [{
|
|
282
|
+
type: "text",
|
|
283
|
+
text: JSON.stringify({
|
|
284
|
+
success: true,
|
|
285
|
+
suggestions: suggestions ?? [],
|
|
286
|
+
samplingUsed: true
|
|
287
|
+
})
|
|
288
|
+
}] };
|
|
289
|
+
})
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
tool: t("js_deobfuscate_jsvmp"),
|
|
293
|
+
domain: DOMAIN,
|
|
294
|
+
bind: b((h, a) => h.handleJsDeobfuscateJsvmp(a))
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
tool: t("js_deobfuscate_pipeline"),
|
|
298
|
+
domain: DOMAIN,
|
|
299
|
+
bind: b((h, a) => h.handleJsDeobfuscatePipeline(a))
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
tool: t("js_analyze_vm"),
|
|
303
|
+
domain: DOMAIN,
|
|
304
|
+
bind: b((h, a) => h.handleJsAnalyzeVm(a))
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
tool: t("js_solve_constraints"),
|
|
308
|
+
domain: DOMAIN,
|
|
309
|
+
bind: b((h, a) => h.handleJsSolveConstraints(a))
|
|
310
|
+
}
|
|
311
|
+
]
|
|
312
|
+
};
|
|
313
|
+
//#endregion
|
|
314
|
+
export { manifest as default };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { n as toolLookup } from "./registry-Bl8ZQW61.mjs";
|
|
2
|
+
import { n as defineMethodRegistrations } from "./bind-helpers-ClV34xdn.mjs";
|
|
3
|
+
import { t as antidebugTools } from "./definitions-DUE5gmdn.mjs";
|
|
4
|
+
//#region src/server/domains/antidebug/manifest.ts
|
|
5
|
+
const DOMAIN = "antidebug";
|
|
6
|
+
const DEP_KEY = "antidebugHandlers";
|
|
7
|
+
const registrations = defineMethodRegistrations({
|
|
8
|
+
domain: DOMAIN,
|
|
9
|
+
depKey: DEP_KEY,
|
|
10
|
+
lookup: toolLookup(antidebugTools),
|
|
11
|
+
entries: [{
|
|
12
|
+
tool: "antidebug_bypass",
|
|
13
|
+
method: "handleAntidebugBypass"
|
|
14
|
+
}, {
|
|
15
|
+
tool: "antidebug_detect_protections",
|
|
16
|
+
method: "handleAntiDebugDetectProtections"
|
|
17
|
+
}]
|
|
18
|
+
});
|
|
19
|
+
async function ensure(ctx) {
|
|
20
|
+
const { CodeCollector } = await import("./modules-tZozf0LQ.mjs").then((n) => n.t);
|
|
21
|
+
const { AntiDebugToolHandlers } = await import("./antidebug-BRKeyt27.mjs");
|
|
22
|
+
if (!ctx.collector) {
|
|
23
|
+
ctx.collector = new CodeCollector(ctx.config.puppeteer);
|
|
24
|
+
ctx.registerCaches();
|
|
25
|
+
}
|
|
26
|
+
if (!ctx.antidebugHandlers) ctx.antidebugHandlers = new AntiDebugToolHandlers(ctx.collector);
|
|
27
|
+
return ctx.antidebugHandlers;
|
|
28
|
+
}
|
|
29
|
+
const manifest = {
|
|
30
|
+
kind: "domain-manifest",
|
|
31
|
+
version: 1,
|
|
32
|
+
domain: DOMAIN,
|
|
33
|
+
depKey: DEP_KEY,
|
|
34
|
+
profiles: ["full"],
|
|
35
|
+
ensure,
|
|
36
|
+
registrations
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
export { manifest as default };
|