const fs = require('fs'); const vm = require('vm'); // 读取原始 provider.js const code = fs.readFileSync('D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/webview/provider.js', 'utf8'); console.log('文件大小:', code.length, '字节'); // 找到 _0x4ff4 函数的位置 const arrayFuncStart = code.indexOf('function _0x4ff4(){'); if (arrayFuncStart === -1) { console.error('找不到 _0x4ff4 函数'); process.exit(1); } // 找到函数结束位置 let braceCount2 = 0; let arrayFuncEnd = arrayFuncStart; let foundStart2 = false; for (let i = arrayFuncStart; i < code.length; i++) { if (code[i] === '{') { braceCount2++; foundStart2 = true; } else if (code[i] === '}') { braceCount2--; if (foundStart2 && braceCount2 === 0) { arrayFuncEnd = i + 1; break; } } } const arrayFunc = code.substring(arrayFuncStart, arrayFuncEnd); console.log('1. 字符串数组函数已提取, 长度:', arrayFunc.length); // 提取解码函数 _0x56bd const decoderStart = code.indexOf('function _0x56bd('); if (decoderStart === -1) { console.error('找不到 _0x56bd 函数'); process.exit(1); } // 找到函数结束位置 let braceCount = 0; let decoderEnd = decoderStart; let 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 decoderFunc = code.substring(decoderStart, decoderEnd); console.log('2. 解码函数已提取'); // 提取 IIFE(用于打乱数组)- 在 _0x4ff4 函数之后 const iifeStart = code.indexOf('(function(_0x', arrayFuncEnd); if (iifeStart === -1) { console.error('找不到 IIFE'); process.exit(1); } // 找到 IIFE 结束 - 寻找 (_0x4ff4,0x 模式 let iifeEnd = code.indexOf('));', iifeStart); if (iifeEnd === -1) { console.error('找不到 IIFE 结束'); process.exit(1); } iifeEnd += 3; // 包含 )); const iifeCode = code.substring(iifeStart, iifeEnd); console.log('3. IIFE 已提取, 长度:', iifeCode.length); // 在沙盒中执行 const sandbox = {}; const setupCode = ` ${arrayFunc} ${decoderFunc} ${iifeCode} `; try { vm.runInNewContext(setupCode, sandbox); // 将函数添加到沙盒 vm.runInNewContext(` globalThis._0x4ff4 = _0x4ff4; globalThis._0x56bd = _0x56bd; `, sandbox); } catch (e) { console.error('执行初始化代码失败:', e.message); process.exit(1); } console.log('4. 沙盒环境已建立'); // 创建解码映射 const decodeMap = {}; let decodedCount = 0; // 查找所有调用模式: _0x56bd(0x123,'xxxx') 或 _0xa6d6ac(0x123,'xxxx') const callPattern = /(_0x56bd|_0xa6d6ac)\((0x[a-f0-9]+),\s*'([^']+)'\)/g; let match; while ((match = callPattern.exec(code)) !== null) { const fullMatch = match[0]; const num = parseInt(match[2], 16); const key = match[3]; if (!decodeMap[fullMatch]) { try { const decoded = vm.runInNewContext(`_0x56bd(${num},'${key}')`, sandbox); if (typeof decoded === 'string') { decodeMap[fullMatch] = decoded; decodedCount++; } } catch (e) { // 忽略错误 } } } console.log('5. 已解码', decodedCount, '个字符串'); // 替换代码中的加密调用 let deobfuscated = code; // 按长度降序排序,避免部分替换问题 const sortedEntries = Object.entries(decodeMap).sort((a, b) => b[0].length - a[0].length); for (const [encrypted, decrypted] of sortedEntries) { // 转义特殊字符 const escaped = encrypted.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(escaped, 'g'); // 根据内容选择合适的引号 let replacement; if (decrypted.includes("'") && !decrypted.includes('"')) { replacement = JSON.stringify(decrypted); } else if (decrypted.includes('"') && !decrypted.includes("'")) { replacement = `'${decrypted}'`; } else if (decrypted.includes("'") && decrypted.includes('"')) { replacement = JSON.stringify(decrypted); } else { replacement = `'${decrypted}'`; } deobfuscated = deobfuscated.replace(regex, replacement); } console.log('6. 字符串替换完成'); // 移除解码函数定义和 IIFE deobfuscated = deobfuscated.replace(arrayFunc, '// [STRING ARRAY REMOVED]'); deobfuscated = deobfuscated.replace(decoderFunc, '// [DECODER REMOVED]'); deobfuscated = deobfuscated.replace(iifeCode, '// [IIFE REMOVED]'); // 移除别名定义 deobfuscated = deobfuscated.replace(/var _0xa6d6ac=_0x56bd;?/g, '// [ALIAS REMOVED]'); console.log('7. 清理完成'); // 保存反混淆后的代码 const outputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated/provider/provider.js'; fs.mkdirSync('D:/temp/破解/cursorpro-0.4.5/deobfuscated/provider', { recursive: true }); fs.writeFileSync(outputPath, deobfuscated); console.log('8. 已保存到:', outputPath); // 输出一些关键字符串 console.log('\n=== 关键 API 字符串 ==='); const apiStrings = Object.entries(decodeMap).filter(([k, v]) => v.includes('cursor') || v.includes('api') || v.includes('http') || v.includes('verify') ); apiStrings.slice(0, 30).forEach(([k, v]) => { if (v.length < 100) console.log(v); });