123 lines
4.3 KiB
JavaScript
123 lines
4.3 KiB
JavaScript
/**
|
|
* 最终全面检查 - 反混淆结果验证
|
|
*/
|
|
const fs = require('fs');
|
|
const babel = require('@babel/core');
|
|
|
|
const inputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider.js';
|
|
const code = fs.readFileSync(inputPath, 'utf8');
|
|
|
|
console.log('='.repeat(50));
|
|
console.log(' provider.js 反混淆最终检查报告');
|
|
console.log('='.repeat(50));
|
|
|
|
// 1. 语法检查
|
|
console.log('\n1. 语法验证:');
|
|
try {
|
|
babel.parseSync(code, { sourceType: 'script' });
|
|
console.log(' ✅ 语法正确');
|
|
} catch (e) {
|
|
console.log(' ❌ 语法错误:', e.message);
|
|
}
|
|
|
|
// 2. 混淆特征检查
|
|
console.log('\n2. 混淆特征检查:');
|
|
|
|
// _0x 开头的变量名
|
|
const oxPattern = /_0x[a-f0-9]+/gi;
|
|
const oxMatches = code.match(oxPattern) || [];
|
|
console.log(` _0x 变量名: ${oxMatches.length === 0 ? '✅ 无' : '❌ ' + oxMatches.length + ' 个'}`);
|
|
|
|
// Unicode 转义
|
|
const unicodePattern = /\\u[0-9a-fA-F]{4}/g;
|
|
const unicodeMatches = code.match(unicodePattern) || [];
|
|
console.log(` Unicode 转义: ${unicodeMatches.length === 0 ? '✅ 无' : '❌ ' + unicodeMatches.length + ' 个'}`);
|
|
|
|
// 加密字符串调用 (如 _0x1234('0x0'))
|
|
const encryptedCallPattern = /_0x[a-f0-9]+\s*\(\s*['"]0x/gi;
|
|
const encryptedCalls = code.match(encryptedCallPattern) || [];
|
|
console.log(` 加密字符串调用: ${encryptedCalls.length === 0 ? '✅ 无' : '❌ ' + encryptedCalls.length + ' 个'}`);
|
|
|
|
// 死代码分支 (如 "xxx" === "xxx" 或 "xxx" !== "yyy")
|
|
const deadCodePattern = /["'][a-zA-Z]+["']\s*[!=]==\s*["'][a-zA-Z]+["']/g;
|
|
const deadCodeMatches = code.match(deadCodePattern) || [];
|
|
console.log(` 死代码分支: ${deadCodeMatches.length === 0 ? '✅ 无' : '⚠️ ' + deadCodeMatches.length + ' 个 (可能是正常代码)'}`);
|
|
|
|
// 泛型变量名 (var0-9, v0-9, param 等是正常的)
|
|
const genericVarPattern = /\b(var[0-9]{2,}|v[0-9]{2,})\b/g;
|
|
const genericVars = code.match(genericVarPattern) || [];
|
|
const uniqueGeneric = [...new Set(genericVars)];
|
|
if (uniqueGeneric.length > 0) {
|
|
console.log(` 泛型变量名: ⚠️ ${uniqueGeneric.length} 种`);
|
|
console.log(` 示例: ${uniqueGeneric.slice(0, 5).join(', ')}`);
|
|
} else {
|
|
console.log(` 泛型变量名: ✅ 无`);
|
|
}
|
|
|
|
// 3. 代码质量统计
|
|
console.log('\n3. 代码质量统计:');
|
|
|
|
const lines = code.split('\n');
|
|
console.log(` 总行数: ${lines.length}`);
|
|
console.log(` 文件大小: ${(code.length / 1024).toFixed(2)} KB`);
|
|
|
|
// 中文字符数量
|
|
const chineseChars = (code.match(/[\u4e00-\u9fff]/g) || []).length;
|
|
console.log(` 中文字符: ${chineseChars} 个`);
|
|
|
|
// 函数数量
|
|
const funcCount = (code.match(/function\s*\(/g) || []).length;
|
|
const arrowCount = (code.match(/=>\s*{/g) || []).length;
|
|
const asyncCount = (code.match(/async\s+(function|\()/g) || []).length;
|
|
console.log(` 函数定义: ${funcCount + arrowCount} 个 (含 ${asyncCount} 个 async)`);
|
|
|
|
// 类方法数量
|
|
const methodCount = (code.match(/async\s+_?[a-zA-Z]+\s*\(/g) || []).length;
|
|
console.log(` 类方法: ${methodCount} 个`);
|
|
|
|
// 4. 关键功能检查
|
|
console.log('\n4. 关键功能保留检查:');
|
|
|
|
const keyFeatures = [
|
|
['CursorProViewProvider', '主类'],
|
|
['verifyKey', '验证激活码'],
|
|
['switchSeamlessToken', '换号功能'],
|
|
['_handleActivate', '激活处理'],
|
|
['_handleInjectSeamless', '无感换号注入'],
|
|
['_writeHostsFile', 'hosts文件写入'],
|
|
['_getCursorInstallPath', '获取Cursor路径'],
|
|
['sqliteSetBatch', 'SQLite批量写入'],
|
|
['CURRENT_VERSION', '版本号'],
|
|
['SNI_PROXY_IP', '代理IP']
|
|
];
|
|
|
|
keyFeatures.forEach(([feature, desc]) => {
|
|
const exists = code.includes(feature);
|
|
console.log(` ${exists ? '✅' : '❌'} ${desc} (${feature})`);
|
|
});
|
|
|
|
// 5. 显示一些关键配置
|
|
console.log('\n5. 关键配置提取:');
|
|
|
|
// 版本号
|
|
const versionMatch = code.match(/CURRENT_VERSION\s*=\s*['"]([^'"]+)['"]/);
|
|
if (versionMatch) {
|
|
console.log(` 版本号: ${versionMatch[1]}`);
|
|
}
|
|
|
|
// SNI代理IP
|
|
const proxyMatch = code.match(/SNI_PROXY_IP\s*=\s*['"]([^'"]+)['"]/);
|
|
if (proxyMatch) {
|
|
console.log(` SNI代理IP: ${proxyMatch[1]}`);
|
|
}
|
|
|
|
// Cursor域名
|
|
const domainsMatch = code.match(/CURSOR_DOMAINS\s*=\s*\[([^\]]+)\]/);
|
|
if (domainsMatch) {
|
|
console.log(` Cursor域名: ${domainsMatch[1].replace(/["']/g, '')}`);
|
|
}
|
|
|
|
console.log('\n' + '='.repeat(50));
|
|
console.log(' 检查完成');
|
|
console.log('='.repeat(50));
|