/** * 语义化变量重命名 * 根据上下文给变量起有意义的名称 */ 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`); 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 semanticPatterns = { // 函数参数 'extensionUri': ['_extensionUri', 'extensionUri'], 'context': ['_context', 'context', 'globalState'], 'webview': ['webview', 'Webview'], 'message': ['message', 'Message', 'postMessage'], 'key': ['key', 'Key', 'verifyKey'], 'path': ['path', 'Path', 'getPath'], 'result': ['result', 'Result', 'success'], 'response': ['response', 'Response'], 'error': ['error', 'Error', 'catch'], 'data': ['data', 'Data'], 'config': ['config', 'Config', 'configuration'], 'options': ['options', 'Options'], 'callback': ['callback', 'Callback'], 'handler': ['handler', 'Handler'], 'listener': ['listener', 'Listener'], 'event': ['event', 'Event'], 'token': ['token', 'Token'], 'email': ['email', 'Email'], 'status': ['status', 'Status'], }; // 收集需要重命名的变量 const renameMap = new Map(); let renamedCount = 0; // 分析每个作用域中的变量 traverse(ast, { // 处理函数参数 Function(path) { const params = path.node.params; // 对于有意义的函数,分析参数 if (path.node.id && path.node.id.name) { const funcName = path.node.id.name; // 根据函数名推断参数名 params.forEach((param, index) => { if (t.isIdentifier(param) && /^arg\d+$/.test(param.name)) { let newName = null; // 常见模式 if (funcName.includes('activate') || funcName.includes('Activate')) { if (index === 0) newName = 'key'; } else if (funcName.includes('message') || funcName.includes('Message')) { if (index === 0) newName = 'message'; } else if (funcName.includes('toggle') || funcName.includes('Toggle')) { if (index === 0) newName = 'enabled'; } if (newName) { const binding = path.scope.getBinding(param.name); if (binding) { binding.path.node.name = newName; binding.referencePaths.forEach(ref => { ref.node.name = newName; }); renamedCount++; } } } }); } }, // 处理类方法 ClassMethod(path) { const methodName = path.node.key.name || ''; const params = path.node.params; params.forEach((param, index) => { if (t.isIdentifier(param) && /^arg\d+$/.test(param.name)) { let newName = null; // 根据方法名推断参数名 if (methodName === 'constructor') { if (index === 0) newName = 'extensionUri'; else if (index === 1) newName = 'context'; } else if (methodName === 'resolveWebviewView') { if (index === 0) newName = 'webviewView'; else if (index === 1) newName = 'context'; else if (index === 2) newName = 'token'; } else if (methodName.includes('Activate')) { if (index === 0) newName = 'key'; } else if (methodName.includes('Message')) { if (index === 0) newName = 'message'; } else if (methodName.includes('Toggle')) { if (index === 0) newName = 'enabled'; else if (index === 1) newName = 'silent'; } else if (methodName.includes('Write')) { if (index === 0) newName = 'content'; } else if (methodName.includes('Path')) { if (index === 0) newName = 'filePath'; } else if (methodName.includes('Account')) { if (index === 0) newName = 'accountData'; } else if (methodName.includes('Usage')) { if (index === 0) newName = 'checkLimit'; } else if (methodName.includes('Inject') || methodName.includes('Restore')) { // 无参数或特定参数 } if (newName) { const binding = path.scope.getBinding(param.name); if (binding) { binding.path.node.name = newName; binding.referencePaths.forEach(ref => { ref.node.name = newName; }); renamedCount++; } } } }); }, // 处理变量声明 VariableDeclarator(path) { if (!t.isIdentifier(path.node.id)) return; const varName = path.node.id.name; // 只处理 var/v + 数字 格式 if (!/^(var|v)\d+$/.test(varName)) return; const init = path.node.init; let newName = null; // 根据初始化值推断 if (t.isAwaitExpression(init) && t.isCallExpression(init.argument)) { const call = init.argument; if (t.isMemberExpression(call.callee)) { const methodName = call.callee.property.name || ''; if (methodName.includes('verify')) newName = 'verifyResult'; else if (methodName.includes('switch')) newName = 'switchResult'; else if (methodName.includes('get')) newName = 'result'; else if (methodName.includes('read')) newName = 'content'; else if (methodName.includes('exec')) newName = 'execResult'; } } else if (t.isCallExpression(init)) { const call = init; if (t.isMemberExpression(call.callee)) { const objName = call.callee.object.name || ''; const methodName = call.callee.property.name || ''; if (methodName === 'get') newName = 'value'; else if (methodName === 'join') newName = 'fullPath'; else if (methodName === 'readFileSync') newName = 'fileContent'; else if (methodName === 'existsSync') newName = 'exists'; else if (methodName === 'getOwnPropertyDescriptor') newName = 'descriptor'; else if (methodName === 'getOwnPropertyNames') newName = 'propNames'; } } else if (t.isObjectExpression(init)) { // 对象字面量 newName = 'options'; } else if (t.isArrayExpression(init)) { newName = 'items'; } else if (t.isMemberExpression(init)) { const propName = init.property.name || ''; if (propName === 'length') newName = 'len'; else if (propName === 'globalState') newName = 'state'; } if (newName) { // 确保名称唯一 const scope = path.scope; let finalName = newName; let counter = 1; while (scope.hasBinding(finalName)) { finalName = newName + counter++; } const binding = scope.getBinding(varName); if (binding) { path.node.id.name = finalName; binding.referencePaths.forEach(ref => { ref.node.name = finalName; }); renamedCount++; } } } }); console.log(`语义化重命名了 ${renamedCount} 个变量`); console.log('\n[3] 生成代码...'); const output = generate(ast, { comments: false, compact: false, concise: false }, code); // 后处理 let finalCode = output.code; finalCode = finalCode.replace(/\["([a-zA-Z_$][a-zA-Z0-9_$]*)"\]/g, '.$1'); console.log('\n[4] 保存文件...'); fs.writeFileSync(outputPath, finalCode); console.log(`保存到: ${outputPath}`); console.log(`新文件大小: ${(finalCode.length / 1024).toFixed(2)} KB`); // 统计剩余的通用变量名 const remainingGeneric = (finalCode.match(/\b(var|arg|v)\d+\b/g) || []); const uniqueGeneric = [...new Set(remainingGeneric)]; console.log(`\n剩余通用变量名: ${uniqueGeneric.length} 个唯一名称`); console.log('\n✅ 完成!');