/** * 变量名反混淆工具 * 将 _0x 前缀的变量名重命名为可读形式 */ const fs = require('fs'); const path = require('path'); // 尝试使用 babel let babel, traverse, generate; try { babel = require('@babel/core'); traverse = require('@babel/traverse').default; generate = require('@babel/generator').default; } catch (e) { console.log('需要安装 babel 依赖,正在安装...'); require('child_process').execSync('npm install @babel/core @babel/traverse @babel/generator @babel/parser --save-dev', { stdio: 'inherit', cwd: 'D:/temp/破解/cursorpro-0.4.5' }); babel = require('@babel/core'); traverse = require('@babel/traverse').default; generate = require('@babel/generator').default; } const inputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider.js'; const outputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider_readable.js'; console.log('╔════════════════════════════════════════════════════╗'); console.log('║ 变量名反混淆工具 ║'); console.log('╚════════════════════════════════════════════════════╝'); const code = fs.readFileSync(inputPath, 'utf8'); console.log(`读取文件: ${(code.length / 1024).toFixed(2)} KB`); console.log('\n[1] 解析 AST...'); let ast; try { ast = babel.parseSync(code, { sourceType: 'script', plugins: [] }); console.log('AST 解析成功'); } catch (e) { console.error('AST 解析失败:', e.message); process.exit(1); } console.log('\n[2] 收集变量名...'); const varMapping = new Map(); let varCounter = 1; let paramCounter = 1; // 变量名生成器 function generateVarName(prefix, counter) { return prefix + counter; } // 检查是否是混淆变量名 function isObfuscatedName(name) { return /^_0x[a-f0-9]+$/i.test(name); } // 遍历 AST 收集所有混淆变量名 traverse(ast, { Identifier(path) { const name = path.node.name; if (isObfuscatedName(name) && !varMapping.has(name)) { // 根据上下文决定新名称 let newName; if (path.parentPath.isFunction() && path.listKey === 'params') { newName = 'arg' + paramCounter++; } else if (path.parentPath.isVariableDeclarator() && path.key === 'id') { newName = 'var' + varCounter++; } else if (path.parentPath.isFunctionDeclaration() && path.key === 'id') { newName = 'func' + varCounter++; } else if (!varMapping.has(name)) { newName = 'v' + varCounter++; } if (newName) { varMapping.set(name, newName); } } } }); console.log(`找到 ${varMapping.size} 个混淆变量名`); console.log('\n[3] 重命名变量...'); let renamedCount = 0; traverse(ast, { Identifier(path) { const name = path.node.name; if (varMapping.has(name)) { path.node.name = varMapping.get(name); renamedCount++; } } }); console.log(`重命名了 ${renamedCount} 处`); console.log('\n[4] 生成代码...'); const output = generate(ast, { comments: true, compact: false, concise: false }, code); console.log('\n[5] 保存文件...'); fs.writeFileSync(outputPath, output.code); console.log(`保存到: ${outputPath}`); console.log(`新文件大小: ${(output.code.length / 1024).toFixed(2)} KB`); // 验证 const remaining = (output.code.match(/_0x[a-f0-9]+/gi) || []).length; console.log(`\n剩余混淆变量名: ${remaining}`); console.log('\n✅ 完成!');