@reverse-craft/ai-tools 1.0.3 → 1.0.5
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/dist/{tools/findJsvmpDispatcherTool.test.d.ts → __tests__/findJsvmpDispatcherTool.property.test.d.ts} +1 -1
- package/dist/__tests__/findJsvmpDispatcherTool.property.test.d.ts.map +1 -0
- package/dist/jsvmpDetector.d.ts +39 -5
- package/dist/jsvmpDetector.d.ts.map +1 -1
- package/dist/llmConfig.d.ts.map +1 -1
- package/dist/server.js +196 -53
- package/dist/server.js.map +2 -2
- package/dist/tools/findJsvmpDispatcherTool.d.ts +3 -1
- package/dist/tools/findJsvmpDispatcherTool.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/index.js +0 -13
- package/dist/index.js.map +0 -1
- package/dist/jsvmpDetector.js +0 -283
- package/dist/jsvmpDetector.js.map +0 -1
- package/dist/llmConfig.js +0 -133
- package/dist/llmConfig.js.map +0 -1
- package/dist/tools/findJsvmpDispatcher.d.ts +0 -41
- package/dist/tools/findJsvmpDispatcher.d.ts.map +0 -1
- package/dist/tools/findJsvmpDispatcherTool.test.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findJsvmpDispatcherTool.property.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/findJsvmpDispatcherTool.property.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
package/dist/jsvmpDetector.d.ts
CHANGED
|
@@ -15,13 +15,37 @@ export interface FormattedCode {
|
|
|
15
15
|
/**
|
|
16
16
|
* Detection type for JSVMP patterns
|
|
17
17
|
*/
|
|
18
|
-
export type DetectionType = "If-Else Dispatcher" | "Switch Dispatcher" | "Instruction Array"
|
|
18
|
+
export type DetectionType = "If-Else Dispatcher" | "Switch Dispatcher" | "Instruction Array";
|
|
19
19
|
/**
|
|
20
20
|
* Confidence level for detection results
|
|
21
21
|
*/
|
|
22
22
|
export type ConfidenceLevel = "ultra_high" | "high" | "medium" | "low";
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* VM Component variable identification
|
|
25
|
+
*/
|
|
26
|
+
export interface VMComponentVariable {
|
|
27
|
+
variable_name: string | null;
|
|
28
|
+
confidence: ConfidenceLevel;
|
|
29
|
+
reasoning: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* VM Components for a JSVMP instance
|
|
33
|
+
*/
|
|
34
|
+
export interface VMComponents {
|
|
35
|
+
instruction_pointer: VMComponentVariable;
|
|
36
|
+
stack_pointer: VMComponentVariable;
|
|
37
|
+
virtual_stack: VMComponentVariable;
|
|
38
|
+
bytecode_array: VMComponentVariable;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Debugging entry point information
|
|
42
|
+
*/
|
|
43
|
+
export interface DebuggingEntryPoint {
|
|
44
|
+
line_number: number;
|
|
45
|
+
description: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A detected region in the code (enhanced with VM components)
|
|
25
49
|
*/
|
|
26
50
|
export interface DetectionRegion {
|
|
27
51
|
start: number;
|
|
@@ -29,12 +53,21 @@ export interface DetectionRegion {
|
|
|
29
53
|
type: DetectionType;
|
|
30
54
|
confidence: ConfidenceLevel;
|
|
31
55
|
description: string;
|
|
56
|
+
vm_components?: VMComponents;
|
|
57
|
+
debugging_entry_point?: DebuggingEntryPoint;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Summary information for detection result
|
|
61
|
+
*/
|
|
62
|
+
export interface DetectionSummary {
|
|
63
|
+
overall_description: string;
|
|
64
|
+
debugging_recommendation: string;
|
|
32
65
|
}
|
|
33
66
|
/**
|
|
34
|
-
* Complete detection result from LLM analysis
|
|
67
|
+
* Complete detection result from LLM analysis (enhanced)
|
|
35
68
|
*/
|
|
36
69
|
export interface DetectionResult {
|
|
37
|
-
summary: string;
|
|
70
|
+
summary: string | DetectionSummary;
|
|
38
71
|
regions: DetectionRegion[];
|
|
39
72
|
}
|
|
40
73
|
/**
|
|
@@ -120,8 +153,9 @@ export declare function createBatches(formattedLines: string[], maxTokensPerBatc
|
|
|
120
153
|
* Validates:
|
|
121
154
|
* - JSON is parseable
|
|
122
155
|
* - Required fields exist: summary, regions
|
|
123
|
-
* - Each region has required fields: start, end, type, confidence, description
|
|
156
|
+
* - Each region has required fields: start/start_line, end/end_line, type, confidence, description
|
|
124
157
|
* - Enum values are valid
|
|
158
|
+
* - Supports both old and new JSON formats
|
|
125
159
|
*
|
|
126
160
|
* @param jsonString - JSON string from LLM response
|
|
127
161
|
* @returns Parsed and validated DetectionResult
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsvmpDetector.d.ts","sourceRoot":"","sources":["../src/jsvmpDetector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAiC,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"jsvmpDetector.d.ts","sourceRoot":"","sources":["../src/jsvmpDetector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAiC,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,mBAAmB,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,EAAE,eAAe,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,aAAa,EAAE,mBAAmB,CAAC;IACnC,aAAa,EAAE,mBAAmB,CAAC;IACnC,cAAc,EAAE,mBAAmB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;CAC7C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACnC,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAsBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,MAAY,GACtB,OAAO,CAAC,aAAa,CAAC,CAuDxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,MAAY,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAiD9B;AAcD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,cAAc,EAAE,MAAM,EAAE,EACxB,iBAAiB,EAAE,MAAM,GACxB,SAAS,EAAE,CAgCb;AA4GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CA2GxE;AA0ED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,eAAe,CA8EjF;AAiBD;;;;;;;;GAQG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,SAAS,EAAE,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkB3D;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA+E/B"}
|
package/dist/llmConfig.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llmConfig.d.ts","sourceRoot":"","sources":["../src/llmConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAIpE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAgBA,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAM9E;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAoC/C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;
|
|
1
|
+
{"version":3,"file":"llmConfig.d.ts","sourceRoot":"","sources":["../src/llmConfig.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAIpE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,WAAW,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAgBA,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,WAAW,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAM9E;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAoC/C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAgGD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,aAAa,CAwBpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAyB5D"}
|
package/dist/server.js
CHANGED
|
@@ -78,53 +78,83 @@ function buildJSVMPSystemPrompt() {
|
|
|
78
78
|
return `You are a Senior JavaScript Reverse Engineer and De-obfuscation Expert. Your specialty is analyzing **JSVMP (JavaScript Virtual Machine Protection)**.
|
|
79
79
|
|
|
80
80
|
**Context: What is JSVMP?**
|
|
81
|
-
JSVMP is a protection technique where original JavaScript code is compiled into custom **bytecode** and executed by a custom **interpreter** (virtual machine) written in JavaScript.
|
|
81
|
+
JSVMP is a protection technique where original JavaScript code is compiled into custom **bytecode** and executed by a custom **interpreter** (virtual machine) written in JavaScript. A single JavaScript file may contain **multiple, independent JSVMP instances**.
|
|
82
82
|
|
|
83
|
-
Key components of JSVMP
|
|
84
|
-
1. **The
|
|
85
|
-
2. **The
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
Key components of each JSVMP instance include:
|
|
84
|
+
1. **The Bytecode Array:** A large array of integers representing the program logic for that specific VM.
|
|
85
|
+
2. **The Virtual Stack:** A central array used to store operands and results for that VM.
|
|
86
|
+
3. **The Dispatcher:** A control flow structure (e.g., a \`while\` loop with a \`switch\` or \`if-else\` chain) that reads an opcode and executes the corresponding logic for that VM.
|
|
87
|
+
4. **Key State Variables:** The "registers" of a specific VM, such as its **Instruction Pointer (IP/PC)** and **Stack Pointer (SP)**.
|
|
88
|
+
5. **Debugging Entry Point:** The single most critical line number within a specific dispatcher loop to set a breakpoint for observing that VM's state.
|
|
88
89
|
|
|
89
90
|
**Task:**
|
|
90
|
-
|
|
91
|
+
Your primary task is to analyze the provided JavaScript code snippet to identify **all independent JSVMP instances** and produce a comprehensive report for each one. You are NOT creating or analyzing any Intermediate Representation (IR). Your goal is to provide the necessary information for a subsequent tool to analyze each VM instance separately and create its IR and mappings.
|
|
92
|
+
|
|
93
|
+
Specifically, for **EACH** JSVMP instance you identify, you must:
|
|
94
|
+
1. Define its location (**region**) and dispatcher type.
|
|
95
|
+
2. Identify the specific **variables** that function as its core **Key State Variables** (Instruction Pointer, Stack Pointer, Virtual Stack, and Bytecode Array).
|
|
96
|
+
3. Pinpoint the exact source code **line number** that serves as its optimal **Debugging Entry Point**.
|
|
97
|
+
4. Summarize all findings in a single, structured JSON output.
|
|
91
98
|
|
|
92
99
|
**Input Data Format:**
|
|
93
100
|
The code is provided in a simplified format: \`LineNo SourceLoc Code\`.
|
|
94
101
|
* **Example:** \`10 L234:56 var x = stack[p++];\`
|
|
95
|
-
* **Instruction:** Focus on the **LineNo** (1st column) and **Code** (3rd column onwards).
|
|
96
|
-
|
|
97
|
-
**Detection Rules & Confidence Levels:**
|
|
98
|
-
Please assign confidence based on the following criteria:
|
|
99
|
-
|
|
100
|
-
* **Ultra High:**
|
|
101
|
-
* A combination of a **Main Loop** + **Dispatcher** + **Stack Operations** appears in the same block.
|
|
102
|
-
* *Example:* A \`while(true)\` loop containing a huge \`if-else\` chain where branches perform \`stack[p++]\` operations.
|
|
102
|
+
* **Instruction:** Focus on the **LineNo** (1st column) and **Code** (3rd column onwards).
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
* **
|
|
109
|
-
*
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
* **
|
|
113
|
-
|
|
104
|
+
**Detection Rules:**
|
|
105
|
+
* **Region Identification:** An individual JSVMP instance is often characterized by a self-contained block containing a **Main Loop** + **Dispatcher** + **Stack Operations**.
|
|
106
|
+
* **Instruction Pointer (IP) Identification:**
|
|
107
|
+
* It is used as the **index for the Bytecode Array of its VM instance**.
|
|
108
|
+
* It is **predictably incremented** in almost every loop iteration.
|
|
109
|
+
* In some branches (jumps), it is **overwritten** with a new value.
|
|
110
|
+
* **Stack Pointer (SP) Identification:**
|
|
111
|
+
* It is used as the **index for the Virtual Stack array of its VM instance**.
|
|
112
|
+
* Its value consistently **increments after a write** (push) and **decrements before a read** (pop).
|
|
113
|
+
* **Debugging Entry Point Identification:**
|
|
114
|
+
* This is the line **inside a specific dispatcher loop** but **before its \`switch\` or \`if-else\` chain begins**. It is typically located right after the \`opcode\` is read from the bytecode array.
|
|
114
115
|
|
|
115
116
|
**Output Format:**
|
|
116
117
|
Return **ONLY valid JSON**. No markdown wrapper, no conversational text.
|
|
117
118
|
|
|
118
119
|
**JSON Schema:**
|
|
119
120
|
{
|
|
120
|
-
"summary":
|
|
121
|
+
"summary": {
|
|
122
|
+
"overall_description": "\u5BF9\u5728\u6587\u4EF6\u4E2D\u53D1\u73B0\u7684JSVMP\u5B9E\u4F8B\u6570\u91CF\u548C\u7C7B\u578B\u7684\u7B80\u8981\u4E2D\u6587\u603B\u7ED3\u3002",
|
|
123
|
+
"debugging_recommendation": "\u4E3A\u4E0B\u4E00\u6B65\u5206\u6790\u63D0\u4F9B\u7684\u603B\u4F53\u4E2D\u6587\u5EFA\u8BAE\u3002\u4F8B\u5982\uFF1A'\u5DF2\u8BC6\u522B\u51FA N \u4E2A\u72EC\u7ACB\u7684JSVMP\u5B9E\u4F8B\u3002\u5EFA\u8BAE\u5BF9\u6BCF\u4E2A\u5B9E\u4F8B\u5206\u522B\u5728\u6307\u5B9A\u7684"\u8C03\u8BD5\u5165\u53E3\u70B9"\u8BBE\u7F6E\u6761\u4EF6\u65AD\u70B9\uFF0C\u5E76\u76D1\u63A7\u5176\u5404\u81EA\u7684\u7EC4\u4EF6\u53D8\u91CF\u3002'"
|
|
124
|
+
},
|
|
121
125
|
"regions": [
|
|
122
126
|
{
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
"type": "<If-Else Dispatcher | Switch Dispatcher | Instruction Array
|
|
127
|
+
"start_line": "<start_line_integer>",
|
|
128
|
+
"end_line": "<end_line_integer>",
|
|
129
|
+
"type": "<If-Else Dispatcher | Switch Dispatcher | Instruction Array>",
|
|
126
130
|
"confidence": "<ultra_high | high | medium | low>",
|
|
127
|
-
"description": "
|
|
131
|
+
"description": "\u5BF9\u8FD9\u4E2A\u7279\u5B9AJSVMP\u5B9E\u4F8B\u7684\u7B80\u8981\u4E2D\u6587\u63CF\u8FF0\u3002",
|
|
132
|
+
"vm_components": {
|
|
133
|
+
"instruction_pointer": {
|
|
134
|
+
"variable_name": "<identified_variable_name | null>",
|
|
135
|
+
"confidence": "<high | medium | low>",
|
|
136
|
+
"reasoning": "Why this variable is the IP for THIS VM instance. E.g., 'Used as index for bytecode array _0x123 within this region.'"
|
|
137
|
+
},
|
|
138
|
+
"stack_pointer": {
|
|
139
|
+
"variable_name": "<identified_variable_name | null>",
|
|
140
|
+
"confidence": "<high | medium | low>",
|
|
141
|
+
"reasoning": "Why this variable is the SP for THIS VM instance. E.g., 'Used as index for stack array _0x456.'"
|
|
142
|
+
},
|
|
143
|
+
"virtual_stack": {
|
|
144
|
+
"variable_name": "<identified_array_name | null>",
|
|
145
|
+
"confidence": "<high | medium | low>",
|
|
146
|
+
"reasoning": "Why this array is the stack for THIS VM instance. E.g., 'Frequently accessed using its stack_pointer _0x789.'"
|
|
147
|
+
},
|
|
148
|
+
"bytecode_array": {
|
|
149
|
+
"variable_name": "<identified_array_name | null>",
|
|
150
|
+
"confidence": "<high | medium | low>",
|
|
151
|
+
"reasoning": "Why this array is the bytecode for THIS VM instance. E.g., 'A large, static array indexed by its instruction_pointer _0x123.'"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"debugging_entry_point": {
|
|
155
|
+
"line_number": "<line_number_integer>",
|
|
156
|
+
"description": "The optimal breakpoint line for THIS VM instance. E.g., 'This line is after the opcode is fetched and before this region's switch statement.'"
|
|
157
|
+
}
|
|
128
158
|
}
|
|
129
159
|
]
|
|
130
160
|
}`;
|
|
@@ -309,8 +339,7 @@ function createBatches(formattedLines, maxTokensPerBatch) {
|
|
|
309
339
|
var VALID_DETECTION_TYPES = [
|
|
310
340
|
"If-Else Dispatcher",
|
|
311
341
|
"Switch Dispatcher",
|
|
312
|
-
"Instruction Array"
|
|
313
|
-
"Stack Operation"
|
|
342
|
+
"Instruction Array"
|
|
314
343
|
];
|
|
315
344
|
var VALID_CONFIDENCE_LEVELS = [
|
|
316
345
|
"ultra_high",
|
|
@@ -324,6 +353,57 @@ function isValidDetectionType(value) {
|
|
|
324
353
|
function isValidConfidenceLevel(value) {
|
|
325
354
|
return VALID_CONFIDENCE_LEVELS.includes(value);
|
|
326
355
|
}
|
|
356
|
+
function parseVMComponentVariable(obj, fieldName) {
|
|
357
|
+
const component = obj[fieldName];
|
|
358
|
+
if (!component || typeof component !== "object") {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
const variableName = component.variable_name;
|
|
362
|
+
const confidence = component.confidence;
|
|
363
|
+
const reasoning = component.reasoning;
|
|
364
|
+
if (typeof confidence !== "string" || !isValidConfidenceLevel(confidence)) {
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
variable_name: typeof variableName === "string" ? variableName : null,
|
|
369
|
+
confidence,
|
|
370
|
+
reasoning: typeof reasoning === "string" ? reasoning : ""
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function parseVMComponents(obj) {
|
|
374
|
+
const vmComponents = obj.vm_components;
|
|
375
|
+
if (!vmComponents || typeof vmComponents !== "object") {
|
|
376
|
+
return void 0;
|
|
377
|
+
}
|
|
378
|
+
const ip = parseVMComponentVariable(vmComponents, "instruction_pointer");
|
|
379
|
+
const sp = parseVMComponentVariable(vmComponents, "stack_pointer");
|
|
380
|
+
const stack = parseVMComponentVariable(vmComponents, "virtual_stack");
|
|
381
|
+
const bytecode = parseVMComponentVariable(vmComponents, "bytecode_array");
|
|
382
|
+
if (!ip && !sp && !stack && !bytecode) {
|
|
383
|
+
return void 0;
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
instruction_pointer: ip ?? { variable_name: null, confidence: "low", reasoning: "" },
|
|
387
|
+
stack_pointer: sp ?? { variable_name: null, confidence: "low", reasoning: "" },
|
|
388
|
+
virtual_stack: stack ?? { variable_name: null, confidence: "low", reasoning: "" },
|
|
389
|
+
bytecode_array: bytecode ?? { variable_name: null, confidence: "low", reasoning: "" }
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
function parseDebuggingEntryPoint(obj) {
|
|
393
|
+
const entryPoint = obj.debugging_entry_point;
|
|
394
|
+
if (!entryPoint || typeof entryPoint !== "object") {
|
|
395
|
+
return void 0;
|
|
396
|
+
}
|
|
397
|
+
const lineNumber = entryPoint.line_number;
|
|
398
|
+
const description = entryPoint.description;
|
|
399
|
+
if (typeof lineNumber !== "number") {
|
|
400
|
+
return void 0;
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
line_number: lineNumber,
|
|
404
|
+
description: typeof description === "string" ? description : ""
|
|
405
|
+
};
|
|
406
|
+
}
|
|
327
407
|
function parseDetectionResult(jsonString) {
|
|
328
408
|
let parsed;
|
|
329
409
|
try {
|
|
@@ -335,7 +415,19 @@ function parseDetectionResult(jsonString) {
|
|
|
335
415
|
throw new Error("LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0C\u671F\u671B\u5BF9\u8C61\u7C7B\u578B");
|
|
336
416
|
}
|
|
337
417
|
const obj = parsed;
|
|
338
|
-
|
|
418
|
+
let summary;
|
|
419
|
+
if (typeof obj.summary === "string") {
|
|
420
|
+
summary = obj.summary;
|
|
421
|
+
} else if (typeof obj.summary === "object" && obj.summary !== null) {
|
|
422
|
+
const summaryObj = obj.summary;
|
|
423
|
+
if (typeof summaryObj.overall_description !== "string" || typeof summaryObj.debugging_recommendation !== "string") {
|
|
424
|
+
throw new Error("LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Csummary \u5BF9\u8C61\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5");
|
|
425
|
+
}
|
|
426
|
+
summary = {
|
|
427
|
+
overall_description: summaryObj.overall_description,
|
|
428
|
+
debugging_recommendation: summaryObj.debugging_recommendation
|
|
429
|
+
};
|
|
430
|
+
} else {
|
|
339
431
|
throw new Error("LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0C\u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: summary");
|
|
340
432
|
}
|
|
341
433
|
if (!Array.isArray(obj.regions)) {
|
|
@@ -347,11 +439,13 @@ function parseDetectionResult(jsonString) {
|
|
|
347
439
|
if (typeof region !== "object" || region === null) {
|
|
348
440
|
throw new Error(`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}] \u4E0D\u662F\u5BF9\u8C61`);
|
|
349
441
|
}
|
|
350
|
-
|
|
351
|
-
|
|
442
|
+
const startLine = region.start_line ?? region.start;
|
|
443
|
+
const endLine = region.end_line ?? region.end;
|
|
444
|
+
if (typeof startLine !== "number") {
|
|
445
|
+
throw new Error(`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}] \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: start_line \u6216 start`);
|
|
352
446
|
}
|
|
353
|
-
if (typeof
|
|
354
|
-
throw new Error(`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}] \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: end`);
|
|
447
|
+
if (typeof endLine !== "number") {
|
|
448
|
+
throw new Error(`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}] \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: end_line \u6216 end`);
|
|
355
449
|
}
|
|
356
450
|
if (typeof region.type !== "string") {
|
|
357
451
|
throw new Error(`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}] \u7F3A\u5C11\u5FC5\u9700\u5B57\u6BB5: type`);
|
|
@@ -372,16 +466,20 @@ function parseDetectionResult(jsonString) {
|
|
|
372
466
|
`LLM \u54CD\u5E94\u683C\u5F0F\u65E0\u6548\uFF0Cregions[${i}].confidence \u503C\u65E0\u6548: "${region.confidence}". \u6709\u6548\u503C: ${VALID_CONFIDENCE_LEVELS.join(", ")}`
|
|
373
467
|
);
|
|
374
468
|
}
|
|
469
|
+
const vmComponents = parseVMComponents(region);
|
|
470
|
+
const debuggingEntryPoint = parseDebuggingEntryPoint(region);
|
|
375
471
|
validatedRegions.push({
|
|
376
|
-
start:
|
|
377
|
-
end:
|
|
472
|
+
start: startLine,
|
|
473
|
+
end: endLine,
|
|
378
474
|
type: region.type,
|
|
379
475
|
confidence: region.confidence,
|
|
380
|
-
description: region.description
|
|
476
|
+
description: region.description,
|
|
477
|
+
...vmComponents && { vm_components: vmComponents },
|
|
478
|
+
...debuggingEntryPoint && { debugging_entry_point: debuggingEntryPoint }
|
|
381
479
|
});
|
|
382
480
|
}
|
|
383
481
|
return {
|
|
384
|
-
summary
|
|
482
|
+
summary,
|
|
385
483
|
regions: validatedRegions
|
|
386
484
|
};
|
|
387
485
|
}
|
|
@@ -390,13 +488,45 @@ function formatDetectionResultOutput(result, filePath, totalLines, batchCount) {
|
|
|
390
488
|
lines.push("=== JSVMP Dispatcher Detection Result ===");
|
|
391
489
|
lines.push(`File: ${filePath} (${totalLines} lines, ${batchCount} batch${batchCount > 1 ? "es" : ""})`);
|
|
392
490
|
lines.push("");
|
|
393
|
-
|
|
491
|
+
if (typeof result.summary === "string") {
|
|
492
|
+
lines.push(`Summary: ${result.summary}`);
|
|
493
|
+
} else {
|
|
494
|
+
lines.push(`Summary: ${result.summary.overall_description}`);
|
|
495
|
+
lines.push(`Recommendation: ${result.summary.debugging_recommendation}`);
|
|
496
|
+
}
|
|
394
497
|
lines.push("");
|
|
395
498
|
if (result.regions.length > 0) {
|
|
396
|
-
lines.push(
|
|
397
|
-
|
|
499
|
+
lines.push(`Detected Regions (${result.regions.length} JSVMP instance${result.regions.length > 1 ? "s" : ""}):`);
|
|
500
|
+
lines.push("");
|
|
501
|
+
for (let i = 0; i < result.regions.length; i++) {
|
|
502
|
+
const region = result.regions[i];
|
|
503
|
+
lines.push(`--- Instance ${i + 1} ---`);
|
|
398
504
|
lines.push(`[${region.confidence}] Lines ${region.start}-${region.end}: ${region.type}`);
|
|
399
505
|
lines.push(` ${region.description}`);
|
|
506
|
+
if (region.vm_components) {
|
|
507
|
+
lines.push(" VM Components:");
|
|
508
|
+
const { instruction_pointer, stack_pointer, virtual_stack, bytecode_array } = region.vm_components;
|
|
509
|
+
if (instruction_pointer.variable_name) {
|
|
510
|
+
lines.push(` - Instruction Pointer: ${instruction_pointer.variable_name} [${instruction_pointer.confidence}]`);
|
|
511
|
+
lines.push(` ${instruction_pointer.reasoning}`);
|
|
512
|
+
}
|
|
513
|
+
if (stack_pointer.variable_name) {
|
|
514
|
+
lines.push(` - Stack Pointer: ${stack_pointer.variable_name} [${stack_pointer.confidence}]`);
|
|
515
|
+
lines.push(` ${stack_pointer.reasoning}`);
|
|
516
|
+
}
|
|
517
|
+
if (virtual_stack.variable_name) {
|
|
518
|
+
lines.push(` - Virtual Stack: ${virtual_stack.variable_name} [${virtual_stack.confidence}]`);
|
|
519
|
+
lines.push(` ${virtual_stack.reasoning}`);
|
|
520
|
+
}
|
|
521
|
+
if (bytecode_array.variable_name) {
|
|
522
|
+
lines.push(` - Bytecode Array: ${bytecode_array.variable_name} [${bytecode_array.confidence}]`);
|
|
523
|
+
lines.push(` ${bytecode_array.reasoning}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (region.debugging_entry_point) {
|
|
527
|
+
lines.push(` Debugging Entry Point: Line ${region.debugging_entry_point.line_number}`);
|
|
528
|
+
lines.push(` ${region.debugging_entry_point.description}`);
|
|
529
|
+
}
|
|
400
530
|
lines.push("");
|
|
401
531
|
}
|
|
402
532
|
} else {
|
|
@@ -412,8 +542,20 @@ function mergeDetectionResults(results) {
|
|
|
412
542
|
const sortedRegions = [...results[0].regions].sort((a, b) => a.start - b.start);
|
|
413
543
|
return { summary: results[0].summary, regions: sortedRegions };
|
|
414
544
|
}
|
|
415
|
-
const
|
|
416
|
-
|
|
545
|
+
const summaryParts = [];
|
|
546
|
+
for (let i = 0; i < results.length; i++) {
|
|
547
|
+
const summary = results[i].summary;
|
|
548
|
+
if (typeof summary === "string") {
|
|
549
|
+
summaryParts.push(`[Batch ${i + 1}] ${summary}`);
|
|
550
|
+
} else {
|
|
551
|
+
summaryParts.push(`[Batch ${i + 1}] ${summary.overall_description}`);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
const lastSummary = results[results.length - 1].summary;
|
|
555
|
+
const combinedSummary = {
|
|
556
|
+
overall_description: summaryParts.join("\n"),
|
|
557
|
+
debugging_recommendation: typeof lastSummary === "string" ? "\u8BF7\u53C2\u8003\u5404\u6279\u6B21\u7684\u5206\u6790\u7ED3\u679C\u8FDB\u884C\u8C03\u8BD5\u3002" : lastSummary.debugging_recommendation
|
|
558
|
+
};
|
|
417
559
|
const allRegions = [];
|
|
418
560
|
for (const result of results) {
|
|
419
561
|
allRegions.push(...result.regions);
|
|
@@ -539,15 +681,16 @@ var findJsvmpDispatcherTool = defineTool({
|
|
|
539
681
|
name: "find_jsvmp_dispatcher",
|
|
540
682
|
description: `Detect JSVMP (JavaScript Virtual Machine Protection) patterns in code using LLM analysis.
|
|
541
683
|
|
|
542
|
-
JSVMP is a code protection technique that converts JavaScript to bytecode executed by a virtual machine.
|
|
543
|
-
- If-Else Dispatchers: Nested if-else chains for instruction dispatch
|
|
544
|
-
- Switch Dispatchers: Large switch statements (>20 cases) for opcode handling
|
|
545
|
-
- Instruction Arrays: Arrays storing bytecode instructions
|
|
546
|
-
- Stack Operations: Virtual stack push/pop patterns
|
|
684
|
+
JSVMP is a code protection technique that converts JavaScript to bytecode executed by a virtual machine. A single file may contain multiple independent JSVMP instances.
|
|
547
685
|
|
|
548
|
-
|
|
686
|
+
This tool identifies for each JSVMP instance:
|
|
687
|
+
- Region location and dispatcher type (If-Else Dispatcher, Switch Dispatcher, Instruction Array)
|
|
688
|
+
- VM Components: Instruction Pointer (IP), Stack Pointer (SP), Virtual Stack, Bytecode Array
|
|
689
|
+
- Debugging Entry Point: The optimal line number to set breakpoints
|
|
549
690
|
|
|
550
|
-
|
|
691
|
+
Detection confidence levels: ultra_high, high, medium, low
|
|
692
|
+
|
|
693
|
+
Automatically splits large files into batches based on token limits and merges results.
|
|
551
694
|
|
|
552
695
|
Requires OPENAI_API_KEY environment variable. Optional: OPENAI_BASE_URL, OPENAI_MODEL.`,
|
|
553
696
|
schema: FindJsvmpDispatcherInputSchema,
|