/** * 最终清理 * 移除未使用的变量和无意义的表达式 */ 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_final.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] 移除无意义的表达式语句...'); let removedExpr = 0; traverse(ast, { ExpressionStatement(path) { const expr = path.node.expression; // 移除纯数字表达式 (如 0x0;) if (t.isNumericLiteral(expr)) { path.remove(); removedExpr++; return; } // 移除纯字符串表达式 (非 'use strict') if (t.isStringLiteral(expr) && expr.value !== 'use strict') { path.remove(); removedExpr++; return; } } }); console.log(`移除了 ${removedExpr} 个无意义表达式`); console.log('\n[3] 移除未使用的变量...'); let removedVars = 0; // 多次遍历以处理嵌套引用 for (let pass = 0; pass < 3; pass++) { traverse(ast, { VariableDeclarator(path) { if (!t.isIdentifier(path.node.id)) return; const name = path.node.id.name; const binding = path.scope.getBinding(name); if (binding && binding.references === 0) { // 不移除以 __ 开头的模块辅助函数 if (name.startsWith('__')) return; path.remove(); removedVars++; } } }); } console.log(`移除了 ${removedVars} 个未使用变量`); console.log('\n[4] 移除空的变量声明...'); let removedEmpty = 0; traverse(ast, { VariableDeclaration(path) { if (path.node.declarations.length === 0) { path.remove(); removedEmpty++; } } }); console.log(`移除了 ${removedEmpty} 个空声明`); console.log('\n[5] 简化十六进制数字...'); let convertedNums = 0; traverse(ast, { NumericLiteral(path) { // 将 0x0 转为 0 if (path.node.extra && path.node.extra.raw && path.node.extra.raw.startsWith('0x')) { delete path.node.extra; convertedNums++; } } }); console.log(`转换了 ${convertedNums} 个十六进制数字`); console.log('\n[6] 生成代码...'); const output = generate(ast, { comments: false, compact: false, concise: false }, code); // 后处理:清理双引号属性 let finalCode = output.code; // 清理 obj["prop"] -> obj.prop (对于有效标识符) finalCode = finalCode.replace(/\["([a-zA-Z_$][a-zA-Z0-9_$]*)"\]/g, '.$1'); // 清理对象字面量中的引号 'key': -> key: finalCode = finalCode.replace(/'(enumerable|value|get|writable|configurable)':/g, '$1:'); console.log('\n[7] 保存文件...'); fs.writeFileSync(outputPath, finalCode); console.log(`保存到: ${outputPath}`); console.log(`新文件大小: ${(finalCode.length / 1024).toFixed(2)} KB`); // 统计 console.log('\n=== 最终统计 ==='); const remaining0x = (finalCode.match(/_0x[a-f0-9]+/gi) || []).length; const remainingSwitch = (finalCode.match(/switch\s*\([^)]*\[/g) || []).length; console.log(`剩余 _0x 模式: ${remaining0x}`); console.log(`剩余数组 switch: ${remainingSwitch}`); console.log('\n✅ 完成!');