备份: 完整开发状态(含反混淆脚本和临时文件)

This commit is contained in:
ccdojox-crypto
2025-12-17 17:18:02 +08:00
parent 9e2333c90c
commit 7e9ea173a7
2872 changed files with 326818 additions and 249 deletions

179
deobfuscate_switch.js Normal file
View File

@@ -0,0 +1,179 @@
/**
* 简化 switch 控制流平坦化
* 将 while(true) { switch(arr[i++]) { case '0': ... } } 转换为顺序执行
*/
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_simplified.js';
const outputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider_final.js';
console.log('╔════════════════════════════════════════════════════╗');
console.log('║ Switch 控制流还原工具 ║');
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] 查找并还原 switch 控制流...');
let restoredCount = 0;
// 查找并收集变量定义
function findVariableValue(path, varName) {
let value = null;
// 在当前作用域向上查找
const binding = path.scope.getBinding(varName);
if (binding && binding.path.isVariableDeclarator()) {
const init = binding.path.node.init;
if (t.isCallExpression(init) &&
t.isMemberExpression(init.callee) &&
t.isStringLiteral(init.callee.object) &&
t.isIdentifier(init.callee.property, { name: 'split' })) {
// "1|4|0|3|2".split('|')
value = init.callee.object.value.split('|');
}
}
return value;
}
traverse(ast, {
WhileStatement(path) {
// 检查是否是 while(true) 或 while(1)
const test = path.node.test;
if (!t.isBooleanLiteral(test, { value: true }) &&
!t.isNumericLiteral(test, { value: 1 })) {
return;
}
const body = path.node.body;
if (!t.isBlockStatement(body)) return;
// 查找 switch 语句
const switchStmt = body.body.find(stmt => t.isSwitchStatement(stmt));
if (!switchStmt) return;
// 检查 discriminant 是否是 arr[i++] 形式
const disc = switchStmt.discriminant;
if (!t.isMemberExpression(disc)) return;
if (!t.isUpdateExpression(disc.property) || disc.property.operator !== '++') return;
const arrName = disc.object.name;
const indexName = disc.property.argument.name;
// 获取顺序数组
const order = findVariableValue(path, arrName);
if (!order) return;
// 收集 case 语句
const cases = new Map();
for (const caseStmt of switchStmt.cases) {
if (!caseStmt.test) continue; // default case
let caseValue;
if (t.isStringLiteral(caseStmt.test)) {
caseValue = caseStmt.test.value;
} else if (t.isNumericLiteral(caseStmt.test)) {
caseValue = String(caseStmt.test.value);
} else {
continue;
}
// 过滤掉 continue 和 break
const consequent = caseStmt.consequent.filter(stmt =>
!t.isContinueStatement(stmt) && !t.isBreakStatement(stmt)
);
cases.set(caseValue, consequent);
}
// 按顺序组装语句
const newStatements = [];
for (const key of order) {
const stmts = cases.get(key);
if (stmts) {
newStatements.push(...stmts);
}
}
if (newStatements.length > 0) {
// 查找并移除相关变量声明
const parentBody = path.parentPath;
if (t.isBlockStatement(parentBody.node) || t.isProgram(parentBody.node)) {
// 替换 while 语句
path.replaceWithMultiple(newStatements);
restoredCount++;
}
}
}
});
console.log(`还原了 ${restoredCount} 处 switch 控制流`);
console.log('\n[3] 清理冗余变量...');
// 清理只用于 switch 控制流的变量
let cleanedVars = 0;
traverse(ast, {
VariableDeclarator(path) {
if (!t.isIdentifier(path.node.id)) return;
const name = path.node.id.name;
const init = path.node.init;
// 检查是否是 "x|x|x".split('|') 形式
if (t.isCallExpression(init) &&
t.isMemberExpression(init.callee) &&
t.isStringLiteral(init.callee.object) &&
/^\d+(\|\d+)+$/.test(init.callee.object.value)) {
// 检查是否还在使用
const binding = path.scope.getBinding(name);
if (binding && binding.references === 0) {
path.remove();
cleanedVars++;
}
}
// 检查是否是用于索引的变量 (初始化为 0)
if (t.isNumericLiteral(init, { value: 0 })) {
const binding = path.scope.getBinding(name);
if (binding && binding.references === 0) {
path.remove();
cleanedVars++;
}
}
}
});
console.log(`清理了 ${cleanedVars} 个冗余变量`);
console.log('\n[4] 生成代码...');
const output = generate(ast, {
comments: false,
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`);
console.log('\n✅ 完成!');