Files
cursornew2026/deobfuscate_provider_v8.js

210 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 动态反混淆 provider.js v8
* 包含 shuffle IIFE 以正确初始化数组
*/
const fs = require('fs');
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 动态反混淆工具 v8 ║');
console.log('╚════════════════════════════════════════════════════╝');
let code = fs.readFileSync(inputPath, 'utf8');
console.log(`读取文件: ${(code.length / 1024).toFixed(2)} KB`);
// 找到 _0x4ff4 函数的结束位置
const arrayFuncStart = code.indexOf('function _0x4ff4()');
let braceCount = 0;
let arrayFuncEnd = arrayFuncStart;
let started = false;
for (let i = arrayFuncStart; i < code.length; i++) {
if (code[i] === '{') {
braceCount++;
started = true;
} else if (code[i] === '}') {
braceCount--;
if (started && braceCount === 0) {
arrayFuncEnd = i + 1;
break;
}
}
}
// 找到 shuffle IIFE 的结束位置
let shuffleStart = arrayFuncEnd;
// 跳过空白和分号
while (code[shuffleStart] === ';' || code[shuffleStart] === '\n' || code[shuffleStart] === ' ' || code[shuffleStart] === '\r') {
shuffleStart++;
}
// 找到 IIFE 的结束
let parenCount = 0;
let shuffleEnd = shuffleStart;
if (code[shuffleStart] === '(') {
for (let i = shuffleStart; i < code.length; i++) {
if (code[i] === '(') parenCount++;
else if (code[i] === ')') {
parenCount--;
if (parenCount === 0) {
shuffleEnd = i + 1;
if (code[shuffleEnd] === ';') shuffleEnd++;
break;
}
}
}
}
console.log(`Shuffle IIFE: ${shuffleStart} - ${shuffleEnd}`);
// 提取完整的初始化代码(包括 _0x56bd, _0x4ff4, 和 shuffle IIFE
const initCode = code.slice(0, shuffleEnd);
console.log(`初始化代码长度: ${(initCode.length / 1024).toFixed(2)} KB`);
// 使用 eval 执行
console.log('\n[1] 使用 eval 执行初始化代码...');
// 全局变量
var vip = 'cursor';
var _0x56bd, _0x4ff4;
try {
eval(initCode);
console.log('初始化成功');
console.log(`_0x56bd 类型: ${typeof _0x56bd}`);
console.log(`_0x4ff4 类型: ${typeof _0x4ff4}`);
} catch (e) {
console.error('初始化失败:', e.message);
console.error(e.stack?.slice(0, 500));
process.exit(1);
}
// 测试解码
console.log('\n[2] 测试解码...');
try {
// 从 shuffle IIFE 中提取的测试用例
const tests = [
[0x5f6, 'yoC7'],
[0x3d2, 'iDwM'],
[0x14e, 'yoC7'],
[0x532, 'ck7z']
];
for (const [index, key] of tests) {
try {
const result = _0x56bd(index, key);
console.log(` _0x56bd(0x${index.toString(16)}, '${key}') = "${result?.slice(0, 50) || '(empty)'}${result?.length > 50 ? '...' : ''}"`);
} catch (e) {
console.log(` _0x56bd(0x${index.toString(16)}, '${key}') = ERROR: ${e.message}`);
}
}
} catch (e) {
console.log('测试解码失败:', e.message);
}
// 查找所有 _0x56bd 调用并解码
console.log('\n[3] 查找所有解码调用...');
const callPattern1 = /_0x56bd\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/gi;
const callPattern2 = /_0x56bd\s*\(\s*(0x[a-f0-9]+)\s*,\s*"([^"]*)"\s*\)/gi;
const decodeMap = new Map();
let match;
let totalCalls = 0;
let successCalls = 0;
// 匹配单引号
while ((match = callPattern1.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 = _0x56bd(index, key);
if (decoded && typeof decoded === 'string') {
decodeMap.set(fullMatch, decoded);
successCalls++;
}
} catch (e) {
// 跳过解码失败的
}
}
}
// 匹配双引号
while ((match = callPattern2.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 = _0x56bd(index, key);
if (decoded && typeof decoded === 'string') {
decodeMap.set(fullMatch, decoded);
successCalls++;
}
} catch (e) {
// 跳过
}
}
}
console.log(`总调用数: ${totalCalls}, 成功解码: ${successCalls}, 唯一模式: ${decodeMap.size}`);
// 显示一些解码样本
console.log('\n[4] 解码样本:');
let sampCount = 0;
for (const [pattern, decoded] of decodeMap) {
if (sampCount < 20) {
console.log(` => "${decoded.slice(0, 60)}${decoded.length > 60 ? '...' : ''}"`);
sampCount++;
}
}
// 替换
console.log('\n[5] 替换编码字符串...');
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[6] 清理代码...');
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[7] 保存文件...');
fs.writeFileSync(outputPath, newCode);
console.log(`保存到: ${outputPath}`);
console.log(`新文件大小: ${(newCode.length / 1024).toFixed(2)} KB`);
console.log('\n✅ 完成!');