/** * 动态反混淆 provider.js v3 * 使用 vm 沙盒执行解码器 */ const fs = require('fs'); const path = require('path'); const vm = require('vm'); const inputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider_clean.js'; const outputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider.js'; console.log('╔════════════════════════════════════════════════════╗'); console.log('║ Provider.js 动态反混淆工具 v3 ║'); console.log('╚════════════════════════════════════════════════════╝'); let code = fs.readFileSync(inputPath, 'utf8'); console.log(`读取文件: ${(code.length / 1024).toFixed(2)} KB`); // 找到 _0x4ff4 函数的开始和结束 const funcStart = code.indexOf('function _0x4ff4()'); if (funcStart === -1) { console.error('未找到 _0x4ff4 函数'); process.exit(1); } // 找到函数结束 - 通过匹配花括号 let braceCount = 0; let funcEnd = funcStart; let started = false; for (let i = funcStart; i < code.length; i++) { if (code[i] === '{') { braceCount++; started = true; } else if (code[i] === '}') { braceCount--; if (started && braceCount === 0) { funcEnd = i + 1; break; } } } // 找到 _0x56bd 函数 const decoderStart = code.indexOf('function _0x56bd('); if (decoderStart === -1) { console.error('未找到 _0x56bd 函数'); process.exit(1); } let decBraceCount = 0; let decoderEnd = decoderStart; let decStarted = false; for (let i = decoderStart; i < code.length; i++) { if (code[i] === '{') { decBraceCount++; decStarted = true; } else if (code[i] === '}') { decBraceCount--; if (decStarted && decBraceCount === 0) { decoderEnd = i + 1; break; } } } const arrayFunc = code.slice(funcStart, funcEnd); const decoderFunc = code.slice(decoderStart, decoderEnd); console.log(`_0x4ff4 函数长度: ${arrayFunc.length}`); console.log(`_0x56bd 函数长度: ${decoderFunc.length}`); // 在沙盒中执行 const sandbox = { vip: 'cursor', console: console }; const vmCode = ` var vip = 'cursor'; ${arrayFunc} ${decoderFunc} // 测试解码器 var result = {}; result._0x56bd = _0x56bd; result._0x4ff4 = _0x4ff4; result; `; console.log('\n[1] 在沙盒中执行解码器...'); let decoder; try { const script = new vm.Script(vmCode, { timeout: 30000 }); const context = vm.createContext(sandbox); decoder = script.runInContext(context, { timeout: 30000 }); console.log('解码器执行成功'); } catch (e) { console.error('沙盒执行失败:', e.message); process.exit(1); } // 测试解码 console.log('\n[2] 测试解码...'); try { const test1 = decoder._0x56bd(0x532, 'ck7z'); console.log(`测试 _0x56bd(0x532, 'ck7z') = "${test1}"`); } catch (e) { console.log('测试解码失败:', e.message); } // 查找所有 _0x56bd 调用 console.log('\n[3] 查找所有解码调用...'); const callPattern = /_0x56bd\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/gi; const decodeMap = new Map(); let match; let totalCalls = 0; while ((match = callPattern.exec(code)) !== null) { const fullMatch = match[0]; const indexHex = match[1]; const key = match[2]; totalCalls++; if (!decodeMap.has(fullMatch)) { try { const index = parseInt(indexHex, 16); const decoded = decoder._0x56bd(index, key); if (decoded && typeof decoded === 'string') { decodeMap.set(fullMatch, decoded); } } catch (e) { // 跳过解码失败的 } } } console.log(`总调用数: ${totalCalls}, 唯一调用数: ${decodeMap.size}`); // 替换 console.log('\n[4] 替换编码字符串...'); let newCode = code; let replaceCount = 0; for (const [pattern, decoded] of decodeMap) { let replacement; // 处理特殊字符 if (decoded.includes('\n') || decoded.includes('\r') || decoded.includes('`') || decoded.includes('${')) { replacement = JSON.stringify(decoded); } else if (decoded.includes("'") && !decoded.includes('"')) { replacement = `"${decoded}"`; } else if (decoded.includes('"') && !decoded.includes("'")) { replacement = `'${decoded}'`; } else { replacement = JSON.stringify(decoded); } const before = newCode.length; newCode = newCode.split(pattern).join(replacement); if (newCode.length !== before) { replaceCount++; } } console.log(`替换了 ${replaceCount} 个模式`); // 清理代码 console.log('\n[5] 清理代码...'); // 简化属性访问 newCode = newCode.replace(/\['([a-zA-Z_$][a-zA-Z0-9_$]*)'\]/g, '.$1'); // 简化布尔值 newCode = newCode.replace(/!!\[\]/g, 'true'); newCode = newCode.replace(/!\[\]/g, 'false'); // 保存 console.log('\n[6] 保存文件...'); fs.writeFileSync(outputPath, newCode); console.log(`保存到: ${outputPath}`); console.log(`新文件大小: ${(newCode.length / 1024).toFixed(2)} KB`); // 保存示例解码 const sampleMap = {}; let count = 0; for (const [k, v] of decodeMap) { if (count < 100 && v.length < 100) { sampleMap[k] = v; count++; } } fs.writeFileSync('D:/temp/破解/cursorpro-0.4.5/provider_sample_decode.json', JSON.stringify(sampleMap, null, 2)); console.log('\n✅ 完成!');