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

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

349
full_deobfuscate_v3.js Normal file
View File

@@ -0,0 +1,349 @@
/**
* 完整反混淆脚本 v3 - 更强大的字符串解码
* 策略:先执行完整的解码器设置,再遍历所有可能的调用参数
*/
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const deobfuscateIO = require('obfuscator-io-deobfuscator').deobfuscate;
const beautify = require('js-beautify').js;
const outputDir = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out';
function ensureDir(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
/**
* 提取并执行完整的解码器设置代码
*/
function setupFullDecoder(code) {
// 查找字符串数组函数名
const arrayFuncMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\)\s*\{/);
if (!arrayFuncMatch) {
console.log(' 未找到字符串数组函数');
return null;
}
const arrayFuncName = arrayFuncMatch[1];
// 查找解码函数 - 更宽松的匹配
const decoderPatterns = [
/function\s+(_0x[a-f0-9]+)\s*\(\s*_0x[a-f0-9]+\s*,\s*_0x[a-f0-9]+\s*\)\s*\{\s*const\s+_0x[a-f0-9]+\s*=\s*_0x[a-f0-9]+\s*\(\s*\)\s*;/,
/function\s+(_0x[a-f0-9]+)\s*\(\s*_0x[a-f0-9]+\s*,\s*_0x[a-f0-9]+\s*\)\s*\{/
];
let decoderFuncName = null;
for (const pattern of decoderPatterns) {
const match = code.match(pattern);
if (match) {
decoderFuncName = match[1];
break;
}
}
if (!decoderFuncName) {
console.log(' 未找到解码函数');
return null;
}
console.log(` 字符串数组函数: ${arrayFuncName}`);
console.log(` 解码函数: ${decoderFuncName}`);
// 提取从开头到解码函数结束的所有代码
// 找到解码函数的结束位置
const decoderStart = code.indexOf(`function ${decoderFuncName}(`);
if (decoderStart === -1) {
console.log(' 未找到解码函数定义');
return null;
}
// 找到解码函数的结束
let braceCount = 0;
let decoderEnd = decoderStart;
let foundStart = false;
for (let i = decoderStart; i < code.length; i++) {
if (code[i] === '{') {
braceCount++;
foundStart = true;
} else if (code[i] === '}') {
braceCount--;
if (foundStart && braceCount === 0) {
decoderEnd = i + 1;
break;
}
}
}
// 提取从文件开头到解码函数结束的所有代码
// 这包括 vip 变量、IIFE、数组函数、解码函数
const setupCode = code.substring(0, decoderEnd);
// 创建沙盒并执行
const sandbox = {
console: { log: () => {}, warn: () => {}, error: () => {} },
parseInt: parseInt,
String: String,
decodeURIComponent: decodeURIComponent
};
try {
vm.runInNewContext(setupCode, sandbox);
// 检查解码函数是否可用
const testResult = vm.runInNewContext(`typeof ${decoderFuncName}`, sandbox);
if (testResult !== 'function') {
console.log(` 解码函数不可用: ${testResult}`);
return null;
}
console.log(` 解码器设置成功`);
return { sandbox, decoderFuncName, arrayFuncName, setupCode };
} catch (e) {
console.log(` 沙盒执行失败: ${e.message}`);
// 尝试更激进的方法 - 执行整个文件的前半部分
return setupAggressiveDecoder(code, decoderFuncName, arrayFuncName);
}
}
/**
* 更激进的解码器设置 - 执行更多代码
*/
function setupAggressiveDecoder(code, decoderFuncName, arrayFuncName) {
console.log(' 尝试激进模式...');
// 找到第一个 exports 或 Object.defineProperty 之前的所有代码
const exportIndex = Math.min(
code.indexOf('Object.defineProperty(exports') !== -1 ? code.indexOf('Object.defineProperty(exports') : Infinity,
code.indexOf('exports.') !== -1 ? code.indexOf('exports.') : Infinity
);
if (exportIndex === Infinity) {
console.log(' 未找到 exports 边界');
return null;
}
const setupCode = code.substring(0, exportIndex);
const sandbox = {
console: { log: () => {}, warn: () => {}, error: () => {} },
parseInt: parseInt,
String: String,
decodeURIComponent: decodeURIComponent,
this: {},
Object: Object
};
try {
vm.runInNewContext(setupCode, sandbox);
const testResult = vm.runInNewContext(`typeof ${decoderFuncName}`, sandbox);
if (testResult === 'function') {
console.log(` 激进模式成功`);
return { sandbox, decoderFuncName, arrayFuncName, setupCode };
}
} catch (e) {
console.log(` 激进模式失败: ${e.message}`);
}
return null;
}
/**
* 收集并解码所有字符串调用
*/
function decodeAllStrings(code, decoder) {
if (!decoder) return { code, decodedCount: 0 };
const { sandbox, decoderFuncName } = decoder;
// 收集所有解码函数别名
const aliasPattern = new RegExp(`const\\s+(_0x[a-f0-9]+)\\s*=\\s*${decoderFuncName}\\s*;`, 'g');
const aliases = [decoderFuncName];
let match;
while ((match = aliasPattern.exec(code)) !== null) {
aliases.push(match[1]);
}
console.log(` 解码函数别名: ${aliases.join(', ')}`);
// 构建所有可能的调用模式
const decodedMap = new Map();
let totalFound = 0;
for (const alias of aliases) {
// 匹配多种调用格式
const patterns = [
new RegExp(`${alias}\\s*\\(\\s*(0x[a-f0-9]+)\\s*,\\s*'([^']*)'\\s*\\)`, 'g'),
new RegExp(`${alias}\\s*\\(\\s*(0x[a-f0-9]+)\\s*,\\s*"([^"]*)"\\s*\\)`, 'g'),
];
for (const pattern of patterns) {
let callMatch;
while ((callMatch = pattern.exec(code)) !== null) {
const fullMatch = callMatch[0];
const num = callMatch[1];
const key = callMatch[2];
if (!decodedMap.has(fullMatch)) {
try {
const decoded = vm.runInNewContext(
`${decoderFuncName}(${num},'${key.replace(/'/g, "\\'")}')`,
sandbox
);
if (typeof decoded === 'string') {
decodedMap.set(fullMatch, decoded);
totalFound++;
}
} catch (e) {
// 解码失败,跳过
}
}
}
}
}
console.log(` 找到 ${totalFound} 个字符串调用`);
// 替换所有解码后的字符串
let decodedCount = 0;
for (const [original, decoded] of decodedMap) {
// 选择合适的引号
let replacement;
if (decoded.includes('\n') || decoded.includes('\r')) {
replacement = '`' + decoded.replace(/`/g, '\\`').replace(/\$/g, '\\$') + '`';
} else if (decoded.includes("'") && !decoded.includes('"')) {
replacement = JSON.stringify(decoded);
} else {
replacement = `'${decoded.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
}
// 全局替换
const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(escapedOriginal, 'g');
const before = code.length;
code = code.replace(regex, replacement);
if (code.length !== before) {
decodedCount++;
}
}
console.log(` 替换了 ${decodedCount} 个不同的字符串`);
// 移除解码器代码(可选,让代码更干净)
// 注释掉解码器相关代码而不是删除
return { code, decodedCount };
}
/**
* 清理混淆的变量引用
*/
function cleanObfuscatedReferences(code) {
// 将 obj['property'] 转换为 obj.property
code = code.replace(/\['([a-zA-Z_$][a-zA-Z0-9_$]*)'\]/g, '.$1');
// 简化 !![] 为 true
code = code.replace(/!!\[\]/g, 'true');
// 简化 ![] 为 false
code = code.replace(/!\[\]/g, 'false');
return code;
}
/**
* AST 清洗
*/
function astClean(code, filename) {
try {
console.log(` [AST] 处理...`);
return deobfuscateIO(code);
} catch (e) {
console.log(` [AST] 失败: ${e.message}`);
return code;
}
}
/**
* 处理单个文件
*/
async function processFile(inputPath, outputPath, filename) {
console.log(`\n${'='.repeat(50)}`);
console.log(`处理: ${filename}`);
console.log('='.repeat(50));
let code = fs.readFileSync(inputPath, 'utf8');
console.log(`原始大小: ${(code.length / 1024).toFixed(2)} KB`);
// Step 1: 设置解码器
console.log('\nStep 1: 设置解码器...');
const decoder = setupFullDecoder(code);
// Step 2: 解码所有字符串
console.log('\nStep 2: 解码字符串...');
const decodeResult = decodeAllStrings(code, decoder);
code = decodeResult.code;
// Step 3: 清理混淆引用
console.log('\nStep 3: 清理混淆引用...');
code = cleanObfuscatedReferences(code);
// Step 4: AST 清洗
console.log('\nStep 4: AST 清洗...');
code = astClean(code, filename);
// Step 5: 再次清理AST 可能引入新的混淆)
console.log('\nStep 5: 二次清理...');
code = cleanObfuscatedReferences(code);
// Step 6: 美化
console.log('\nStep 6: 美化代码...');
code = beautify(code, {
indent_size: 4,
preserve_newlines: true,
max_preserve_newlines: 2,
space_in_empty_paren: true,
jslint_happy: false,
brace_style: 'collapse'
});
console.log(`\n处理后大小: ${(code.length / 1024).toFixed(2)} KB`);
// 保存
ensureDir(path.dirname(outputPath));
fs.writeFileSync(outputPath, code);
console.log(`已保存: ${outputPath}`);
}
// 主函数
async function main() {
console.log('╔════════════════════════════════════════════════════╗');
console.log('║ 完整反混淆脚本 v3 ║');
console.log('║ 完整解码器执行 + 批量字符串替换 + AST清洗 ║');
console.log('╚════════════════════════════════════════════════════╝\n');
const files = [
{ input: 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/webview/provider.js', output: 'webview/provider.js' },
{ input: 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/extension.js', output: 'extension.js' },
{ input: 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/utils/account.js', output: 'utils/account.js' },
{ input: 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/utils/sqlite.js', output: 'utils/sqlite.js' },
{ input: 'D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/api/client.js', output: 'api/client.js' },
];
for (const file of files) {
if (fs.existsSync(file.input)) {
await processFile(file.input, path.join(outputDir, file.output), file.output);
} else {
console.log(`\n跳过: ${file.input} (不存在)`);
}
}
console.log('\n╔════════════════════════════════════════════════════╗');
console.log('║ 完成! ║');
console.log('╚════════════════════════════════════════════════════╝');
console.log(`\n输出目录: ${outputDir}`);
}
main().catch(console.error);