/** * 第三轮变量重命名 - 基于上下文的深度分析 */ const fs = require('fs'); const babel = require('@babel/core'); const traverse = require('@babel/traverse').default; const generate = require('@babel/generator').default; const t = require('@babel/types'); 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.js'; console.log('╔════════════════════════════════════════════════════╗'); console.log('║ 第三轮深度变量重命名 ║'); console.log('╚════════════════════════════════════════════════════╝'); const code = fs.readFileSync(inputPath, 'utf8'); console.log(`读取文件: ${(code.length / 1024).toFixed(2)} KB`); // 简单的文本替换方式处理特定模式 let newCode = code; // 1. 修复 workbenchpathasyncResult 这种奇怪的名称 const uglyNames = { 'workbenchpathasyncResult': 'workbenchPath', 'cursorinstallpathResult': 'cursorPath', 'cursorrunningpathResult': 'cursorRunningPath', 'seamlessstatusResult': 'seamlessStatus', 'proxystatusResult': 'proxyStatus', 'accountusageResult': 'accountUsage', 'userswitchstatusResult': 'userSwitchStatus', 'announcementResult': 'announcement', 'versionResult': 'versionInfo', }; for (const [ugly, nice] of Object.entries(uglyNames)) { const regex = new RegExp('\\b' + ugly + '\\b', 'g'); newCode = newCode.replace(regex, nice); } console.log('[1] 修复了命名风格问题'); // 保存中间结果 fs.writeFileSync(outputPath, newCode); // 2. 使用 AST 进行更复杂的重命名 console.log('\n[2] 解析 AST...'); let ast; try { ast = babel.parseSync(newCode, { sourceType: 'script', plugins: [] }); console.log('AST 解析成功'); } catch (e) { console.error('AST 解析失败:', e.message); process.exit(1); } // 追踪使用的名称 const usedNames = new Map(); function isNameUsed(scope, name) { if (scope.hasBinding(name)) return true; const key = scope.uid; if (!usedNames.has(key)) usedNames.set(key, new Set()); return usedNames.get(key).has(name); } function markNameUsed(scope, name) { const key = scope.uid; if (!usedNames.has(key)) usedNames.set(key, new Set()); usedNames.get(key).add(name); } function getUniqueName(scope, baseName) { let name = baseName; let counter = 1; while (isNameUsed(scope, name)) { name = baseName + counter++; } markNameUsed(scope, name); return name; } console.log('\n[3] 分析变量使用上下文...'); let renamedCount = 0; // 收集变量的使用上下文 const varContexts = new Map(); traverse(ast, { Identifier(path) { const name = path.node.name; if (!/^(var|arg|v)\d+$/.test(name)) return; if (!varContexts.has(name)) { varContexts.set(name, { usages: [] }); } const ctx = varContexts.get(name); // 分析使用上下文 const parent = path.parent; // 赋值右边 if (t.isAssignmentExpression(parent) && parent.right === path.node) { // 跳过 } // 赋值左边 else if (t.isAssignmentExpression(parent) && parent.left === path.node) { ctx.usages.push({ type: 'assign', parent }); } // 成员访问 var.xxx else if (t.isMemberExpression(parent) && parent.object === path.node) { const prop = parent.property.name || parent.property.value; if (prop) ctx.usages.push({ type: 'member', prop }); } // 方法调用参数 else if (t.isCallExpression(parent)) { const callee = parent.callee; if (t.isMemberExpression(callee)) { const method = callee.property.name; ctx.usages.push({ type: 'callArg', method }); } } } }); // 根据上下文推断名称 const inferredNames = new Map(); for (const [varName, ctx] of varContexts) { let inferredName = null; // 检查成员访问 const members = ctx.usages.filter(u => u.type === 'member').map(u => u.prop); if (members.includes('platform')) inferredName = 'platform'; else if (members.includes('stdout')) inferredName = 'execResult'; else if (members.includes('success')) inferredName = 'result'; else if (members.includes('email')) inferredName = 'accountInfo'; else if (members.includes('switched')) inferredName = 'switchResult'; else if (members.includes('path')) inferredName = 'pathInfo'; else if (members.includes('length')) inferredName = 'items'; else if (members.includes('trim')) inferredName = 'str'; else if (members.includes('match')) inferredName = 'text'; else if (members.includes('replace')) inferredName = 'content'; else if (members.includes('split')) inferredName = 'text'; else if (members.includes('join')) inferredName = 'parts'; else if (members.includes('push')) inferredName = 'list'; else if (members.includes('forEach') || members.includes('map') || members.includes('filter')) { inferredName = 'items'; } if (inferredName) { inferredNames.set(varName, inferredName); } } console.log(`推断了 ${inferredNames.size} 个变量名`); // 应用推断的名称 traverse(ast, { VariableDeclarator(path) { if (!t.isIdentifier(path.node.id)) return; const varName = path.node.id.name; if (!inferredNames.has(varName)) return; const newName = getUniqueName(path.scope, inferredNames.get(varName)); const binding = path.scope.getBinding(varName); if (binding) { path.node.id.name = newName; binding.referencePaths.forEach(ref => { ref.node.name = newName; }); renamedCount++; } } }); console.log(`重命名了 ${renamedCount} 个变量`); // 4. 处理特殊的 process.platform 赋值 console.log('\n[4] 处理特殊模式...'); let specialCount = 0; traverse(ast, { VariableDeclarator(path) { if (!t.isIdentifier(path.node.id)) return; const varName = path.node.id.name; if (!/^(var|v)\d+$/.test(varName)) return; const init = path.node.init; let newName = null; // process.platform if (t.isMemberExpression(init) && t.isIdentifier(init.object, { name: 'process' }) && t.isIdentifier(init.property, { name: 'platform' })) { newName = 'platform'; } // process.env.xxx else if (t.isMemberExpression(init) && t.isMemberExpression(init.object) && t.isIdentifier(init.object.object, { name: 'process' }) && t.isIdentifier(init.object.property, { name: 'env' })) { const envVar = init.property.name || init.property.value; if (envVar === 'APPDATA') newName = 'appData'; else if (envVar === 'HOME') newName = 'homeDir'; else if (envVar === 'LOCALAPPDATA') newName = 'localAppData'; else newName = 'envValue'; } // null 初始化 else if (t.isNullLiteral(init)) { // 检查后续使用来推断 const binding = path.scope.getBinding(varName); if (binding) { for (const ref of binding.referencePaths) { const parent = ref.parent; if (t.isAssignmentExpression(parent) && parent.left === ref.node) { const right = parent.right; if (t.isCallExpression(right) && t.isMemberExpression(right.callee)) { const method = right.callee.property.name; if (method === 'dirname') newName = 'dirPath'; else if (method === 'join') newName = 'fullPath'; } } } } if (!newName) newName = 'result'; } if (newName) { const finalName = getUniqueName(path.scope, newName); const binding = path.scope.getBinding(varName); if (binding) { path.node.id.name = finalName; binding.referencePaths.forEach(ref => { ref.node.name = finalName; }); specialCount++; } } } }); console.log(`处理了 ${specialCount} 个特殊模式`); console.log('\n[5] 生成代码...'); const output = generate(ast, { comments: false, compact: false, concise: false }, newCode); let finalCode = output.code; finalCode = finalCode.replace(/\["([a-zA-Z_$][a-zA-Z0-9_$]*)"\]/g, '.$1'); console.log('\n[6] 保存文件...'); fs.writeFileSync(outputPath, finalCode); console.log(`保存到: ${outputPath}`); console.log(`新文件大小: ${(finalCode.length / 1024).toFixed(2)} KB`); const remaining = (finalCode.match(/\b(var|arg|v)\d+\b/g) || []); const unique = [...new Set(remaining)]; console.log(`\n剩余通用变量名: ${unique.length} 个唯一名称`); console.log('\n✅ 完成!');