@jshookmcp/jshook 0.1.7 → 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.
Files changed (44) hide show
  1. package/README.md +145 -100
  2. package/README.zh.md +81 -36
  3. package/dist/constants.d.ts +1 -1
  4. package/dist/constants.js +3 -1
  5. package/dist/modules/analyzer/QualityAnalyzer.js +1 -1
  6. package/dist/modules/browser/BrowserDiscovery.js +2 -2
  7. package/dist/modules/browser/BrowserModeManager.js +3 -3
  8. package/dist/modules/captcha/AICaptchaDetector.d.ts +12 -16
  9. package/dist/modules/captcha/AICaptchaDetector.js +209 -189
  10. package/dist/modules/captcha/CaptchaDetector.constants.d.ts +2 -0
  11. package/dist/modules/captcha/CaptchaDetector.constants.js +116 -25
  12. package/dist/modules/captcha/CaptchaDetector.d.ts +2 -11
  13. package/dist/modules/captcha/CaptchaDetector.js +102 -51
  14. package/dist/modules/captcha/types.d.ts +46 -0
  15. package/dist/modules/captcha/types.js +52 -0
  16. package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts +15 -20
  17. package/dist/modules/deobfuscator/AdvancedDeobfuscator.js +66 -234
  18. package/dist/modules/deobfuscator/Deobfuscator.d.ts +3 -10
  19. package/dist/modules/deobfuscator/Deobfuscator.js +125 -404
  20. package/dist/modules/deobfuscator/webcrack.d.ts +13 -0
  21. package/dist/modules/deobfuscator/webcrack.js +164 -0
  22. package/dist/modules/detector/ObfuscationDetector.d.ts +6 -0
  23. package/dist/modules/detector/ObfuscationDetector.js +53 -2
  24. package/dist/modules/hook/AIHookGenerator.js +1 -1
  25. package/dist/modules/process/memory/writer.js +1 -1
  26. package/dist/server/domains/analysis/definitions.js +223 -2
  27. package/dist/server/domains/analysis/handlers.impl.d.ts +2 -3
  28. package/dist/server/domains/analysis/handlers.impl.js +60 -15
  29. package/dist/server/domains/analysis/manifest.js +2 -5
  30. package/dist/server/domains/browser/definitions.tools.behavior.js +36 -24
  31. package/dist/server/domains/browser/definitions.tools.security.js +13 -10
  32. package/dist/server/domains/browser/handlers/camoufox-flow.js +0 -1
  33. package/dist/server/domains/browser/handlers/captcha-solver.d.ts +1 -1
  34. package/dist/server/domains/browser/handlers/captcha-solver.js +121 -54
  35. package/dist/server/domains/browser/handlers/page-navigation.js +0 -2
  36. package/dist/server/domains/browser/handlers.impl.d.ts +1 -1
  37. package/dist/server/domains/browser/handlers.impl.js +3 -3
  38. package/dist/server/domains/browser/manifest.js +1 -1
  39. package/dist/server/domains/shared/modules.d.ts +1 -0
  40. package/dist/types/deobfuscator.d.ts +43 -1
  41. package/dist/types/index.d.ts +1 -1
  42. package/dist/utils/config.js +19 -10
  43. package/package.json +6 -3
  44. package/scripts/postinstall.cjs +37 -0
@@ -0,0 +1,164 @@
1
+ import { readdir, rm, stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { logger } from '../../utils/logger.js';
4
+ const DEFAULT_OPTIONS = {
5
+ jsx: true,
6
+ mangle: false,
7
+ unminify: true,
8
+ unpack: true,
9
+ };
10
+ const MAX_BUNDLE_MODULES = 100;
11
+ function normalizeOptions(options) {
12
+ return {
13
+ jsx: options.jsx ?? DEFAULT_OPTIONS.jsx,
14
+ mangle: options.mangle ?? DEFAULT_OPTIONS.mangle,
15
+ unminify: options.unminify ?? DEFAULT_OPTIONS.unminify,
16
+ unpack: options.unpack ?? DEFAULT_OPTIONS.unpack,
17
+ };
18
+ }
19
+ function isSupportedNodeVersion() {
20
+ const major = Number.parseInt(process.versions.node.split('.')[0] ?? '0', 10);
21
+ return Number.isFinite(major) && major >= 22;
22
+ }
23
+ function matchesRule(module, rule) {
24
+ const target = rule.target === 'path' ? module.path : module.code;
25
+ const matchType = rule.matchType ?? 'includes';
26
+ if (matchType === 'exact') {
27
+ return target === rule.pattern;
28
+ }
29
+ if (matchType === 'regex') {
30
+ try {
31
+ return new RegExp(rule.pattern, 'm').test(target);
32
+ }
33
+ catch {
34
+ return false;
35
+ }
36
+ }
37
+ return target.includes(rule.pattern);
38
+ }
39
+ function applyBundleMappings(bundle, mappings) {
40
+ const remapped = new Map();
41
+ if (!mappings || mappings.length === 0) {
42
+ return remapped;
43
+ }
44
+ for (const module of bundle.modules.values()) {
45
+ for (const rule of mappings) {
46
+ if (!rule.path || !rule.pattern) {
47
+ continue;
48
+ }
49
+ if (matchesRule(module, rule)) {
50
+ if (module.path !== rule.path) {
51
+ remapped.set(module.id, { fromPath: module.path });
52
+ module.path = rule.path;
53
+ }
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ return remapped;
59
+ }
60
+ function summarizeBundle(bundle, options, remapped) {
61
+ const maxBundleModules = options.maxBundleModules ?? MAX_BUNDLE_MODULES;
62
+ const modules = Array.from(bundle.modules.values())
63
+ .sort((left, right) => {
64
+ if (left.isEntry !== right.isEntry) {
65
+ return left.isEntry ? -1 : 1;
66
+ }
67
+ return left.path.localeCompare(right.path);
68
+ })
69
+ .slice(0, maxBundleModules)
70
+ .map((module) => ({
71
+ id: module.id,
72
+ path: module.path,
73
+ isEntry: module.isEntry,
74
+ size: module.code.length,
75
+ code: options.includeModuleCode ? module.code : undefined,
76
+ mappedPathFrom: remapped.get(module.id)?.fromPath,
77
+ }));
78
+ return {
79
+ type: bundle.type,
80
+ entryId: bundle.entryId,
81
+ moduleCount: bundle.modules.size,
82
+ truncated: bundle.modules.size > maxBundleModules,
83
+ mappingsApplied: remapped.size,
84
+ modules,
85
+ };
86
+ }
87
+ async function collectSavedArtifacts(rootDir, currentDir = rootDir) {
88
+ const entries = await readdir(currentDir, { withFileTypes: true });
89
+ const artifacts = [];
90
+ for (const entry of entries) {
91
+ const fullPath = path.join(currentDir, entry.name);
92
+ if (entry.isDirectory()) {
93
+ artifacts.push(...(await collectSavedArtifacts(rootDir, fullPath)));
94
+ continue;
95
+ }
96
+ if (!entry.isFile()) {
97
+ continue;
98
+ }
99
+ const metadata = await stat(fullPath);
100
+ artifacts.push({
101
+ path: path.relative(rootDir, fullPath).replace(/\\/g, '/'),
102
+ size: metadata.size,
103
+ type: 'file',
104
+ });
105
+ }
106
+ return artifacts.sort((left, right) => left.path.localeCompare(right.path));
107
+ }
108
+ export async function runWebcrack(code, options) {
109
+ const optionsUsed = normalizeOptions(options);
110
+ if (!isSupportedNodeVersion()) {
111
+ const reason = `webcrack requires Node.js 22+; current runtime is ${process.versions.node}`;
112
+ logger.warn(reason);
113
+ return {
114
+ applied: false,
115
+ code,
116
+ optionsUsed,
117
+ reason,
118
+ };
119
+ }
120
+ try {
121
+ const { webcrack } = (await import('webcrack'));
122
+ const result = await webcrack(code, {
123
+ jsx: optionsUsed.jsx,
124
+ unpack: optionsUsed.unpack,
125
+ deobfuscate: true,
126
+ unminify: optionsUsed.unminify,
127
+ mangle: optionsUsed.mangle,
128
+ });
129
+ const remapped = result.bundle ? applyBundleMappings(result.bundle, options.mappings) : new Map();
130
+ let savedTo;
131
+ let savedArtifacts;
132
+ if (typeof options.outputDir === 'string' && options.outputDir.trim().length > 0) {
133
+ savedTo = path.resolve(options.outputDir);
134
+ if (options.forceOutput) {
135
+ await rm(savedTo, { recursive: true, force: true });
136
+ }
137
+ await result.save(savedTo);
138
+ savedArtifacts = await collectSavedArtifacts(savedTo);
139
+ }
140
+ return {
141
+ applied: true,
142
+ code: result.code,
143
+ bundle: result.bundle
144
+ ? summarizeBundle(result.bundle, {
145
+ includeModuleCode: options.includeModuleCode,
146
+ maxBundleModules: options.maxBundleModules,
147
+ }, remapped)
148
+ : undefined,
149
+ savedTo,
150
+ savedArtifacts,
151
+ optionsUsed,
152
+ };
153
+ }
154
+ catch (error) {
155
+ const reason = error instanceof Error ? error.message : String(error);
156
+ logger.warn('webcrack execution failed, falling back to legacy pipeline', error);
157
+ return {
158
+ applied: false,
159
+ code,
160
+ optionsUsed,
161
+ reason,
162
+ };
163
+ }
164
+ }
@@ -4,12 +4,18 @@ export interface DetectionResult {
4
4
  confidence: Record<ObfuscationType, number>;
5
5
  features: string[];
6
6
  recommendations: string[];
7
+ toolRecommendations: Array<{
8
+ tool: string;
9
+ reason: string;
10
+ suggestedArgs?: Record<string, unknown>;
11
+ }>;
7
12
  vmFeatures?: VMFeatures;
8
13
  }
9
14
  export declare class ObfuscationDetector {
10
15
  private jsvmpDetector;
11
16
  constructor();
12
17
  detect(code: string): DetectionResult;
18
+ private buildToolRecommendations;
13
19
  private detectVMProtectionDetailed;
14
20
  private detectJavaScriptObfuscator;
15
21
  private detectWebpack;
@@ -16,13 +16,13 @@ export class ObfuscationDetector {
16
16
  confidence['javascript-obfuscator'] = 0.9;
17
17
  features.push('String array with rotation');
18
18
  features.push('Control flow flattening');
19
- recommendations.push('Use webcrack or restringer for deobfuscation');
19
+ recommendations.push('Use deobfuscate/advanced_deobfuscate with webcrack enabled');
20
20
  }
21
21
  if (this.detectWebpack(code)) {
22
22
  types.push('webpack');
23
23
  confidence['webpack'] = 0.85;
24
24
  features.push('__webpack_require__');
25
- recommendations.push('Use webpack-bundle-analyzer');
25
+ recommendations.push('Use deobfuscate/advanced_deobfuscate with unpack=true to recover modules');
26
26
  }
27
27
  if (this.detectUglify(code)) {
28
28
  types.push('uglify');
@@ -140,9 +140,51 @@ export class ObfuscationDetector {
140
140
  confidence: confidence,
141
141
  features,
142
142
  recommendations,
143
+ toolRecommendations: this.buildToolRecommendations(types, code),
143
144
  vmFeatures,
144
145
  };
145
146
  }
147
+ buildToolRecommendations(types, code) {
148
+ const recommendations = new Map();
149
+ const addRecommendation = (tool, reason, suggestedArgs) => {
150
+ if (!recommendations.has(tool)) {
151
+ recommendations.set(tool, { tool, reason, suggestedArgs });
152
+ }
153
+ };
154
+ if (types.includes('webpack') || types.includes('packer')) {
155
+ addRecommendation('webcrack_unpack', 'Bundle or wrapper markers detected; unpacking modules is likely the highest-value first step.', { code, unpack: true, unminify: true });
156
+ }
157
+ if (types.some((type) => [
158
+ 'javascript-obfuscator',
159
+ 'string-array-rotation',
160
+ 'hex-encoding',
161
+ 'base64-encoding',
162
+ 'urlencoded',
163
+ 'unknown',
164
+ ].includes(type))) {
165
+ addRecommendation('deobfuscate', 'Static cleanup is likely sufficient; start with the standard webcrack-backed deobfuscation path.', { code, unminify: true });
166
+ }
167
+ if (types.some((type) => [
168
+ 'vm-protection',
169
+ 'control-flow-flattening',
170
+ 'dead-code-injection',
171
+ 'opaque-predicates',
172
+ 'invisible-unicode',
173
+ 'jscrambler',
174
+ 'jsfuck',
175
+ 'aaencode',
176
+ 'jjencode',
177
+ ].includes(type))) {
178
+ addRecommendation('advanced_deobfuscate', 'Complex protections detected; use the advanced webcrack-backed flow for deeper cleanup.', { code, detectOnly: false, unminify: true });
179
+ }
180
+ if (types.includes('eval-obfuscation') || types.includes('self-modifying')) {
181
+ addRecommendation('manage_hooks', 'Runtime-generated code is present; capture or hook execution points before static cleanup if analysis stalls.', { action: 'create', target: 'eval', type: 'function' });
182
+ }
183
+ if (recommendations.size === 0) {
184
+ addRecommendation('deobfuscate', 'No strong signature matched; start with the standard webcrack-backed path.', { code });
185
+ }
186
+ return Array.from(recommendations.values());
187
+ }
146
188
  detectVMProtectionDetailed(code) {
147
189
  try {
148
190
  const detector = this.jsvmpDetector;
@@ -273,6 +315,15 @@ export class ObfuscationDetector {
273
315
  result.recommendations.forEach((rec) => {
274
316
  report += ` - ${rec}\n`;
275
317
  });
318
+ if (result.toolRecommendations.length > 0) {
319
+ report += `\nSuggested Tools:\n`;
320
+ result.toolRecommendations.forEach((item) => {
321
+ report += ` - ${item.tool}: ${item.reason}\n`;
322
+ if (item.suggestedArgs) {
323
+ report += ` args: ${JSON.stringify(item.suggestedArgs)}\n`;
324
+ }
325
+ });
326
+ }
276
327
  return report;
277
328
  }
278
329
  }
@@ -61,7 +61,7 @@ export class AIHookGenerator {
61
61
  generateFunctionHook(request, hookId) {
62
62
  const { target, behavior, condition, customCode } = request;
63
63
  const functionName = target.name || target.pattern || 'unknownFunction';
64
- let code = `
64
+ const code = `
65
65
  (function() {
66
66
  const originalFunction = window.${functionName};
67
67
 
@@ -149,7 +149,7 @@ export async function writeMemory(platform, pid, address, data, encoding = 'hex'
149
149
  buffer = Buffer.from(cleanHex, 'hex');
150
150
  }
151
151
  }
152
- catch (e) {
152
+ catch (_e) {
153
153
  return { success: false, error: `Invalid ${encoding} data` };
154
154
  }
155
155
  if (platform === 'win32' && isKoffiAvailable()) {
@@ -138,7 +138,7 @@ export const coreTools = [
138
138
  },
139
139
  {
140
140
  name: 'deobfuscate',
141
- description: 'Run LLM-assisted JavaScript deobfuscation.',
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 VM-oriented strategies.',
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>;