/** * 批量生成解码映射 - 为每个混淆文件生成 decoded_map.json */ const fs = require('fs'); const path = require('path'); const vm = require('vm'); const baseDir = 'D:/temp/破解/cursorpro-0.4.5'; /** * 从代码中提取解码器并生成映射 */ function generateDecodeMap(code, filename) { console.log(`\n处理: ${filename}`); console.log('='.repeat(40)); // 查找字符串数组函数 const arrayFuncMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\)\s*\{/); if (!arrayFuncMatch) { console.log(' 未找到字符串数组函数'); return null; } const arrayFuncName = arrayFuncMatch[1]; // 查找解码函数 const decoderMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\s*_0x[a-f0-9]+\s*,\s*_0x[a-f0-9]+\s*\)\s*\{/); if (!decoderMatch) { console.log(' 未找到解码函数'); return null; } const decoderFuncName = decoderMatch[1]; console.log(` 数组函数: ${arrayFuncName}`); console.log(` 解码函数: ${decoderFuncName}`); // 提取所有解码器调用模式 const callPatterns = [ /_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/g, /_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*"([^"]*)"\s*\)/g ]; const calls = new Set(); for (const pattern of callPatterns) { let match; while ((match = pattern.exec(code)) !== null) { calls.add(match[0]); } } console.log(` 找到 ${calls.size} 个唯一调用`); // 尝试设置沙盒执行解码器 // 提取从开头到第一个 exports 之前的所有代码 let exportIndex = code.indexOf('Object.defineProperty(exports'); if (exportIndex === -1) { exportIndex = code.indexOf('exports.'); } if (exportIndex === -1) { exportIndex = code.length; } // 找到解码函数结束位置 const decoderStart = code.indexOf(`function ${decoderFuncName}(`); let braceCount = 0, decoderEnd = decoderStart, foundStart = false; for (let i = decoderStart; i < code.length; i++) { if (code[i] === '{') { braceCount++; foundStart = true; } else if (code[i] === '}') { braceCount--; if (foundStart && braceCount === 0) { decoderEnd = i + 1; break; } } } // 提取设置代码 const setupCode = code.substring(0, Math.min(decoderEnd + 500, exportIndex)); // 在沙盒中执行 const sandbox = { console: { log: () => {}, warn: () => {}, error: () => {} }, parseInt, String, decodeURIComponent, vip: 'cursor' }; try { vm.runInNewContext(setupCode, sandbox); // 测试解码器 const testResult = vm.runInNewContext(`typeof ${decoderFuncName}`, sandbox); if (testResult !== 'function') { console.log(` 解码器不可用: ${testResult}`); return null; } console.log(` 解码器设置成功`); // 解码所有调用 const decodeMap = {}; let successCount = 0; let failCount = 0; for (const call of calls) { // 提取参数 const paramMatch = call.match(/_0x[a-f0-9]+\s*\(\s*(0x[a-f0-9]+)\s*,\s*['"]([^'"]*)['"]\s*\)/); if (!paramMatch) continue; const num = paramMatch[1]; const key = paramMatch[2]; try { const decoded = vm.runInNewContext( `${decoderFuncName}(${num},'${key.replace(/'/g, "\\'")}')`, sandbox ); if (typeof decoded === 'string') { decodeMap[call] = decoded; successCount++; } else { failCount++; } } catch (e) { failCount++; } } console.log(` 成功解码: ${successCount}`); console.log(` 解码失败: ${failCount}`); return decodeMap; } catch (e) { console.log(` 沙盒执行失败: ${e.message}`); return null; } } // 主函数 function main() { console.log('╔════════════════════════════════════════╗'); console.log('║ 批量生成解码映射 ║'); console.log('╚════════════════════════════════════════╝'); const files = [ { input: '原版本/extension/out/webview/provider.js', output: 'provider_decoded_map.json' }, { input: '原版本/extension/out/extension.js', output: 'extension_decoded_map.json' }, { input: '原版本/extension/out/utils/account.js', output: 'account_decoded_map.json' }, { input: '原版本/extension/out/utils/sqlite.js', output: 'sqlite_decoded_map.json' }, { input: '原版本/extension/out/api/client.js', output: 'client_decoded_map.json' } ]; for (const file of files) { const inputPath = path.join(baseDir, file.input); const outputPath = path.join(baseDir, file.output); // 检查是否已存在 if (fs.existsSync(outputPath)) { const existing = JSON.parse(fs.readFileSync(outputPath, 'utf8')); console.log(`\n${file.output}: 已存在 (${Object.keys(existing).length} 条)`); continue; } if (!fs.existsSync(inputPath)) { console.log(`\n跳过: ${file.input} (不存在)`); continue; } const code = fs.readFileSync(inputPath, 'utf8'); const decodeMap = generateDecodeMap(code, file.input); if (decodeMap && Object.keys(decodeMap).length > 0) { fs.writeFileSync(outputPath, JSON.stringify(decodeMap, null, 2)); console.log(` 已保存: ${outputPath}`); } else { console.log(` 无法生成映射`); } } console.log('\n完成!'); } main();