备份: 完整开发状态(含反混淆脚本和临时文件)
This commit is contained in:
193
deobfuscate_provider_v3.js
Normal file
193
deobfuscate_provider_v3.js
Normal file
@@ -0,0 +1,193 @@
|
||||
/**
|
||||
* 动态反混淆 provider.js v3
|
||||
* 使用 vm 沙盒执行解码器
|
||||
*/
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
|
||||
const inputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider_clean.js';
|
||||
const outputPath = 'D:/temp/破解/cursorpro-0.4.5/deobfuscated_full/extension/out/webview/provider.js';
|
||||
|
||||
console.log('╔════════════════════════════════════════════════════╗');
|
||||
console.log('║ Provider.js 动态反混淆工具 v3 ║');
|
||||
console.log('╚════════════════════════════════════════════════════╝');
|
||||
|
||||
let code = fs.readFileSync(inputPath, 'utf8');
|
||||
console.log(`读取文件: ${(code.length / 1024).toFixed(2)} KB`);
|
||||
|
||||
// 找到 _0x4ff4 函数的开始和结束
|
||||
const funcStart = code.indexOf('function _0x4ff4()');
|
||||
if (funcStart === -1) {
|
||||
console.error('未找到 _0x4ff4 函数');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 找到函数结束 - 通过匹配花括号
|
||||
let braceCount = 0;
|
||||
let funcEnd = funcStart;
|
||||
let started = false;
|
||||
for (let i = funcStart; i < code.length; i++) {
|
||||
if (code[i] === '{') {
|
||||
braceCount++;
|
||||
started = true;
|
||||
} else if (code[i] === '}') {
|
||||
braceCount--;
|
||||
if (started && braceCount === 0) {
|
||||
funcEnd = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 找到 _0x56bd 函数
|
||||
const decoderStart = code.indexOf('function _0x56bd(');
|
||||
if (decoderStart === -1) {
|
||||
console.error('未找到 _0x56bd 函数');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let decBraceCount = 0;
|
||||
let decoderEnd = decoderStart;
|
||||
let decStarted = false;
|
||||
for (let i = decoderStart; i < code.length; i++) {
|
||||
if (code[i] === '{') {
|
||||
decBraceCount++;
|
||||
decStarted = true;
|
||||
} else if (code[i] === '}') {
|
||||
decBraceCount--;
|
||||
if (decStarted && decBraceCount === 0) {
|
||||
decoderEnd = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const arrayFunc = code.slice(funcStart, funcEnd);
|
||||
const decoderFunc = code.slice(decoderStart, decoderEnd);
|
||||
|
||||
console.log(`_0x4ff4 函数长度: ${arrayFunc.length}`);
|
||||
console.log(`_0x56bd 函数长度: ${decoderFunc.length}`);
|
||||
|
||||
// 在沙盒中执行
|
||||
const sandbox = {
|
||||
vip: 'cursor',
|
||||
console: console
|
||||
};
|
||||
|
||||
const vmCode = `
|
||||
var vip = 'cursor';
|
||||
${arrayFunc}
|
||||
${decoderFunc}
|
||||
|
||||
// 测试解码器
|
||||
var result = {};
|
||||
result._0x56bd = _0x56bd;
|
||||
result._0x4ff4 = _0x4ff4;
|
||||
result;
|
||||
`;
|
||||
|
||||
console.log('\n[1] 在沙盒中执行解码器...');
|
||||
let decoder;
|
||||
try {
|
||||
const script = new vm.Script(vmCode, { timeout: 30000 });
|
||||
const context = vm.createContext(sandbox);
|
||||
decoder = script.runInContext(context, { timeout: 30000 });
|
||||
console.log('解码器执行成功');
|
||||
} catch (e) {
|
||||
console.error('沙盒执行失败:', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 测试解码
|
||||
console.log('\n[2] 测试解码...');
|
||||
try {
|
||||
const test1 = decoder._0x56bd(0x532, 'ck7z');
|
||||
console.log(`测试 _0x56bd(0x532, 'ck7z') = "${test1}"`);
|
||||
} catch (e) {
|
||||
console.log('测试解码失败:', e.message);
|
||||
}
|
||||
|
||||
// 查找所有 _0x56bd 调用
|
||||
console.log('\n[3] 查找所有解码调用...');
|
||||
const callPattern = /_0x56bd\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/gi;
|
||||
const decodeMap = new Map();
|
||||
let match;
|
||||
let totalCalls = 0;
|
||||
|
||||
while ((match = callPattern.exec(code)) !== null) {
|
||||
const fullMatch = match[0];
|
||||
const indexHex = match[1];
|
||||
const key = match[2];
|
||||
totalCalls++;
|
||||
|
||||
if (!decodeMap.has(fullMatch)) {
|
||||
try {
|
||||
const index = parseInt(indexHex, 16);
|
||||
const decoded = decoder._0x56bd(index, key);
|
||||
if (decoded && typeof decoded === 'string') {
|
||||
decodeMap.set(fullMatch, decoded);
|
||||
}
|
||||
} catch (e) {
|
||||
// 跳过解码失败的
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`总调用数: ${totalCalls}, 唯一调用数: ${decodeMap.size}`);
|
||||
|
||||
// 替换
|
||||
console.log('\n[4] 替换编码字符串...');
|
||||
let newCode = code;
|
||||
let replaceCount = 0;
|
||||
|
||||
for (const [pattern, decoded] of decodeMap) {
|
||||
let replacement;
|
||||
// 处理特殊字符
|
||||
if (decoded.includes('\n') || decoded.includes('\r') || decoded.includes('`') || decoded.includes('${')) {
|
||||
replacement = JSON.stringify(decoded);
|
||||
} else if (decoded.includes("'") && !decoded.includes('"')) {
|
||||
replacement = `"${decoded}"`;
|
||||
} else if (decoded.includes('"') && !decoded.includes("'")) {
|
||||
replacement = `'${decoded}'`;
|
||||
} else {
|
||||
replacement = JSON.stringify(decoded);
|
||||
}
|
||||
|
||||
const before = newCode.length;
|
||||
newCode = newCode.split(pattern).join(replacement);
|
||||
if (newCode.length !== before) {
|
||||
replaceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`替换了 ${replaceCount} 个模式`);
|
||||
|
||||
// 清理代码
|
||||
console.log('\n[5] 清理代码...');
|
||||
|
||||
// 简化属性访问
|
||||
newCode = newCode.replace(/\['([a-zA-Z_$][a-zA-Z0-9_$]*)'\]/g, '.$1');
|
||||
|
||||
// 简化布尔值
|
||||
newCode = newCode.replace(/!!\[\]/g, 'true');
|
||||
newCode = newCode.replace(/!\[\]/g, 'false');
|
||||
|
||||
// 保存
|
||||
console.log('\n[6] 保存文件...');
|
||||
fs.writeFileSync(outputPath, newCode);
|
||||
console.log(`保存到: ${outputPath}`);
|
||||
console.log(`新文件大小: ${(newCode.length / 1024).toFixed(2)} KB`);
|
||||
|
||||
// 保存示例解码
|
||||
const sampleMap = {};
|
||||
let count = 0;
|
||||
for (const [k, v] of decodeMap) {
|
||||
if (count < 100 && v.length < 100) {
|
||||
sampleMap[k] = v;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync('D:/temp/破解/cursorpro-0.4.5/provider_sample_decode.json', JSON.stringify(sampleMap, null, 2));
|
||||
|
||||
console.log('\n✅ 完成!');
|
||||
Reference in New Issue
Block a user