@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,15 +1,6 @@
|
|
|
1
1
|
import { Page } from 'rebrowser-puppeteer-core';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type?: 'slider' | 'image' | 'recaptcha' | 'hcaptcha' | 'cloudflare' | 'page_redirect' | 'url_redirect' | 'unknown';
|
|
5
|
-
selector?: string;
|
|
6
|
-
title?: string;
|
|
7
|
-
url?: string;
|
|
8
|
-
confidence: number;
|
|
9
|
-
vendor?: 'geetest' | 'tencent' | 'aliyun' | 'cloudflare' | 'akamai' | 'datadome' | 'perimeter-x' | 'recaptcha' | 'hcaptcha' | 'unknown';
|
|
10
|
-
details?: unknown;
|
|
11
|
-
falsePositiveReason?: string;
|
|
12
|
-
}
|
|
2
|
+
import type { CaptchaDetectionResult } from '../captcha/types.js';
|
|
3
|
+
export type { CaptchaDetectionResult } from '../captcha/types.js';
|
|
13
4
|
export declare class CaptchaDetector {
|
|
14
5
|
private static readonly EXCLUDE_SELECTORS;
|
|
15
6
|
private static readonly CAPTCHA_SELECTORS;
|
|
@@ -29,11 +29,11 @@ export class CaptchaDetector {
|
|
|
29
29
|
return vendorCheck;
|
|
30
30
|
}
|
|
31
31
|
logger.info('No CAPTCHA detected by current heuristics');
|
|
32
|
-
return { detected: false, confidence: 0 };
|
|
32
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
33
33
|
}
|
|
34
34
|
catch (error) {
|
|
35
35
|
logger.error('CAPTCHA detection failed', error);
|
|
36
|
-
return { detected: false, confidence: 0 };
|
|
36
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
async checkUrl(page) {
|
|
@@ -42,53 +42,82 @@ export class CaptchaDetector {
|
|
|
42
42
|
for (const excludeKeyword of CaptchaDetector.EXCLUDE_KEYWORDS.url) {
|
|
43
43
|
if (lowerUrl.includes(excludeKeyword)) {
|
|
44
44
|
logger.debug(`URL matched exclusion keyword: ${excludeKeyword}`);
|
|
45
|
-
return {
|
|
45
|
+
return {
|
|
46
|
+
detected: false,
|
|
47
|
+
type: 'none',
|
|
48
|
+
confidence: 0,
|
|
49
|
+
falsePositiveReason: `URL exclusion: ${excludeKeyword}`,
|
|
50
|
+
};
|
|
46
51
|
}
|
|
47
52
|
}
|
|
48
53
|
for (const keyword of CaptchaDetector.CAPTCHA_KEYWORDS.url) {
|
|
49
54
|
if (lowerUrl.includes(keyword)) {
|
|
50
55
|
let type = 'url_redirect';
|
|
51
|
-
let
|
|
56
|
+
let providerHint;
|
|
52
57
|
let confidence = 70;
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
if (lowerUrl.includes('cloudflare') ||
|
|
59
|
+
lowerUrl.includes('cdn-cgi') ||
|
|
60
|
+
lowerUrl.includes('akamai') ||
|
|
61
|
+
lowerUrl.includes('datadome') ||
|
|
62
|
+
lowerUrl.includes('perimeterx') ||
|
|
63
|
+
lowerUrl.includes('perimeter') ||
|
|
64
|
+
lowerUrl.includes('px-captcha') ||
|
|
65
|
+
lowerUrl.includes('incapsula') ||
|
|
66
|
+
lowerUrl.includes('distil') ||
|
|
67
|
+
lowerUrl.includes('shield-square')) {
|
|
68
|
+
type = 'browser_check';
|
|
69
|
+
providerHint = 'edge_service';
|
|
61
70
|
confidence = 95;
|
|
62
71
|
}
|
|
63
|
-
else if (
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
else if (lowerUrl.includes('recaptcha') ||
|
|
73
|
+
lowerUrl.includes('turnstile') ||
|
|
74
|
+
lowerUrl.includes('hcaptcha')) {
|
|
75
|
+
type = 'widget';
|
|
76
|
+
providerHint = 'embedded_widget';
|
|
66
77
|
confidence = 95;
|
|
67
78
|
}
|
|
68
|
-
else if (
|
|
79
|
+
else if (lowerUrl.includes('geetest') ||
|
|
80
|
+
lowerUrl.includes('aliyun/captcha') ||
|
|
81
|
+
lowerUrl.includes('tencent/captcha') ||
|
|
82
|
+
lowerUrl.includes('netease-captcha') ||
|
|
83
|
+
lowerUrl.includes('yidun')) {
|
|
69
84
|
type = 'slider';
|
|
70
|
-
|
|
85
|
+
providerHint = 'regional_service';
|
|
86
|
+
confidence = 90;
|
|
87
|
+
}
|
|
88
|
+
else if (lowerUrl.includes('arkose') ||
|
|
89
|
+
lowerUrl.includes('funcaptcha') ||
|
|
90
|
+
lowerUrl.includes('friendly-captcha') ||
|
|
91
|
+
lowerUrl.includes('keycaptcha') ||
|
|
92
|
+
lowerUrl.includes('iw-captcha')) {
|
|
93
|
+
type = 'widget';
|
|
94
|
+
providerHint = 'managed_service';
|
|
71
95
|
confidence = 90;
|
|
72
96
|
}
|
|
73
97
|
if (confidence < 80) {
|
|
74
98
|
const domCheck = await this.verifyByDOM(page);
|
|
75
99
|
if (!domCheck) {
|
|
76
100
|
logger.debug(`URL keyword match in DOM, skipping: ${keyword}`);
|
|
77
|
-
return {
|
|
101
|
+
return {
|
|
102
|
+
detected: false,
|
|
103
|
+
type: 'none',
|
|
104
|
+
confidence: 0,
|
|
105
|
+
falsePositiveReason: `URLDOM: ${keyword}`,
|
|
106
|
+
};
|
|
78
107
|
}
|
|
79
108
|
confidence = 85;
|
|
80
109
|
}
|
|
81
|
-
logger.warn(`CAPTCHA URL
|
|
110
|
+
logger.warn(`CAPTCHA URL signal detected (confidence: ${confidence}%)`);
|
|
82
111
|
return {
|
|
83
112
|
detected: true,
|
|
84
113
|
type,
|
|
85
114
|
url,
|
|
86
|
-
|
|
115
|
+
providerHint,
|
|
87
116
|
confidence,
|
|
88
117
|
};
|
|
89
118
|
}
|
|
90
119
|
}
|
|
91
|
-
return { detected: false, confidence: 0 };
|
|
120
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
92
121
|
}
|
|
93
122
|
async checkTitle(page) {
|
|
94
123
|
const title = await page.title();
|
|
@@ -96,7 +125,12 @@ export class CaptchaDetector {
|
|
|
96
125
|
for (const excludeKeyword of CaptchaDetector.EXCLUDE_KEYWORDS.title) {
|
|
97
126
|
if (lowerTitle.includes(excludeKeyword.toLowerCase())) {
|
|
98
127
|
logger.debug(`Title matched exclusion keyword: ${excludeKeyword}`);
|
|
99
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
detected: false,
|
|
130
|
+
type: 'none',
|
|
131
|
+
confidence: 0,
|
|
132
|
+
falsePositiveReason: `Title exclusion: ${excludeKeyword}`,
|
|
133
|
+
};
|
|
100
134
|
}
|
|
101
135
|
}
|
|
102
136
|
for (const keyword of CaptchaDetector.CAPTCHA_KEYWORDS.title) {
|
|
@@ -104,7 +138,12 @@ export class CaptchaDetector {
|
|
|
104
138
|
const domCheck = await this.verifyByDOM(page);
|
|
105
139
|
if (!domCheck) {
|
|
106
140
|
logger.debug(`DOM keyword is common UI element, skipping: ${keyword}`);
|
|
107
|
-
return {
|
|
141
|
+
return {
|
|
142
|
+
detected: false,
|
|
143
|
+
type: 'none',
|
|
144
|
+
confidence: 0,
|
|
145
|
+
falsePositiveReason: `DOM: ${keyword}`,
|
|
146
|
+
};
|
|
108
147
|
}
|
|
109
148
|
logger.warn(`CAPTCHA DOM keyword detected: ${keyword}`);
|
|
110
149
|
return {
|
|
@@ -115,7 +154,7 @@ export class CaptchaDetector {
|
|
|
115
154
|
};
|
|
116
155
|
}
|
|
117
156
|
}
|
|
118
|
-
return { detected: false, confidence: 0 };
|
|
157
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
119
158
|
}
|
|
120
159
|
async checkDOMElements(page) {
|
|
121
160
|
for (const selector of CaptchaDetector.CAPTCHA_SELECTORS.slider) {
|
|
@@ -128,19 +167,21 @@ export class CaptchaDetector {
|
|
|
128
167
|
logger.debug(`Selector is generic, skipping: ${selector}`);
|
|
129
168
|
continue;
|
|
130
169
|
}
|
|
131
|
-
logger.warn(`CAPTCHA selector detected: ${selector}`);
|
|
132
|
-
let
|
|
133
|
-
if (selector.includes('geetest')
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
170
|
+
logger.warn(`Slider CAPTCHA selector detected: ${selector}`);
|
|
171
|
+
let providerHint;
|
|
172
|
+
if (selector.includes('geetest') ||
|
|
173
|
+
selector.includes('nc_') ||
|
|
174
|
+
selector.includes('aliyun') ||
|
|
175
|
+
selector.includes('tcaptcha') ||
|
|
176
|
+
selector.includes('tencent') ||
|
|
177
|
+
selector.includes('yidun')) {
|
|
178
|
+
providerHint = 'regional_service';
|
|
179
|
+
}
|
|
139
180
|
return {
|
|
140
181
|
detected: true,
|
|
141
182
|
type: 'slider',
|
|
142
183
|
selector,
|
|
143
|
-
|
|
184
|
+
providerHint,
|
|
144
185
|
confidence: 95,
|
|
145
186
|
};
|
|
146
187
|
}
|
|
@@ -149,12 +190,12 @@ export class CaptchaDetector {
|
|
|
149
190
|
for (const selector of CaptchaDetector.CAPTCHA_SELECTORS.recaptcha) {
|
|
150
191
|
const element = await page.$(selector);
|
|
151
192
|
if (element) {
|
|
152
|
-
logger.warn(`
|
|
193
|
+
logger.warn(`Embedded challenge widget detected: ${selector}`);
|
|
153
194
|
return {
|
|
154
195
|
detected: true,
|
|
155
|
-
type: '
|
|
196
|
+
type: 'widget',
|
|
156
197
|
selector,
|
|
157
|
-
|
|
198
|
+
providerHint: 'embedded_widget',
|
|
158
199
|
confidence: 98,
|
|
159
200
|
};
|
|
160
201
|
}
|
|
@@ -162,12 +203,12 @@ export class CaptchaDetector {
|
|
|
162
203
|
for (const selector of CaptchaDetector.CAPTCHA_SELECTORS.hcaptcha) {
|
|
163
204
|
const element = await page.$(selector);
|
|
164
205
|
if (element) {
|
|
165
|
-
logger.warn(`
|
|
206
|
+
logger.warn(`Embedded challenge widget detected: ${selector}`);
|
|
166
207
|
return {
|
|
167
208
|
detected: true,
|
|
168
|
-
type: '
|
|
209
|
+
type: 'widget',
|
|
169
210
|
selector,
|
|
170
|
-
|
|
211
|
+
providerHint: 'embedded_widget',
|
|
171
212
|
confidence: 98,
|
|
172
213
|
};
|
|
173
214
|
}
|
|
@@ -175,24 +216,29 @@ export class CaptchaDetector {
|
|
|
175
216
|
for (const selector of CaptchaDetector.CAPTCHA_SELECTORS.cloudflare) {
|
|
176
217
|
const element = await page.$(selector);
|
|
177
218
|
if (element) {
|
|
178
|
-
logger.warn(`
|
|
219
|
+
logger.warn(`Edge browser-check challenge detected: ${selector}`);
|
|
179
220
|
return {
|
|
180
221
|
detected: true,
|
|
181
|
-
type: '
|
|
222
|
+
type: 'browser_check',
|
|
182
223
|
selector,
|
|
183
|
-
|
|
224
|
+
providerHint: 'edge_service',
|
|
184
225
|
confidence: 97,
|
|
185
226
|
};
|
|
186
227
|
}
|
|
187
228
|
}
|
|
188
|
-
return { detected: false, confidence: 0 };
|
|
229
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
189
230
|
}
|
|
190
231
|
async checkPageText(page) {
|
|
191
232
|
const bodyText = await page.evaluate(() => document.body.innerText);
|
|
192
233
|
for (const excludeKeyword of CaptchaDetector.EXCLUDE_KEYWORDS.text) {
|
|
193
234
|
if (bodyText.includes(excludeKeyword)) {
|
|
194
235
|
logger.debug(`Body text matched exclusion keyword: ${excludeKeyword}`);
|
|
195
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
detected: false,
|
|
238
|
+
type: 'none',
|
|
239
|
+
confidence: 0,
|
|
240
|
+
falsePositiveReason: `Text exclusion: ${excludeKeyword}`,
|
|
241
|
+
};
|
|
196
242
|
}
|
|
197
243
|
}
|
|
198
244
|
for (const keyword of CaptchaDetector.CAPTCHA_KEYWORDS.text) {
|
|
@@ -200,7 +246,12 @@ export class CaptchaDetector {
|
|
|
200
246
|
const domCheck = await this.verifyByDOM(page);
|
|
201
247
|
if (!domCheck) {
|
|
202
248
|
logger.debug(`Keyword is common element, skipping: ${keyword}`);
|
|
203
|
-
return {
|
|
249
|
+
return {
|
|
250
|
+
detected: false,
|
|
251
|
+
type: 'none',
|
|
252
|
+
confidence: 0,
|
|
253
|
+
falsePositiveReason: `DOM: ${keyword}`,
|
|
254
|
+
};
|
|
204
255
|
}
|
|
205
256
|
logger.warn(`CAPTCHA keyword detected: ${keyword}`);
|
|
206
257
|
return {
|
|
@@ -211,7 +262,7 @@ export class CaptchaDetector {
|
|
|
211
262
|
};
|
|
212
263
|
}
|
|
213
264
|
}
|
|
214
|
-
return { detected: false, confidence: 0 };
|
|
265
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
215
266
|
}
|
|
216
267
|
async checkVendorSpecific(page) {
|
|
217
268
|
const geetestCheck = await page.evaluate(() => {
|
|
@@ -219,11 +270,11 @@ export class CaptchaDetector {
|
|
|
219
270
|
return !!win.initGeetest || document.querySelector('.geetest_holder');
|
|
220
271
|
});
|
|
221
272
|
if (geetestCheck) {
|
|
222
|
-
logger.warn('
|
|
273
|
+
logger.warn('Regional slider CAPTCHA indicators detected');
|
|
223
274
|
return {
|
|
224
275
|
detected: true,
|
|
225
276
|
type: 'slider',
|
|
226
|
-
|
|
277
|
+
providerHint: 'regional_service',
|
|
227
278
|
confidence: 95,
|
|
228
279
|
};
|
|
229
280
|
}
|
|
@@ -232,15 +283,15 @@ export class CaptchaDetector {
|
|
|
232
283
|
return !!win.TencentCaptcha || document.querySelector('.tcaptcha-transform');
|
|
233
284
|
});
|
|
234
285
|
if (tencentCheck) {
|
|
235
|
-
logger.warn('
|
|
286
|
+
logger.warn('Regional slider CAPTCHA indicators detected');
|
|
236
287
|
return {
|
|
237
288
|
detected: true,
|
|
238
289
|
type: 'slider',
|
|
239
|
-
|
|
290
|
+
providerHint: 'regional_service',
|
|
240
291
|
confidence: 95,
|
|
241
292
|
};
|
|
242
293
|
}
|
|
243
|
-
return { detected: false, confidence: 0 };
|
|
294
|
+
return { detected: false, type: 'none', confidence: 0 };
|
|
244
295
|
}
|
|
245
296
|
async waitForCompletion(page, timeout = 300000) {
|
|
246
297
|
logger.info('Waiting for CAPTCHA to be solved...');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export declare const CAPTCHA_TYPES: readonly ["slider", "image", "widget", "browser_check", "page_redirect", "url_redirect", "text_input", "none", "unknown"];
|
|
2
|
+
export type CaptchaType = (typeof CAPTCHA_TYPES)[number];
|
|
3
|
+
export declare const CAPTCHA_PROVIDER_HINTS: readonly ["regional_service", "embedded_widget", "edge_service", "managed_service", "external_review", "unknown"];
|
|
4
|
+
export type CaptchaProviderHint = (typeof CAPTCHA_PROVIDER_HINTS)[number];
|
|
5
|
+
export declare const LEGACY_CAPTCHA_TYPE_ALIASES: Readonly<Record<string, CaptchaType>>;
|
|
6
|
+
export declare const LEGACY_CAPTCHA_PROVIDER_HINT_ALIASES: Readonly<Record<string, CaptchaProviderHint>>;
|
|
7
|
+
export interface CaptchaDetectionResultBase {
|
|
8
|
+
detected: boolean;
|
|
9
|
+
type: CaptchaType;
|
|
10
|
+
providerHint?: CaptchaProviderHint;
|
|
11
|
+
confidence: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CaptchaDetectionResult extends CaptchaDetectionResultBase {
|
|
14
|
+
selector?: string;
|
|
15
|
+
title?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
details?: unknown;
|
|
18
|
+
falsePositiveReason?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CaptchaLocation {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
export interface AICaptchaDetectionResult extends CaptchaDetectionResultBase {
|
|
27
|
+
reasoning: string;
|
|
28
|
+
location?: CaptchaLocation | null;
|
|
29
|
+
screenshot?: string;
|
|
30
|
+
screenshotPath?: string;
|
|
31
|
+
suggestions?: string[];
|
|
32
|
+
}
|
|
33
|
+
export interface CaptchaDetectionConfig {
|
|
34
|
+
autoDetectCaptcha?: boolean;
|
|
35
|
+
autoSwitchHeadless?: boolean;
|
|
36
|
+
captchaTimeout?: number;
|
|
37
|
+
defaultHeadless?: boolean;
|
|
38
|
+
askBeforeSwitchBack?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface CaptchaPageInfo {
|
|
41
|
+
url: string;
|
|
42
|
+
title: string;
|
|
43
|
+
bodyText: string;
|
|
44
|
+
hasIframes: boolean;
|
|
45
|
+
suspiciousElements: string[];
|
|
46
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export const CAPTCHA_TYPES = [
|
|
2
|
+
'slider',
|
|
3
|
+
'image',
|
|
4
|
+
'widget',
|
|
5
|
+
'browser_check',
|
|
6
|
+
'page_redirect',
|
|
7
|
+
'url_redirect',
|
|
8
|
+
'text_input',
|
|
9
|
+
'none',
|
|
10
|
+
'unknown',
|
|
11
|
+
];
|
|
12
|
+
export const CAPTCHA_PROVIDER_HINTS = [
|
|
13
|
+
'regional_service',
|
|
14
|
+
'embedded_widget',
|
|
15
|
+
'edge_service',
|
|
16
|
+
'managed_service',
|
|
17
|
+
'external_review',
|
|
18
|
+
'unknown',
|
|
19
|
+
];
|
|
20
|
+
export const LEGACY_CAPTCHA_TYPE_ALIASES = {
|
|
21
|
+
recaptcha: 'widget',
|
|
22
|
+
hcaptcha: 'widget',
|
|
23
|
+
turnstile: 'widget',
|
|
24
|
+
cloudflare: 'browser_check',
|
|
25
|
+
};
|
|
26
|
+
export const LEGACY_CAPTCHA_PROVIDER_HINT_ALIASES = {
|
|
27
|
+
geetest: 'regional_service',
|
|
28
|
+
tencent: 'regional_service',
|
|
29
|
+
aliyun: 'regional_service',
|
|
30
|
+
keycaptcha: 'regional_service',
|
|
31
|
+
yidun: 'regional_service',
|
|
32
|
+
'netease-captcha': 'regional_service',
|
|
33
|
+
recaptcha: 'embedded_widget',
|
|
34
|
+
hcaptcha: 'embedded_widget',
|
|
35
|
+
turnstile: 'embedded_widget',
|
|
36
|
+
cloudflare: 'edge_service',
|
|
37
|
+
akamai: 'edge_service',
|
|
38
|
+
datadome: 'edge_service',
|
|
39
|
+
'perimeter-x': 'edge_service',
|
|
40
|
+
perimeterx: 'edge_service',
|
|
41
|
+
perimeter: 'edge_service',
|
|
42
|
+
'px-captcha': 'edge_service',
|
|
43
|
+
incapsula: 'edge_service',
|
|
44
|
+
distil: 'edge_service',
|
|
45
|
+
'shield-square': 'edge_service',
|
|
46
|
+
arkose: 'managed_service',
|
|
47
|
+
funcaptcha: 'managed_service',
|
|
48
|
+
'friendly-captcha': 'managed_service',
|
|
49
|
+
'iw-captcha': 'managed_service',
|
|
50
|
+
'external-ai-required': 'external_review',
|
|
51
|
+
unknown: 'unknown',
|
|
52
|
+
};
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DeobfuscateBundleSummary, DeobfuscateMappingRule, DeobfuscateSavedArtifact } from '../../types/deobfuscator.js';
|
|
2
2
|
export interface AdvancedDeobfuscateOptions {
|
|
3
3
|
code: string;
|
|
4
4
|
detectOnly?: boolean;
|
|
5
5
|
aggressiveVM?: boolean;
|
|
6
6
|
useASTOptimization?: boolean;
|
|
7
7
|
timeout?: number;
|
|
8
|
+
unpack?: boolean;
|
|
9
|
+
unminify?: boolean;
|
|
10
|
+
jsx?: boolean;
|
|
11
|
+
mangle?: boolean;
|
|
12
|
+
outputDir?: string;
|
|
13
|
+
forceOutput?: boolean;
|
|
14
|
+
includeModuleCode?: boolean;
|
|
15
|
+
maxBundleModules?: number;
|
|
16
|
+
mappings?: DeobfuscateMappingRule[];
|
|
8
17
|
}
|
|
9
18
|
export interface AdvancedDeobfuscateResult {
|
|
10
19
|
code: string;
|
|
@@ -12,6 +21,11 @@ export interface AdvancedDeobfuscateResult {
|
|
|
12
21
|
confidence: number;
|
|
13
22
|
warnings: string[];
|
|
14
23
|
astOptimized?: boolean;
|
|
24
|
+
bundle?: DeobfuscateBundleSummary;
|
|
25
|
+
savedTo?: string;
|
|
26
|
+
savedArtifacts?: DeobfuscateSavedArtifact[];
|
|
27
|
+
engine?: 'webcrack';
|
|
28
|
+
webcrackApplied?: boolean;
|
|
15
29
|
vmDetected?: {
|
|
16
30
|
type: string;
|
|
17
31
|
instructions: number;
|
|
@@ -19,25 +33,6 @@ export interface AdvancedDeobfuscateResult {
|
|
|
19
33
|
};
|
|
20
34
|
}
|
|
21
35
|
export declare class AdvancedDeobfuscator {
|
|
22
|
-
private llm?;
|
|
23
|
-
private vmDeobfuscator;
|
|
24
|
-
constructor(llm?: LLMService);
|
|
25
36
|
deobfuscate(options: AdvancedDeobfuscateOptions): Promise<AdvancedDeobfuscateResult>;
|
|
26
|
-
private detectInvisibleUnicode;
|
|
27
|
-
private decodeInvisibleUnicode;
|
|
28
|
-
private detectControlFlowFlattening;
|
|
29
|
-
private unflattenControlFlow;
|
|
30
|
-
private detectStringArrayRotation;
|
|
31
|
-
private derotateStringArray;
|
|
32
|
-
private detectDeadCodeInjection;
|
|
33
|
-
private removeDeadCode;
|
|
34
|
-
private detectOpaquePredicates;
|
|
35
|
-
private removeOpaquePredicates;
|
|
36
|
-
private llmCleanup;
|
|
37
|
-
private normalizeCode;
|
|
38
|
-
private detectStringEncoding;
|
|
39
|
-
private decodeStrings;
|
|
40
|
-
private applyASTOptimizations;
|
|
41
37
|
private calculateConfidence;
|
|
42
|
-
private estimateCodeComplexity;
|
|
43
38
|
}
|