deepspider 0.3.0 → 0.3.2
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/.env.example +3 -0
- package/README.md +13 -13
- package/package.json +6 -6
- package/src/agent/core/PanelBridge.js +29 -77
- package/src/agent/core/StreamHandler.js +139 -14
- package/src/agent/index.js +51 -12
- package/src/agent/logger.js +184 -9
- package/src/agent/middleware/report.js +42 -16
- package/src/agent/middleware/subagent.js +233 -0
- package/src/agent/middleware/toolGuard.js +77 -0
- package/src/agent/middleware/validationWorkflow.js +171 -0
- package/src/agent/prompts/system.js +181 -59
- package/src/agent/run.js +41 -6
- package/src/agent/skills/crawler/SKILL.md +64 -3
- package/src/agent/skills/crawler/evolved.md +9 -1
- package/src/agent/skills/dynamic-analysis/SKILL.md +74 -7
- package/src/agent/skills/env/SKILL.md +75 -0
- package/src/agent/skills/evolve.js +0 -3
- package/src/agent/skills/sandbox/SKILL.md +35 -0
- package/src/agent/skills/static-analysis/SKILL.md +98 -2
- package/src/agent/subagents/anti-detect.js +10 -20
- package/src/agent/subagents/captcha.js +7 -19
- package/src/agent/subagents/crawler.js +25 -37
- package/src/agent/subagents/factory.js +109 -9
- package/src/agent/subagents/index.js +4 -13
- package/src/agent/subagents/js2python.js +7 -19
- package/src/agent/subagents/reverse.js +180 -0
- package/src/agent/tools/analysis.js +84 -1
- package/src/agent/tools/anti-detect.js +5 -2
- package/src/agent/tools/browser.js +160 -0
- package/src/agent/tools/captcha.js +1 -1
- package/src/agent/tools/capture.js +24 -3
- package/src/agent/tools/correlate.js +129 -15
- package/src/agent/tools/crawler.js +2 -1
- package/src/agent/tools/crawlerGenerator.js +90 -0
- package/src/agent/tools/debug.js +43 -6
- package/src/agent/tools/evolve.js +6 -3
- package/src/agent/tools/extractor.js +5 -1
- package/src/agent/tools/file.js +16 -7
- package/src/agent/tools/generateHook.js +66 -0
- package/src/agent/tools/hookManager.js +19 -9
- package/src/agent/tools/index.js +33 -20
- package/src/agent/tools/nodejs.js +41 -6
- package/src/agent/tools/python.js +4 -4
- package/src/agent/tools/report.js +2 -2
- package/src/agent/tools/runtime.js +1 -1
- package/src/agent/tools/sandbox.js +21 -1
- package/src/agent/tools/scratchpad.js +70 -0
- package/src/agent/tools/tracing.js +26 -0
- package/src/agent/tools/verifyAlgorithm.js +117 -0
- package/src/analyzer/EncryptionAnalyzer.js +2 -2
- package/src/browser/EnvBridge.js +27 -13
- package/src/browser/client.js +124 -18
- package/src/browser/collector.js +101 -22
- package/src/browser/defaultHooks.js +3 -1
- package/src/browser/hooks/index.js +5 -0
- package/src/browser/interceptors/AntiDebugInterceptor.js +132 -0
- package/src/browser/interceptors/NetworkInterceptor.js +77 -13
- package/src/browser/interceptors/ScriptInterceptor.js +34 -9
- package/src/browser/interceptors/index.js +1 -0
- package/src/browser/ui/analysisPanel.js +469 -464
- package/src/cli/commands/config.js +11 -3
- package/src/config/paths.js +9 -1
- package/src/config/settings.js +7 -1
- package/src/core/PatchGenerator.js +26 -6
- package/src/core/Sandbox.js +140 -3
- package/src/env/EnvCodeGenerator.js +60 -88
- package/src/env/modules/bom/history.js +6 -0
- package/src/env/modules/bom/location.js +6 -0
- package/src/env/modules/bom/navigator.js +13 -0
- package/src/env/modules/bom/screen.js +6 -0
- package/src/env/modules/bom/storage.js +7 -0
- package/src/env/modules/dom/document.js +14 -0
- package/src/env/modules/dom/event.js +4 -0
- package/src/env/modules/index.js +27 -10
- package/src/env/modules/webapi/fetch.js +4 -0
- package/src/env/modules/webapi/url.js +4 -0
- package/src/env/modules/webapi/xhr.js +8 -0
- package/src/store/DataStore.js +130 -47
- package/src/store/Store.js +2 -1
- package/src/agent/subagents/dynamic.js +0 -64
- package/src/agent/subagents/env-agent.js +0 -82
- package/src/agent/subagents/sandbox.js +0 -55
- package/src/agent/subagents/static.js +0 -66
package/src/env/modules/index.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* DeepSpider - 环境模块索引
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { navigatorCode } from './bom/navigator.js';
|
|
6
|
-
import { locationCode } from './bom/location.js';
|
|
7
|
-
import { screenCode } from './bom/screen.js';
|
|
8
|
-
import { historyCode } from './bom/history.js';
|
|
9
|
-
import { storageCode } from './bom/storage.js';
|
|
10
|
-
import { documentCode } from './dom/document.js';
|
|
11
|
-
import { eventCode } from './dom/event.js';
|
|
12
|
-
import { fetchCode } from './webapi/fetch.js';
|
|
13
|
-
import { xhrCode } from './webapi/xhr.js';
|
|
14
|
-
import { urlCode } from './webapi/url.js';
|
|
5
|
+
import { navigatorCode, navigatorCovers } from './bom/navigator.js';
|
|
6
|
+
import { locationCode, locationCovers } from './bom/location.js';
|
|
7
|
+
import { screenCode, screenCovers } from './bom/screen.js';
|
|
8
|
+
import { historyCode, historyCovers } from './bom/history.js';
|
|
9
|
+
import { storageCode, storageCovers } from './bom/storage.js';
|
|
10
|
+
import { documentCode, documentCovers } from './dom/document.js';
|
|
11
|
+
import { eventCode, eventCovers } from './dom/event.js';
|
|
12
|
+
import { fetchCode, fetchCovers } from './webapi/fetch.js';
|
|
13
|
+
import { xhrCode, xhrCovers } from './webapi/xhr.js';
|
|
14
|
+
import { urlCode, urlCovers } from './webapi/url.js';
|
|
15
15
|
|
|
16
16
|
export const modules = {
|
|
17
17
|
navigator: navigatorCode,
|
|
@@ -31,4 +31,21 @@ export const loadOrder = [
|
|
|
31
31
|
'screen', 'history', 'storage', 'url', 'fetch', 'xhr'
|
|
32
32
|
];
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* 所有预置模块覆盖的 API 集合
|
|
36
|
+
* 供 PatchGenerator 查询:已有模块覆盖的属性不需要生成低质量 template 补丁
|
|
37
|
+
*/
|
|
38
|
+
export const coveredAPIs = new Set([
|
|
39
|
+
...navigatorCovers,
|
|
40
|
+
...locationCovers,
|
|
41
|
+
...screenCovers,
|
|
42
|
+
...historyCovers,
|
|
43
|
+
...storageCovers,
|
|
44
|
+
...documentCovers,
|
|
45
|
+
...eventCovers,
|
|
46
|
+
...fetchCovers,
|
|
47
|
+
...xhrCovers,
|
|
48
|
+
...urlCovers,
|
|
49
|
+
]);
|
|
50
|
+
|
|
34
51
|
export default modules;
|
|
@@ -45,4 +45,12 @@ export const xhrCode = `
|
|
|
45
45
|
})();
|
|
46
46
|
`;
|
|
47
47
|
|
|
48
|
+
export const xhrCovers = [
|
|
49
|
+
'XMLHttpRequest', 'XMLHttpRequest.prototype.open',
|
|
50
|
+
'XMLHttpRequest.prototype.send', 'XMLHttpRequest.prototype.abort',
|
|
51
|
+
'XMLHttpRequest.prototype.setRequestHeader',
|
|
52
|
+
'XMLHttpRequest.prototype.getResponseHeader',
|
|
53
|
+
'XMLHttpRequest.prototype.getAllResponseHeaders',
|
|
54
|
+
];
|
|
55
|
+
|
|
48
56
|
export default xhrCode;
|
package/src/store/DataStore.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* 支持会话隔离、内容去重、自动清理
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import { writeFile, readFile,
|
|
7
|
+
import { existsSync, readFileSync } from 'fs';
|
|
8
|
+
import { writeFile, readFile, rm } from 'fs/promises';
|
|
9
9
|
import { join } from 'path';
|
|
10
10
|
import { createHash } from 'crypto';
|
|
11
11
|
import { PATHS, ensureDir } from '../config/paths.js';
|
|
@@ -128,12 +128,68 @@ export class DataStore {
|
|
|
128
128
|
this.sessionId = null;
|
|
129
129
|
// 上次清理时间
|
|
130
130
|
this.lastCleanup = 0;
|
|
131
|
+
// 文件锁:防止并发写入同一站点索引
|
|
132
|
+
this.siteLocks = new Map();
|
|
131
133
|
|
|
132
134
|
ensureDir(DATA_DIR);
|
|
133
135
|
ensureDir(SITES_DIR);
|
|
134
136
|
this.loadGlobalIndex();
|
|
135
137
|
}
|
|
136
138
|
|
|
139
|
+
/**
|
|
140
|
+
* 获取站点锁(带超时和队列)
|
|
141
|
+
*/
|
|
142
|
+
async acquireLock(site, timeout = 30000) {
|
|
143
|
+
// 初始化该站点的锁队列
|
|
144
|
+
if (!this.siteLocks.has(site)) {
|
|
145
|
+
this.siteLocks.set(site, { locked: false, queue: [] });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const lockState = this.siteLocks.get(site);
|
|
149
|
+
|
|
150
|
+
// 如果当前未锁定,直接获取锁
|
|
151
|
+
if (!lockState.locked) {
|
|
152
|
+
lockState.locked = true;
|
|
153
|
+
let released = false;
|
|
154
|
+
return () => {
|
|
155
|
+
if (released) return;
|
|
156
|
+
released = true;
|
|
157
|
+
lockState.locked = false;
|
|
158
|
+
// 唤醒队列中的下一个
|
|
159
|
+
const next = lockState.queue.shift();
|
|
160
|
+
if (next) next.resolve();
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// 当前已锁定,加入等待队列
|
|
165
|
+
return new Promise((resolve, reject) => {
|
|
166
|
+
const id = Date.now().toString(36) + Math.random().toString(36).slice(2, 5);
|
|
167
|
+
const timer = setTimeout(() => {
|
|
168
|
+
// 从队列中移除
|
|
169
|
+
const idx = lockState.queue.findIndex(item => item.id === id);
|
|
170
|
+
if (idx > -1) lockState.queue.splice(idx, 1);
|
|
171
|
+
reject(new Error(`获取站点 ${site} 的锁超时`));
|
|
172
|
+
}, timeout);
|
|
173
|
+
|
|
174
|
+
lockState.queue.push({
|
|
175
|
+
id,
|
|
176
|
+
resolve: () => {
|
|
177
|
+
clearTimeout(timer);
|
|
178
|
+
lockState.locked = true;
|
|
179
|
+
let released = false;
|
|
180
|
+
resolve(() => {
|
|
181
|
+
if (released) return;
|
|
182
|
+
released = true;
|
|
183
|
+
lockState.locked = false;
|
|
184
|
+
// 唤醒队列中的下一个
|
|
185
|
+
const next = lockState.queue.shift();
|
|
186
|
+
if (next) next.resolve();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
137
193
|
/**
|
|
138
194
|
* 创建新会话
|
|
139
195
|
*/
|
|
@@ -201,7 +257,7 @@ export class DataStore {
|
|
|
201
257
|
if (existsSync(indexFile)) {
|
|
202
258
|
index = JSON.parse(readFileSync(indexFile, 'utf-8'));
|
|
203
259
|
}
|
|
204
|
-
} catch
|
|
260
|
+
} catch {
|
|
205
261
|
// 使用默认索引
|
|
206
262
|
}
|
|
207
263
|
|
|
@@ -241,61 +297,87 @@ export class DataStore {
|
|
|
241
297
|
this.globalIndex.sites.push(stats);
|
|
242
298
|
}
|
|
243
299
|
|
|
244
|
-
this.saveGlobalIndex()
|
|
300
|
+
await this.saveGlobalIndex();
|
|
245
301
|
}
|
|
246
302
|
|
|
247
303
|
/**
|
|
248
|
-
*
|
|
304
|
+
* 保存响应数据(带去重,带锁防止竞态条件)
|
|
249
305
|
*/
|
|
250
306
|
async saveResponse(data) {
|
|
251
|
-
const { url, method, status, requestHeaders, requestBody, responseBody, timestamp, pageUrl } = data;
|
|
307
|
+
const { url, method, status, requestHeaders, requestBody, responseBody, timestamp, pageUrl, initiator } = data;
|
|
252
308
|
const { site, path } = parseUrl(pageUrl || url);
|
|
253
309
|
|
|
254
|
-
//
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// 检查是否已存在相同内容
|
|
259
|
-
const existing = index.responses.find(r => r.hash === hash);
|
|
260
|
-
if (existing) {
|
|
261
|
-
// 更新时间戳和会话,不重复存储
|
|
262
|
-
existing.timestamp = timestamp || Date.now();
|
|
263
|
-
existing.sessionId = this.getSessionId();
|
|
264
|
-
await this.saveSiteIndex(site);
|
|
265
|
-
return { id: existing.id, site, path, deduplicated: true };
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const siteDir = this.getSiteDir(site);
|
|
269
|
-
const responsesDir = join(siteDir, 'responses', path);
|
|
270
|
-
ensureDir(responsesDir);
|
|
271
|
-
|
|
272
|
-
// 生成可读文件名
|
|
273
|
-
const readableName = getReadableFilename(url, 'response', method);
|
|
274
|
-
const seq = String(index.responses.length).padStart(3, '0');
|
|
275
|
-
const id = `${readableName}_${seq}`;
|
|
276
|
-
const file = join(responsesDir, `${id}.json`);
|
|
310
|
+
// 获取站点锁,防止并发写入
|
|
311
|
+
const releaseLock = await this.acquireLock(site);
|
|
312
|
+
let result;
|
|
277
313
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
pageUrl, timestamp
|
|
282
|
-
});
|
|
314
|
+
try {
|
|
315
|
+
// 生成去重 hash
|
|
316
|
+
const hash = requestHash(url, method, requestBody);
|
|
283
317
|
|
|
284
|
-
|
|
318
|
+
// 重新加载索引(获取最新状态)
|
|
319
|
+
this.siteIndexCache.delete(site);
|
|
320
|
+
const index = await this.getSiteIndex(site);
|
|
285
321
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
322
|
+
// 检查是否已存在相同内容
|
|
323
|
+
const existing = index.responses.find(r => r.hash === hash);
|
|
324
|
+
if (existing) {
|
|
325
|
+
// 更新时间戳和会话,不重复存储
|
|
326
|
+
existing.timestamp = timestamp || Date.now();
|
|
327
|
+
existing.sessionId = this.getSessionId();
|
|
328
|
+
// 更新 initiator(不同代码路径可能调用同一 API)
|
|
329
|
+
if (initiator) {
|
|
330
|
+
existing.hasInitiator = true;
|
|
331
|
+
// 同步更新详情文件中的 initiator
|
|
332
|
+
try {
|
|
333
|
+
const detail = JSON.parse(await readFile(existing.file, 'utf-8'));
|
|
334
|
+
detail.initiator = initiator;
|
|
335
|
+
await writeFile(existing.file, JSON.stringify(detail));
|
|
336
|
+
} catch { /* 文件读写失败不影响主流程 */ }
|
|
337
|
+
}
|
|
338
|
+
await this.saveSiteIndex(site);
|
|
339
|
+
result = { id: existing.id, site, path, deduplicated: true };
|
|
340
|
+
} else {
|
|
341
|
+
const siteDir = this.getSiteDir(site);
|
|
342
|
+
const responsesDir = join(siteDir, 'responses', path);
|
|
343
|
+
ensureDir(responsesDir);
|
|
344
|
+
|
|
345
|
+
// 生成可读文件名(使用当前索引长度作为序号)
|
|
346
|
+
const readableName = getReadableFilename(url, 'response', method);
|
|
347
|
+
const seq = String(index.responses.length).padStart(3, '0');
|
|
348
|
+
const id = `${readableName}_${seq}`;
|
|
349
|
+
const file = join(responsesDir, `${id}.json`);
|
|
350
|
+
|
|
351
|
+
const content = JSON.stringify({
|
|
352
|
+
url, method, status,
|
|
353
|
+
requestHeaders, requestBody, responseBody,
|
|
354
|
+
pageUrl, timestamp, initiator,
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
await writeFile(file, content);
|
|
358
|
+
|
|
359
|
+
index.responses.push({
|
|
360
|
+
id, url, path, method, status,
|
|
361
|
+
timestamp: timestamp || Date.now(),
|
|
362
|
+
file, size: content.length,
|
|
363
|
+
hash, hasInitiator: !!initiator,
|
|
364
|
+
sessionId: this.getSessionId()
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
await this.saveSiteIndex(site);
|
|
368
|
+
result = { id, site, path };
|
|
369
|
+
}
|
|
370
|
+
} finally {
|
|
371
|
+
// 确保锁被释放
|
|
372
|
+
releaseLock();
|
|
373
|
+
}
|
|
293
374
|
|
|
294
|
-
|
|
295
|
-
|
|
375
|
+
if (!result.deduplicated) {
|
|
376
|
+
await this.updateSiteStats(site);
|
|
377
|
+
}
|
|
296
378
|
this.maybeCleanup();
|
|
297
379
|
|
|
298
|
-
return
|
|
380
|
+
return result;
|
|
299
381
|
}
|
|
300
382
|
|
|
301
383
|
/**
|
|
@@ -374,6 +456,7 @@ export class DataStore {
|
|
|
374
456
|
id: r.id, url: r.url, path: r.path,
|
|
375
457
|
method: r.method, status: r.status,
|
|
376
458
|
timestamp: r.timestamp, size: r.size,
|
|
459
|
+
hasInitiator: !!r.hasInitiator,
|
|
377
460
|
sessionId: r.sessionId
|
|
378
461
|
}));
|
|
379
462
|
}
|
|
@@ -446,7 +529,7 @@ export class DataStore {
|
|
|
446
529
|
timestamp: meta.timestamp
|
|
447
530
|
});
|
|
448
531
|
}
|
|
449
|
-
} catch
|
|
532
|
+
} catch { /* skip */ }
|
|
450
533
|
}
|
|
451
534
|
}
|
|
452
535
|
return results;
|
|
@@ -477,7 +560,7 @@ export class DataStore {
|
|
|
477
560
|
timestamp: meta.timestamp
|
|
478
561
|
});
|
|
479
562
|
}
|
|
480
|
-
} catch
|
|
563
|
+
} catch { /* skip */ }
|
|
481
564
|
}
|
|
482
565
|
}
|
|
483
566
|
return results;
|
package/src/store/Store.js
CHANGED
|
@@ -37,7 +37,8 @@ export class Store {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
_getFilePath(type, name) {
|
|
40
|
-
const
|
|
40
|
+
const safeType = type.replace(/[^a-zA-Z0-9_.-]/g, '_');
|
|
41
|
+
const typeDir = path.join(this.baseDir, safeType);
|
|
41
42
|
if (!fs.existsSync(typeDir)) {
|
|
42
43
|
fs.mkdirSync(typeDir, { recursive: true });
|
|
43
44
|
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DeepSpider - 动态分析子代理
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createSkillsMiddleware } from 'deepagents';
|
|
6
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
7
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
8
|
-
|
|
9
|
-
import { runtimeTools } from '../tools/runtime.js';
|
|
10
|
-
import { debugTools } from '../tools/debug.js';
|
|
11
|
-
import { captureTools } from '../tools/capture.js';
|
|
12
|
-
import { browserTools } from '../tools/browser.js';
|
|
13
|
-
import { cryptoHookTools } from '../tools/cryptohook.js';
|
|
14
|
-
import { correlateTools } from '../tools/correlate.js';
|
|
15
|
-
import { tracingTools } from '../tools/tracing.js';
|
|
16
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
17
|
-
|
|
18
|
-
export const dynamicSubagent = {
|
|
19
|
-
name: 'dynamic-agent',
|
|
20
|
-
description: '动态分析专家。当需要在浏览器中调试分析时使用,适用于:设置断点捕获运行时数据、分析请求与加密的关联、采集真实环境数据。',
|
|
21
|
-
systemPrompt: `你是 DeepSpider 的动态分析专家。
|
|
22
|
-
|
|
23
|
-
## 职责
|
|
24
|
-
- 控制浏览器执行
|
|
25
|
-
- 设置断点捕获运行时数据
|
|
26
|
-
- 采集真实环境数据
|
|
27
|
-
- 收集 Hook 日志
|
|
28
|
-
- 分析请求与加密的关联
|
|
29
|
-
|
|
30
|
-
## 浏览器状态检查
|
|
31
|
-
**在执行任何操作前,先判断浏览器状态:**
|
|
32
|
-
- 如果任务描述中包含"浏览器已就绪"等关键词,不要调用 launch_browser
|
|
33
|
-
- 先使用 get_hook_logs 检查是否有数据
|
|
34
|
-
- 只有确认浏览器未启动时,才执行启动流程
|
|
35
|
-
|
|
36
|
-
## 工作流程
|
|
37
|
-
1. 检查浏览器状态
|
|
38
|
-
2. 如需启动:launch_browser → navigate_to
|
|
39
|
-
3. 等待 Hook 捕获加密调用
|
|
40
|
-
4. 分析请求与加密的关联
|
|
41
|
-
5. 必要时设置断点深入分析
|
|
42
|
-
6. 采集环境数据
|
|
43
|
-
|
|
44
|
-
## 经验记录
|
|
45
|
-
完成分析后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
46
|
-
- skill: "dynamic-analysis"`,
|
|
47
|
-
tools: [
|
|
48
|
-
...runtimeTools,
|
|
49
|
-
...debugTools,
|
|
50
|
-
...captureTools,
|
|
51
|
-
...browserTools,
|
|
52
|
-
...cryptoHookTools,
|
|
53
|
-
...correlateTools,
|
|
54
|
-
...tracingTools,
|
|
55
|
-
...evolveTools,
|
|
56
|
-
],
|
|
57
|
-
middleware: [
|
|
58
|
-
createFilterToolsMiddleware(),
|
|
59
|
-
createSkillsMiddleware({
|
|
60
|
-
backend: skillsBackend,
|
|
61
|
-
sources: [SKILLS.dynamic],
|
|
62
|
-
}),
|
|
63
|
-
],
|
|
64
|
-
};
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DeepSpider - 补环境子代理
|
|
3
|
-
* 方向:通过补全浏览器环境让代码直接运行
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { createSkillsMiddleware } from 'deepagents';
|
|
7
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
8
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
9
|
-
|
|
10
|
-
import { sandboxTools } from '../tools/sandbox.js';
|
|
11
|
-
import { nodejsTools } from '../tools/nodejs.js';
|
|
12
|
-
import { envDumpTools } from '../tools/envdump.js';
|
|
13
|
-
import { extractTools } from '../tools/extract.js';
|
|
14
|
-
import { patchTools } from '../tools/patch.js';
|
|
15
|
-
import { envTools } from '../tools/env.js';
|
|
16
|
-
import { profileTools } from '../tools/profile.js';
|
|
17
|
-
import { storeTools } from '../tools/store.js';
|
|
18
|
-
import { hookTools } from '../tools/hook.js';
|
|
19
|
-
import { antiDebugTools } from '../tools/antidebug.js';
|
|
20
|
-
import { asyncTools } from '../tools/async.js';
|
|
21
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
22
|
-
|
|
23
|
-
export const envAgentSubagent = {
|
|
24
|
-
name: 'env-agent',
|
|
25
|
-
description: '补环境专家。当需要让混淆代码在沙箱中直接运行时使用,适用于:环境检测多、算法复杂难还原、需要快速获取结果的场景。',
|
|
26
|
-
systemPrompt: `你是 DeepSpider 的补环境专家。
|
|
27
|
-
|
|
28
|
-
## 分析方向
|
|
29
|
-
补环境是 JS 逆向的黑盒方向,目标是让混淆代码在沙箱中直接运行,无需理解算法逻辑。
|
|
30
|
-
|
|
31
|
-
## 核心流程
|
|
32
|
-
1. **环境自吐** - 发现代码访问了哪些环境
|
|
33
|
-
2. **浏览器提取** - 从真实浏览器获取环境值
|
|
34
|
-
3. **生成补丁** - 转换为可注入的代码
|
|
35
|
-
4. **沙箱执行** - 运行并获取结果
|
|
36
|
-
|
|
37
|
-
## 判断标准
|
|
38
|
-
适合补环境的场景:
|
|
39
|
-
- 环境检测多(webdriver、chrome对象等)
|
|
40
|
-
- 算法复杂难以还原
|
|
41
|
-
- 需要快速获取结果
|
|
42
|
-
- 代码频繁更新
|
|
43
|
-
|
|
44
|
-
## 快速模式
|
|
45
|
-
如果只需快速验证代码能否运行:
|
|
46
|
-
1. list_env_modules 查看预置模块
|
|
47
|
-
2. load_all_env_modules 加载全部
|
|
48
|
-
3. sandbox_inject 注入
|
|
49
|
-
4. sandbox_execute 执行
|
|
50
|
-
|
|
51
|
-
## 执行工具选择
|
|
52
|
-
- sandbox_execute: 隔离沙箱,适合补环境后的代码执行
|
|
53
|
-
- run_node_code: Node.js 执行,适合需要 require npm 包的场景
|
|
54
|
-
|
|
55
|
-
## 失败处理
|
|
56
|
-
如果补环境多次失败,建议切换到纯算分析方向。
|
|
57
|
-
|
|
58
|
-
## 经验记录
|
|
59
|
-
完成分析后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
60
|
-
- skill: "env"`,
|
|
61
|
-
tools: [
|
|
62
|
-
...sandboxTools,
|
|
63
|
-
...nodejsTools,
|
|
64
|
-
...envDumpTools,
|
|
65
|
-
...extractTools,
|
|
66
|
-
...patchTools,
|
|
67
|
-
...envTools,
|
|
68
|
-
...profileTools,
|
|
69
|
-
...hookTools,
|
|
70
|
-
...antiDebugTools,
|
|
71
|
-
...asyncTools,
|
|
72
|
-
...storeTools,
|
|
73
|
-
...evolveTools,
|
|
74
|
-
],
|
|
75
|
-
middleware: [
|
|
76
|
-
createFilterToolsMiddleware(),
|
|
77
|
-
createSkillsMiddleware({
|
|
78
|
-
backend: skillsBackend,
|
|
79
|
-
sources: [SKILLS.env],
|
|
80
|
-
}),
|
|
81
|
-
],
|
|
82
|
-
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DeepSpider - 沙箱验证子代理
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createSkillsMiddleware } from 'deepagents';
|
|
6
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
7
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
8
|
-
|
|
9
|
-
import { sandboxTools } from '../tools/sandbox.js';
|
|
10
|
-
import { nodejsTools } from '../tools/nodejs.js';
|
|
11
|
-
import { patchTools } from '../tools/patch.js';
|
|
12
|
-
import { envTools } from '../tools/env.js';
|
|
13
|
-
import { verifyTools } from '../tools/verify.js';
|
|
14
|
-
import { fileTools } from '../tools/file.js';
|
|
15
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
16
|
-
|
|
17
|
-
export const sandboxSubagent = {
|
|
18
|
-
name: 'sandbox-agent',
|
|
19
|
-
description: '沙箱验证专家。当需要验证提取的代码能否正确执行时使用,适用于:验证加密算法、补全缺失环境、生成可独立运行的脚本。',
|
|
20
|
-
systemPrompt: `你是 DeepSpider 的验证执行专家。
|
|
21
|
-
|
|
22
|
-
## 职责
|
|
23
|
-
- 在沙箱中验证提取的加密算法
|
|
24
|
-
- 补全缺失的环境
|
|
25
|
-
- 生成可独立运行的脚本
|
|
26
|
-
- 验证加密结果是否正确
|
|
27
|
-
|
|
28
|
-
## 执行工具选择
|
|
29
|
-
- sandbox_execute: 隔离沙箱,适合不需要外部依赖的代码
|
|
30
|
-
- run_node_code: Node.js 执行,适合需要 require npm 包的代码(如 crypto-js)
|
|
31
|
-
|
|
32
|
-
## 输出
|
|
33
|
-
- 验证结果
|
|
34
|
-
- 可执行的 JS 模块
|
|
35
|
-
|
|
36
|
-
## 经验记录
|
|
37
|
-
完成验证后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
38
|
-
- skill: "sandbox"`,
|
|
39
|
-
tools: [
|
|
40
|
-
...sandboxTools,
|
|
41
|
-
...nodejsTools,
|
|
42
|
-
...patchTools,
|
|
43
|
-
...envTools,
|
|
44
|
-
...verifyTools,
|
|
45
|
-
...fileTools,
|
|
46
|
-
...evolveTools,
|
|
47
|
-
],
|
|
48
|
-
middleware: [
|
|
49
|
-
createFilterToolsMiddleware(),
|
|
50
|
-
createSkillsMiddleware({
|
|
51
|
-
backend: skillsBackend,
|
|
52
|
-
sources: [SKILLS.sandbox],
|
|
53
|
-
}),
|
|
54
|
-
],
|
|
55
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DeepSpider - 静态分析子代理
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { createSkillsMiddleware } from 'deepagents';
|
|
6
|
-
import { SKILLS, skillsBackend } from '../skills/config.js';
|
|
7
|
-
import { createFilterToolsMiddleware } from '../middleware/filterTools.js';
|
|
8
|
-
|
|
9
|
-
import { analyzerTools } from '../tools/analyzer.js';
|
|
10
|
-
import { deobfuscatorTools } from '../tools/deobfuscator.js';
|
|
11
|
-
import { traceTools } from '../tools/trace.js';
|
|
12
|
-
import { webcrackTools } from '../tools/webcrack.js';
|
|
13
|
-
import { preprocessTools } from '../tools/preprocess.js';
|
|
14
|
-
import { extractorTools } from '../tools/extractor.js';
|
|
15
|
-
import { storeTools } from '../tools/store.js';
|
|
16
|
-
import { verifyTools } from '../tools/verify.js';
|
|
17
|
-
import { correlateTools } from '../tools/correlate.js';
|
|
18
|
-
import { evolveTools } from '../tools/evolve.js';
|
|
19
|
-
|
|
20
|
-
export const staticSubagent = {
|
|
21
|
-
name: 'static-agent',
|
|
22
|
-
description: '静态代码分析专家。当需要分析混淆代码、还原加密算法时使用,适用于:Webpack解包、反混淆、定位加密入口、算法还原验证。',
|
|
23
|
-
systemPrompt: `你是 DeepSpider 的静态分析专家。
|
|
24
|
-
|
|
25
|
-
## 职责
|
|
26
|
-
- 预处理打包代码(Webpack/Vite/Rollup)
|
|
27
|
-
- 反混淆处理
|
|
28
|
-
- 定位加密函数入口
|
|
29
|
-
- 还原算法逻辑
|
|
30
|
-
- 验证算法正确性
|
|
31
|
-
|
|
32
|
-
## 工作流程
|
|
33
|
-
1. preprocess_code 预处理
|
|
34
|
-
2. 如有 bundle 则解包
|
|
35
|
-
3. deobfuscate 反混淆
|
|
36
|
-
4. analyze_encryption 定位入口
|
|
37
|
-
5. 验证算法
|
|
38
|
-
|
|
39
|
-
## 输出
|
|
40
|
-
- 加密函数位置
|
|
41
|
-
- 断点建议
|
|
42
|
-
- 算法分析结果
|
|
43
|
-
|
|
44
|
-
## 经验记录
|
|
45
|
-
完成分析后,如发现有价值的经验,使用 evolve_skill 记录:
|
|
46
|
-
- skill: "static-analysis"`,
|
|
47
|
-
tools: [
|
|
48
|
-
...preprocessTools,
|
|
49
|
-
...webcrackTools,
|
|
50
|
-
...analyzerTools,
|
|
51
|
-
...deobfuscatorTools,
|
|
52
|
-
...traceTools,
|
|
53
|
-
...extractorTools,
|
|
54
|
-
...verifyTools,
|
|
55
|
-
...correlateTools,
|
|
56
|
-
...storeTools,
|
|
57
|
-
...evolveTools,
|
|
58
|
-
],
|
|
59
|
-
middleware: [
|
|
60
|
-
createFilterToolsMiddleware(),
|
|
61
|
-
createSkillsMiddleware({
|
|
62
|
-
backend: skillsBackend,
|
|
63
|
-
sources: [SKILLS.static],
|
|
64
|
-
}),
|
|
65
|
-
],
|
|
66
|
-
};
|