@jshookmcp/jshook 0.1.6 → 0.1.8
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/LICENSE +661 -661
- package/README.md +145 -100
- package/README.zh.md +81 -36
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +3 -1
- package/dist/index.js +0 -0
- package/dist/modules/analyzer/QualityAnalyzer.js +1 -1
- package/dist/modules/browser/BrowserDiscovery.js +2 -2
- package/dist/modules/browser/BrowserModeManager.js +3 -3
- package/dist/modules/captcha/AICaptchaDetector.d.ts +12 -16
- package/dist/modules/captcha/AICaptchaDetector.js +229 -209
- package/dist/modules/captcha/CaptchaDetector.constants.d.ts +2 -0
- package/dist/modules/captcha/CaptchaDetector.constants.js +116 -25
- package/dist/modules/captcha/CaptchaDetector.d.ts +2 -11
- package/dist/modules/captcha/CaptchaDetector.js +102 -51
- package/dist/modules/captcha/types.d.ts +46 -0
- package/dist/modules/captcha/types.js +52 -0
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts +15 -20
- package/dist/modules/deobfuscator/AdvancedDeobfuscator.js +66 -234
- package/dist/modules/deobfuscator/Deobfuscator.d.ts +3 -10
- package/dist/modules/deobfuscator/Deobfuscator.js +125 -404
- package/dist/modules/deobfuscator/webcrack.d.ts +13 -0
- package/dist/modules/deobfuscator/webcrack.js +164 -0
- package/dist/modules/detector/ObfuscationDetector.d.ts +6 -0
- package/dist/modules/detector/ObfuscationDetector.js +53 -2
- package/dist/modules/hook/AIHookGenerator.js +1 -1
- package/dist/modules/process/MacProcessManager.js +25 -25
- package/dist/modules/process/memory/availability.js +49 -49
- package/dist/modules/process/memory/injector.js +185 -185
- package/dist/modules/process/memory/reader.js +50 -50
- package/dist/modules/process/memory/scanner.js +165 -165
- package/dist/modules/process/memory/writer.js +55 -55
- package/dist/native/scripts/linux/enum-windows.sh +12 -12
- package/dist/native/scripts/macos/enum-windows.applescript +22 -22
- package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
- package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
- package/dist/server/domains/analysis/definitions.js +223 -2
- package/dist/server/domains/analysis/handlers.impl.d.ts +2 -3
- package/dist/server/domains/analysis/handlers.impl.js +60 -15
- package/dist/server/domains/analysis/manifest.js +2 -5
- package/dist/server/domains/browser/definitions.tools.behavior.js +36 -24
- package/dist/server/domains/browser/definitions.tools.page-core.js +53 -53
- package/dist/server/domains/browser/definitions.tools.runtime.js +40 -40
- package/dist/server/domains/browser/definitions.tools.security.js +80 -77
- package/dist/server/domains/browser/handlers/camoufox-flow.js +0 -1
- package/dist/server/domains/browser/handlers/captcha-solver.d.ts +1 -1
- package/dist/server/domains/browser/handlers/captcha-solver.js +121 -54
- package/dist/server/domains/browser/handlers/page-navigation.js +0 -2
- package/dist/server/domains/browser/handlers.impl.d.ts +1 -1
- package/dist/server/domains/browser/handlers.impl.js +3 -3
- package/dist/server/domains/browser/manifest.js +1 -1
- package/dist/server/domains/shared/modules.d.ts +1 -0
- package/dist/server/domains/transform/handlers.impl.transform-base.js +102 -102
- package/dist/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
- package/dist/types/deobfuscator.d.ts +43 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/config.js +19 -10
- package/package.json +30 -44
- package/scripts/postinstall.cjs +37 -0
- package/src/native/scripts/linux/enum-windows.sh +12 -12
- package/src/native/scripts/macos/enum-windows.applescript +22 -22
- package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
- package/src/native/scripts/windows/enum-windows.ps1 +44 -44
- package/src/native/scripts/windows/inject-dll.ps1 +21 -21
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
param(
|
|
2
|
-
[int]$TargetPid
|
|
3
|
-
)
|
|
4
|
-
|
|
5
|
-
Add-Type @"
|
|
6
|
-
using System;
|
|
7
|
-
using System.Runtime.InteropServices;
|
|
8
|
-
public class Win32 {
|
|
9
|
-
[DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string title);
|
|
10
|
-
[DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int pid);
|
|
11
|
-
[DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);
|
|
12
|
-
[DllImport("user32.dll")] public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder className, int maxCount);
|
|
13
|
-
[DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
|
|
14
|
-
[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
|
|
15
|
-
}
|
|
16
|
-
"@
|
|
17
|
-
|
|
18
|
-
$windows = @()
|
|
19
|
-
$hwnd = [IntPtr]::Zero
|
|
20
|
-
while ($true) {
|
|
21
|
-
$hwnd = [Win32]::FindWindowEx([IntPtr]::Zero, $hwnd, $null, $null)
|
|
22
|
-
if ($hwnd -eq [IntPtr]::Zero) { break }
|
|
23
|
-
$windowPid = 0
|
|
24
|
-
[Win32]::GetWindowThreadProcessId($hwnd, [ref]$windowPid) | Out-Null
|
|
25
|
-
if ($windowPid -eq $TargetPid) {
|
|
26
|
-
$title = New-Object System.Text.StringBuilder 256
|
|
27
|
-
$className = New-Object System.Text.StringBuilder 256
|
|
28
|
-
[Win32]::GetWindowText($hwnd, $title, 256) | Out-Null
|
|
29
|
-
[Win32]::GetClassName($hwnd, $className, 256) | Out-Null
|
|
30
|
-
$rect = New-Object Win32+RECT
|
|
31
|
-
[Win32]::GetWindowRect($hwnd, [ref]$rect) | Out-Null
|
|
32
|
-
$windows += @{
|
|
33
|
-
Handle = $hwnd.ToString()
|
|
34
|
-
Title = $title.ToString()
|
|
35
|
-
ClassName = $className.ToString()
|
|
36
|
-
ProcessId = $windowPid
|
|
37
|
-
Left = $rect.Left
|
|
38
|
-
Top = $rect.Top
|
|
39
|
-
Right = $rect.Right
|
|
40
|
-
Bottom = $rect.Bottom
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
$windows | ConvertTo-Json -Compress
|
|
1
|
+
param(
|
|
2
|
+
[int]$TargetPid
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
Add-Type @"
|
|
6
|
+
using System;
|
|
7
|
+
using System.Runtime.InteropServices;
|
|
8
|
+
public class Win32 {
|
|
9
|
+
[DllImport("user32.dll")] public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childAfter, string className, string title);
|
|
10
|
+
[DllImport("user32.dll")] public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int pid);
|
|
11
|
+
[DllImport("user32.dll")] public static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder text, int count);
|
|
12
|
+
[DllImport("user32.dll")] public static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder className, int maxCount);
|
|
13
|
+
[DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
|
|
14
|
+
[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left, Top, Right, Bottom; }
|
|
15
|
+
}
|
|
16
|
+
"@
|
|
17
|
+
|
|
18
|
+
$windows = @()
|
|
19
|
+
$hwnd = [IntPtr]::Zero
|
|
20
|
+
while ($true) {
|
|
21
|
+
$hwnd = [Win32]::FindWindowEx([IntPtr]::Zero, $hwnd, $null, $null)
|
|
22
|
+
if ($hwnd -eq [IntPtr]::Zero) { break }
|
|
23
|
+
$windowPid = 0
|
|
24
|
+
[Win32]::GetWindowThreadProcessId($hwnd, [ref]$windowPid) | Out-Null
|
|
25
|
+
if ($windowPid -eq $TargetPid) {
|
|
26
|
+
$title = New-Object System.Text.StringBuilder 256
|
|
27
|
+
$className = New-Object System.Text.StringBuilder 256
|
|
28
|
+
[Win32]::GetWindowText($hwnd, $title, 256) | Out-Null
|
|
29
|
+
[Win32]::GetClassName($hwnd, $className, 256) | Out-Null
|
|
30
|
+
$rect = New-Object Win32+RECT
|
|
31
|
+
[Win32]::GetWindowRect($hwnd, [ref]$rect) | Out-Null
|
|
32
|
+
$windows += @{
|
|
33
|
+
Handle = $hwnd.ToString()
|
|
34
|
+
Title = $title.ToString()
|
|
35
|
+
ClassName = $className.ToString()
|
|
36
|
+
ProcessId = $windowPid
|
|
37
|
+
Left = $rect.Left
|
|
38
|
+
Top = $rect.Top
|
|
39
|
+
Right = $rect.Right
|
|
40
|
+
Bottom = $rect.Bottom
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
$windows | ConvertTo-Json -Compress
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
param(
|
|
2
|
-
[int]$TargetPid,
|
|
3
|
-
[string]$DllPath
|
|
4
|
-
)
|
|
5
|
-
|
|
6
|
-
Add-Type @"
|
|
7
|
-
using System;
|
|
8
|
-
using System.Runtime.InteropServices;
|
|
9
|
-
public class Injector {
|
|
10
|
-
[DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
11
|
-
[DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int alloc, int protect);
|
|
12
|
-
[DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
|
|
13
|
-
[DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stack, IntPtr start, IntPtr param, int flags, out int threadId);
|
|
14
|
-
[DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name);
|
|
15
|
-
[DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string name);
|
|
16
|
-
[DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr handle);
|
|
17
|
-
}
|
|
18
|
-
"@
|
|
19
|
-
|
|
20
|
-
# Injection requires elevated privileges and is disabled for safety
|
|
21
|
-
Write-Output "DLL injection is disabled for safety in this implementation. PID: $TargetPid, DLL: $DllPath"
|
|
1
|
+
param(
|
|
2
|
+
[int]$TargetPid,
|
|
3
|
+
[string]$DllPath
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
Add-Type @"
|
|
7
|
+
using System;
|
|
8
|
+
using System.Runtime.InteropServices;
|
|
9
|
+
public class Injector {
|
|
10
|
+
[DllImport("kernel32.dll")] public static extern IntPtr OpenProcess(int access, bool inherit, int pid);
|
|
11
|
+
[DllImport("kernel32.dll")] public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr addr, int size, int alloc, int protect);
|
|
12
|
+
[DllImport("kernel32.dll")] public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr addr, byte[] buffer, int size, out int written);
|
|
13
|
+
[DllImport("kernel32.dll")] public static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr attr, int stack, IntPtr start, IntPtr param, int flags, out int threadId);
|
|
14
|
+
[DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string name);
|
|
15
|
+
[DllImport("kernel32.dll")] public static extern IntPtr GetProcAddress(IntPtr hModule, string name);
|
|
16
|
+
[DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr handle);
|
|
17
|
+
}
|
|
18
|
+
"@
|
|
19
|
+
|
|
20
|
+
# Injection requires elevated privileges and is disabled for safety
|
|
21
|
+
Write-Output "DLL injection is disabled for safety in this implementation. PID: $TargetPid, DLL: $DllPath"
|
|
@@ -138,7 +138,7 @@ export const coreTools = [
|
|
|
138
138
|
},
|
|
139
139
|
{
|
|
140
140
|
name: 'deobfuscate',
|
|
141
|
-
description: 'Run
|
|
141
|
+
description: 'Run webcrack-powered JavaScript deobfuscation with bundle unpacking support.',
|
|
142
142
|
inputSchema: {
|
|
143
143
|
type: 'object',
|
|
144
144
|
properties: {
|
|
@@ -157,6 +157,75 @@ export const coreTools = [
|
|
|
157
157
|
description: 'Enable aggressive deobfuscation strategy',
|
|
158
158
|
default: false,
|
|
159
159
|
},
|
|
160
|
+
unpack: {
|
|
161
|
+
type: 'boolean',
|
|
162
|
+
description: 'Use webcrack to unpack webpack/browserify bundles when possible',
|
|
163
|
+
default: true,
|
|
164
|
+
},
|
|
165
|
+
unminify: {
|
|
166
|
+
type: 'boolean',
|
|
167
|
+
description: 'Use webcrack to reformat and unminify code before post-processing',
|
|
168
|
+
default: true,
|
|
169
|
+
},
|
|
170
|
+
jsx: {
|
|
171
|
+
type: 'boolean',
|
|
172
|
+
description: 'Ask webcrack to decompile React.createElement trees back to JSX when supported',
|
|
173
|
+
default: true,
|
|
174
|
+
},
|
|
175
|
+
mangle: {
|
|
176
|
+
type: 'boolean',
|
|
177
|
+
description: 'Rename obfuscated identifiers using webcrack mangle pass',
|
|
178
|
+
default: false,
|
|
179
|
+
},
|
|
180
|
+
outputDir: {
|
|
181
|
+
type: 'string',
|
|
182
|
+
description: 'Optional directory where webcrack should save the deobfuscated code and extracted bundle',
|
|
183
|
+
},
|
|
184
|
+
forceOutput: {
|
|
185
|
+
type: 'boolean',
|
|
186
|
+
description: 'Remove outputDir before saving webcrack artifacts',
|
|
187
|
+
default: false,
|
|
188
|
+
},
|
|
189
|
+
includeModuleCode: {
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
description: 'Include unpacked module source in bundle output when returning bundle details',
|
|
192
|
+
default: false,
|
|
193
|
+
},
|
|
194
|
+
maxBundleModules: {
|
|
195
|
+
type: 'number',
|
|
196
|
+
description: 'Maximum number of bundle modules to return in the response',
|
|
197
|
+
default: 100,
|
|
198
|
+
},
|
|
199
|
+
mappings: {
|
|
200
|
+
type: 'array',
|
|
201
|
+
description: 'Optional remapping rules applied to unpacked bundle module paths. Each rule can match against module code or current path.',
|
|
202
|
+
items: {
|
|
203
|
+
type: 'object',
|
|
204
|
+
properties: {
|
|
205
|
+
path: {
|
|
206
|
+
type: 'string',
|
|
207
|
+
description: 'New module path to assign when the rule matches',
|
|
208
|
+
},
|
|
209
|
+
pattern: {
|
|
210
|
+
type: 'string',
|
|
211
|
+
description: 'Text or regex used to match module code/path',
|
|
212
|
+
},
|
|
213
|
+
matchType: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
enum: ['includes', 'regex', 'exact'],
|
|
216
|
+
description: 'How to interpret pattern',
|
|
217
|
+
default: 'includes',
|
|
218
|
+
},
|
|
219
|
+
target: {
|
|
220
|
+
type: 'string',
|
|
221
|
+
enum: ['code', 'path'],
|
|
222
|
+
description: 'Whether to match against module source code or the current module path',
|
|
223
|
+
default: 'code',
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
required: ['path', 'pattern'],
|
|
227
|
+
},
|
|
228
|
+
},
|
|
160
229
|
},
|
|
161
230
|
required: ['code'],
|
|
162
231
|
},
|
|
@@ -258,7 +327,7 @@ export const coreTools = [
|
|
|
258
327
|
},
|
|
259
328
|
{
|
|
260
329
|
name: 'advanced_deobfuscate',
|
|
261
|
-
description: 'Run advanced deobfuscation with
|
|
330
|
+
description: 'Run advanced deobfuscation with webcrack backend (deprecated legacy flags ignored).',
|
|
262
331
|
inputSchema: {
|
|
263
332
|
type: 'object',
|
|
264
333
|
properties: {
|
|
@@ -286,6 +355,158 @@ export const coreTools = [
|
|
|
286
355
|
description: 'Operation timeout in milliseconds',
|
|
287
356
|
default: 60000,
|
|
288
357
|
},
|
|
358
|
+
unpack: {
|
|
359
|
+
type: 'boolean',
|
|
360
|
+
description: 'Use webcrack to unpack webpack/browserify bundles before advanced cleanup',
|
|
361
|
+
default: true,
|
|
362
|
+
},
|
|
363
|
+
unminify: {
|
|
364
|
+
type: 'boolean',
|
|
365
|
+
description: 'Use webcrack unminify pass before VM and AST-oriented cleanup',
|
|
366
|
+
default: true,
|
|
367
|
+
},
|
|
368
|
+
jsx: {
|
|
369
|
+
type: 'boolean',
|
|
370
|
+
description: 'Allow webcrack to decompile React.createElement back to JSX when supported',
|
|
371
|
+
default: true,
|
|
372
|
+
},
|
|
373
|
+
mangle: {
|
|
374
|
+
type: 'boolean',
|
|
375
|
+
description: 'Rename obfuscated identifiers during the webcrack phase',
|
|
376
|
+
default: false,
|
|
377
|
+
},
|
|
378
|
+
outputDir: {
|
|
379
|
+
type: 'string',
|
|
380
|
+
description: 'Optional directory where webcrack should save the deobfuscated code and extracted bundle',
|
|
381
|
+
},
|
|
382
|
+
forceOutput: {
|
|
383
|
+
type: 'boolean',
|
|
384
|
+
description: 'Remove outputDir before saving webcrack artifacts',
|
|
385
|
+
default: false,
|
|
386
|
+
},
|
|
387
|
+
includeModuleCode: {
|
|
388
|
+
type: 'boolean',
|
|
389
|
+
description: 'Include unpacked module source in bundle output when returning bundle details',
|
|
390
|
+
default: false,
|
|
391
|
+
},
|
|
392
|
+
maxBundleModules: {
|
|
393
|
+
type: 'number',
|
|
394
|
+
description: 'Maximum number of bundle modules to return in the response',
|
|
395
|
+
default: 100,
|
|
396
|
+
},
|
|
397
|
+
mappings: {
|
|
398
|
+
type: 'array',
|
|
399
|
+
description: 'Optional remapping rules applied to unpacked bundle module paths. Each rule can match against module code or current path.',
|
|
400
|
+
items: {
|
|
401
|
+
type: 'object',
|
|
402
|
+
properties: {
|
|
403
|
+
path: {
|
|
404
|
+
type: 'string',
|
|
405
|
+
description: 'New module path to assign when the rule matches',
|
|
406
|
+
},
|
|
407
|
+
pattern: {
|
|
408
|
+
type: 'string',
|
|
409
|
+
description: 'Text or regex used to match module code/path',
|
|
410
|
+
},
|
|
411
|
+
matchType: {
|
|
412
|
+
type: 'string',
|
|
413
|
+
enum: ['includes', 'regex', 'exact'],
|
|
414
|
+
description: 'How to interpret pattern',
|
|
415
|
+
default: 'includes',
|
|
416
|
+
},
|
|
417
|
+
target: {
|
|
418
|
+
type: 'string',
|
|
419
|
+
enum: ['code', 'path'],
|
|
420
|
+
description: 'Whether to match against module source code or the current module path',
|
|
421
|
+
default: 'code',
|
|
422
|
+
},
|
|
423
|
+
},
|
|
424
|
+
required: ['path', 'pattern'],
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
required: ['code'],
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
name: 'webcrack_unpack',
|
|
433
|
+
description: 'Run webcrack bundle unpacking directly and return extracted module graph details.',
|
|
434
|
+
inputSchema: {
|
|
435
|
+
type: 'object',
|
|
436
|
+
properties: {
|
|
437
|
+
code: {
|
|
438
|
+
type: 'string',
|
|
439
|
+
description: 'Bundled or obfuscated JavaScript source',
|
|
440
|
+
},
|
|
441
|
+
unpack: {
|
|
442
|
+
type: 'boolean',
|
|
443
|
+
description: 'Extract modules from the bundle when supported',
|
|
444
|
+
default: true,
|
|
445
|
+
},
|
|
446
|
+
unminify: {
|
|
447
|
+
type: 'boolean',
|
|
448
|
+
description: 'Unminify the code before extracting bundle modules',
|
|
449
|
+
default: true,
|
|
450
|
+
},
|
|
451
|
+
jsx: {
|
|
452
|
+
type: 'boolean',
|
|
453
|
+
description: 'Decompile React.createElement trees back to JSX when supported',
|
|
454
|
+
default: true,
|
|
455
|
+
},
|
|
456
|
+
mangle: {
|
|
457
|
+
type: 'boolean',
|
|
458
|
+
description: 'Rename obfuscated identifiers during the webcrack pass',
|
|
459
|
+
default: false,
|
|
460
|
+
},
|
|
461
|
+
outputDir: {
|
|
462
|
+
type: 'string',
|
|
463
|
+
description: 'Optional directory where webcrack should save the extracted bundle files',
|
|
464
|
+
},
|
|
465
|
+
forceOutput: {
|
|
466
|
+
type: 'boolean',
|
|
467
|
+
description: 'Remove outputDir before saving webcrack artifacts',
|
|
468
|
+
default: false,
|
|
469
|
+
},
|
|
470
|
+
includeModuleCode: {
|
|
471
|
+
type: 'boolean',
|
|
472
|
+
description: 'Include unpacked module source in bundle output',
|
|
473
|
+
default: false,
|
|
474
|
+
},
|
|
475
|
+
maxBundleModules: {
|
|
476
|
+
type: 'number',
|
|
477
|
+
description: 'Maximum number of bundle modules to return in the response',
|
|
478
|
+
default: 100,
|
|
479
|
+
},
|
|
480
|
+
mappings: {
|
|
481
|
+
type: 'array',
|
|
482
|
+
description: 'Optional remapping rules applied to unpacked bundle module paths. Each rule can match against module code or current path.',
|
|
483
|
+
items: {
|
|
484
|
+
type: 'object',
|
|
485
|
+
properties: {
|
|
486
|
+
path: {
|
|
487
|
+
type: 'string',
|
|
488
|
+
description: 'New module path to assign when the rule matches',
|
|
489
|
+
},
|
|
490
|
+
pattern: {
|
|
491
|
+
type: 'string',
|
|
492
|
+
description: 'Text or regex used to match module code/path',
|
|
493
|
+
},
|
|
494
|
+
matchType: {
|
|
495
|
+
type: 'string',
|
|
496
|
+
enum: ['includes', 'regex', 'exact'],
|
|
497
|
+
description: 'How to interpret pattern',
|
|
498
|
+
default: 'includes',
|
|
499
|
+
},
|
|
500
|
+
target: {
|
|
501
|
+
type: 'string',
|
|
502
|
+
enum: ['code', 'path'],
|
|
503
|
+
description: 'Whether to match against module source code or the current module path',
|
|
504
|
+
default: 'code',
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
required: ['path', 'pattern'],
|
|
508
|
+
},
|
|
509
|
+
},
|
|
289
510
|
},
|
|
290
511
|
required: ['code'],
|
|
291
512
|
},
|
|
@@ -3,7 +3,6 @@ import { CodeCollector } from '../../domains/shared/modules.js';
|
|
|
3
3
|
import { ScriptManager } from '../../domains/shared/modules.js';
|
|
4
4
|
import { Deobfuscator } from '../../domains/shared/modules.js';
|
|
5
5
|
import { AdvancedDeobfuscator } from '../../domains/shared/modules.js';
|
|
6
|
-
import { ASTOptimizer } from '../../domains/shared/modules.js';
|
|
7
6
|
import { ObfuscationDetector } from '../../domains/shared/modules.js';
|
|
8
7
|
import { CodeAnalyzer } from '../../domains/shared/modules.js';
|
|
9
8
|
import { CryptoDetector } from '../../domains/shared/modules.js';
|
|
@@ -13,7 +12,6 @@ interface CoreAnalysisHandlerDeps {
|
|
|
13
12
|
scriptManager: ScriptManager;
|
|
14
13
|
deobfuscator: Deobfuscator;
|
|
15
14
|
advancedDeobfuscator: AdvancedDeobfuscator;
|
|
16
|
-
astOptimizer: ASTOptimizer;
|
|
17
15
|
obfuscationDetector: ObfuscationDetector;
|
|
18
16
|
analyzer: CodeAnalyzer;
|
|
19
17
|
cryptoDetector: CryptoDetector;
|
|
@@ -24,13 +22,13 @@ export declare class CoreAnalysisHandlers {
|
|
|
24
22
|
private readonly scriptManager;
|
|
25
23
|
private readonly deobfuscator;
|
|
26
24
|
private readonly advancedDeobfuscator;
|
|
27
|
-
private readonly astOptimizer;
|
|
28
25
|
private readonly obfuscationDetector;
|
|
29
26
|
private readonly analyzer;
|
|
30
27
|
private readonly cryptoDetector;
|
|
31
28
|
private readonly hookManager;
|
|
32
29
|
constructor(deps: CoreAnalysisHandlerDeps);
|
|
33
30
|
private requireCodeArg;
|
|
31
|
+
private extractWebcrackArgs;
|
|
34
32
|
handleCollectCode(args: ToolArgs): Promise<ToolResponse>;
|
|
35
33
|
handleSearchInScripts(args: ToolArgs): Promise<ToolResponse>;
|
|
36
34
|
handleExtractFunctionTree(args: ToolArgs): Promise<ToolResponse>;
|
|
@@ -40,6 +38,7 @@ export declare class CoreAnalysisHandlers {
|
|
|
40
38
|
handleManageHooks(args: ToolArgs): Promise<ToolResponse>;
|
|
41
39
|
handleDetectObfuscation(args: ToolArgs): Promise<ToolResponse>;
|
|
42
40
|
handleAdvancedDeobfuscate(args: ToolArgs): Promise<ToolResponse>;
|
|
41
|
+
handleWebcrackUnpack(args: ToolArgs): Promise<ToolResponse>;
|
|
43
42
|
handleWebpackEnumerate(args: ToolArgs): Promise<ToolResponse>;
|
|
44
43
|
handleSourceMapExtract(args: ToolArgs): Promise<ToolResponse>;
|
|
45
44
|
handleClearCollectedData(): Promise<ToolResponse>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { logger } from '../../../utils/logger.js';
|
|
2
2
|
import { asJsonResponse, asTextResponse, serializeError } from '../../domains/shared/response.js';
|
|
3
3
|
import { runSourceMapExtract, runWebpackEnumerate } from '../../domains/analysis/handlers.web-tools.js';
|
|
4
|
+
import { runWebcrack } from '../../../modules/deobfuscator/webcrack.js';
|
|
4
5
|
export class CoreAnalysisHandlers {
|
|
5
6
|
collector;
|
|
6
7
|
scriptManager;
|
|
7
8
|
deobfuscator;
|
|
8
9
|
advancedDeobfuscator;
|
|
9
|
-
astOptimizer;
|
|
10
10
|
obfuscationDetector;
|
|
11
11
|
analyzer;
|
|
12
12
|
cryptoDetector;
|
|
@@ -16,7 +16,6 @@ export class CoreAnalysisHandlers {
|
|
|
16
16
|
this.scriptManager = deps.scriptManager;
|
|
17
17
|
this.deobfuscator = deps.deobfuscator;
|
|
18
18
|
this.advancedDeobfuscator = deps.advancedDeobfuscator;
|
|
19
|
-
this.astOptimizer = deps.astOptimizer;
|
|
20
19
|
this.obfuscationDetector = deps.obfuscationDetector;
|
|
21
20
|
this.analyzer = deps.analyzer;
|
|
22
21
|
this.cryptoDetector = deps.cryptoDetector;
|
|
@@ -30,6 +29,33 @@ export class CoreAnalysisHandlers {
|
|
|
30
29
|
}
|
|
31
30
|
return code;
|
|
32
31
|
}
|
|
32
|
+
extractWebcrackArgs(args) {
|
|
33
|
+
const extracted = {};
|
|
34
|
+
if (typeof args.unpack === 'boolean')
|
|
35
|
+
extracted.unpack = args.unpack;
|
|
36
|
+
if (typeof args.unminify === 'boolean')
|
|
37
|
+
extracted.unminify = args.unminify;
|
|
38
|
+
if (typeof args.jsx === 'boolean')
|
|
39
|
+
extracted.jsx = args.jsx;
|
|
40
|
+
if (typeof args.mangle === 'boolean')
|
|
41
|
+
extracted.mangle = args.mangle;
|
|
42
|
+
if (typeof args.outputDir === 'string' && args.outputDir.trim().length > 0) {
|
|
43
|
+
extracted.outputDir = args.outputDir;
|
|
44
|
+
}
|
|
45
|
+
if (typeof args.forceOutput === 'boolean')
|
|
46
|
+
extracted.forceOutput = args.forceOutput;
|
|
47
|
+
if (typeof args.includeModuleCode === 'boolean')
|
|
48
|
+
extracted.includeModuleCode = args.includeModuleCode;
|
|
49
|
+
if (typeof args.maxBundleModules === 'number')
|
|
50
|
+
extracted.maxBundleModules = args.maxBundleModules;
|
|
51
|
+
if (Array.isArray(args.mappings)) {
|
|
52
|
+
extracted.mappings = args.mappings.filter((item) => typeof item === 'object' &&
|
|
53
|
+
item !== null &&
|
|
54
|
+
typeof item.path === 'string' &&
|
|
55
|
+
typeof item.pattern === 'string');
|
|
56
|
+
}
|
|
57
|
+
return extracted;
|
|
58
|
+
}
|
|
33
59
|
async handleCollectCode(args) {
|
|
34
60
|
const returnSummaryOnly = args.returnSummaryOnly ?? false;
|
|
35
61
|
let smartMode = args.smartMode;
|
|
@@ -200,6 +226,7 @@ export class CoreAnalysisHandlers {
|
|
|
200
226
|
code,
|
|
201
227
|
llm: args.llm,
|
|
202
228
|
aggressive: args.aggressive,
|
|
229
|
+
...this.extractWebcrackArgs(args),
|
|
203
230
|
});
|
|
204
231
|
return asJsonResponse(result);
|
|
205
232
|
}
|
|
@@ -280,24 +307,42 @@ export class CoreAnalysisHandlers {
|
|
|
280
307
|
error: 'code is required and must be a non-empty string',
|
|
281
308
|
});
|
|
282
309
|
}
|
|
283
|
-
const detectOnly = args.detectOnly ?? false;
|
|
284
|
-
const aggressiveVM = args.aggressiveVM ?? false;
|
|
285
|
-
const useASTOptimization = args.useASTOptimization ?? true;
|
|
286
|
-
const timeout = args.timeout ?? 60000;
|
|
287
310
|
const result = await this.advancedDeobfuscator.deobfuscate({
|
|
288
311
|
code,
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
312
|
+
...this.extractWebcrackArgs(args),
|
|
313
|
+
...(typeof args.detectOnly === 'boolean' ? { detectOnly: args.detectOnly } : {}),
|
|
314
|
+
...(typeof args.aggressiveVM === 'boolean' ? { aggressiveVM: args.aggressiveVM } : {}),
|
|
315
|
+
...(typeof args.useASTOptimization === 'boolean'
|
|
316
|
+
? { useASTOptimization: args.useASTOptimization }
|
|
317
|
+
: {}),
|
|
318
|
+
...(typeof args.timeout === 'number' ? { timeout: args.timeout } : {}),
|
|
292
319
|
});
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
320
|
+
return asJsonResponse(result);
|
|
321
|
+
}
|
|
322
|
+
async handleWebcrackUnpack(args) {
|
|
323
|
+
const code = this.requireCodeArg(args, 'webcrack_unpack');
|
|
324
|
+
if (!code) {
|
|
325
|
+
return asJsonResponse({
|
|
326
|
+
success: false,
|
|
327
|
+
error: 'code is required and must be a non-empty string',
|
|
328
|
+
});
|
|
296
329
|
}
|
|
330
|
+
const result = await runWebcrack(code, {
|
|
331
|
+
unpack: args.unpack ?? true,
|
|
332
|
+
unminify: args.unminify ?? true,
|
|
333
|
+
jsx: args.jsx ?? true,
|
|
334
|
+
mangle: args.mangle ?? false,
|
|
335
|
+
...this.extractWebcrackArgs(args),
|
|
336
|
+
});
|
|
297
337
|
return asJsonResponse({
|
|
298
|
-
|
|
299
|
-
code:
|
|
300
|
-
|
|
338
|
+
success: result.applied,
|
|
339
|
+
code: result.code,
|
|
340
|
+
bundle: result.bundle,
|
|
341
|
+
savedTo: result.savedTo,
|
|
342
|
+
savedArtifacts: result.savedArtifacts,
|
|
343
|
+
optionsUsed: result.optionsUsed,
|
|
344
|
+
warning: result.reason,
|
|
345
|
+
engine: 'webcrack',
|
|
301
346
|
});
|
|
302
347
|
}
|
|
303
348
|
async handleWebpackEnumerate(args) {
|
|
@@ -3,7 +3,6 @@ import { coreTools } from '../../domains/analysis/definitions.js';
|
|
|
3
3
|
import { CoreAnalysisHandlers } from '../../domains/analysis/index.js';
|
|
4
4
|
import { Deobfuscator } from '../../domains/shared/modules.js';
|
|
5
5
|
import { AdvancedDeobfuscator } from '../../domains/shared/modules.js';
|
|
6
|
-
import { ASTOptimizer } from '../../domains/shared/modules.js';
|
|
7
6
|
import { ObfuscationDetector } from '../../domains/shared/modules.js';
|
|
8
7
|
import { CodeAnalyzer } from '../../domains/shared/modules.js';
|
|
9
8
|
import { CryptoDetector } from '../../domains/shared/modules.js';
|
|
@@ -17,9 +16,7 @@ function ensure(ctx) {
|
|
|
17
16
|
if (!ctx.deobfuscator)
|
|
18
17
|
ctx.deobfuscator = new Deobfuscator(ctx.llm);
|
|
19
18
|
if (!ctx.advancedDeobfuscator)
|
|
20
|
-
ctx.advancedDeobfuscator = new AdvancedDeobfuscator(
|
|
21
|
-
if (!ctx.astOptimizer)
|
|
22
|
-
ctx.astOptimizer = new ASTOptimizer();
|
|
19
|
+
ctx.advancedDeobfuscator = new AdvancedDeobfuscator();
|
|
23
20
|
if (!ctx.obfuscationDetector)
|
|
24
21
|
ctx.obfuscationDetector = new ObfuscationDetector();
|
|
25
22
|
if (!ctx.analyzer)
|
|
@@ -34,7 +31,6 @@ function ensure(ctx) {
|
|
|
34
31
|
scriptManager: ctx.scriptManager,
|
|
35
32
|
deobfuscator: ctx.deobfuscator,
|
|
36
33
|
advancedDeobfuscator: ctx.advancedDeobfuscator,
|
|
37
|
-
astOptimizer: ctx.astOptimizer,
|
|
38
34
|
obfuscationDetector: ctx.obfuscationDetector,
|
|
39
35
|
analyzer: ctx.analyzer,
|
|
40
36
|
cryptoDetector: ctx.cryptoDetector,
|
|
@@ -60,6 +56,7 @@ const manifest = {
|
|
|
60
56
|
{ tool: t('manage_hooks'), domain: DOMAIN, bind: b((h, a) => h.handleManageHooks(a)) },
|
|
61
57
|
{ tool: t('detect_obfuscation'), domain: DOMAIN, bind: b((h, a) => h.handleDetectObfuscation(a)) },
|
|
62
58
|
{ tool: t('advanced_deobfuscate'), domain: DOMAIN, bind: b((h, a) => h.handleAdvancedDeobfuscate(a)) },
|
|
59
|
+
{ tool: t('webcrack_unpack'), domain: DOMAIN, bind: b((h, a) => h.handleWebcrackUnpack(a)) },
|
|
63
60
|
{ tool: t('clear_collected_data'), domain: DOMAIN, bind: b((h) => h.handleClearCollectedData()) },
|
|
64
61
|
{ tool: t('get_collection_stats'), domain: DOMAIN, bind: b((h) => h.handleGetCollectionStats()) },
|
|
65
62
|
{ tool: t('webpack_enumerate'), domain: DOMAIN, bind: b((h, a) => h.handleWebpackEnumerate(a)) },
|