备份: 完整开发状态(含反混淆脚本和临时文件)
This commit is contained in:
271
final_rename3.js
Normal file
271
final_rename3.js
Normal file
@@ -0,0 +1,271 @@
|
||||
/**
|
||||
* 第三轮变量重命名 - 基于上下文的深度分析
|
||||
*/
|
||||
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✅ 完成!');
|
||||
Reference in New Issue
Block a user