/**
 * CursorPro 完整反编译脚本
 * 解码所有混淆字符串并生成干净代码
 */
const fs = require('fs');

// 读取原版代码
const code = fs.readFileSync('D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/api/client.js', 'utf8');

// 设置 vip
var vip = 'cursor';

// 1. 定义 _0x81f8 函数
const func81f8Start = code.indexOf('function _0x81f8()');
const func81f8End = code.indexOf('return _0x81f8();}', func81f8Start) + 'return _0x81f8();}'.length;
const func81f8Code = code.substring(func81f8Start, func81f8End);
eval(func81f8Code);

// 2. 定义 _0x3fbb 函数
const func3fbbStart = code.indexOf('function _0x3fbb(');
const func3fbbEnd = code.indexOf(',_0x3fbb(_0x91e0a,_0x2e3a7e);}', func3fbbStart) + ',_0x3fbb(_0x91e0a,_0x2e3a7e);}'.length;
const func3fbbCode = code.substring(func3fbbStart, func3fbbEnd);
eval(func3fbbCode);

// 3. 执行混淆IIFE
const iifeStart = code.indexOf("const _0x1ede40=_0x3fbb;");
const iifeEnd = code.indexOf("var __createBinding");
let iifeCode = code.substring(iifeStart, iifeEnd).trim();
if (iifeCode.endsWith(';')) {
    iifeCode = iifeCode.slice(0, -1);
}
eval(iifeCode);

console.log('解码器初始化成功');
console.log('原版API地址:', _0x3fbb(0x18a, 'yC20'));

// 收集所有解码调用
const decode = _0x3fbb;
const decodedMap = new Map();

// 匹配所有解码调用: _0x变量名(0x数字, '字符串')
const regex = /_0x[a-zA-Z0-9]+\s*\(\s*(0x[0-9a-fA-F]+)\s*,\s*'([^']+)'\s*\)/g;

let match;
while ((match = regex.exec(code)) !== null) {
    const fullMatch = match[0];
    const index = parseInt(match[1], 16);
    const key = match[2];

    if (!decodedMap.has(fullMatch)) {
        try {
            const decoded = decode(index, key);
            decodedMap.set(fullMatch, decoded);
        } catch (e) {
            console.log(`解码失败: ${fullMatch} - ${e.message}`);
        }
    }
}

console.log(`\n共解码 ${decodedMap.size} 个字符串\n`);

// 输出所有解码结果
console.log('=== 解码映射表 ===');
const sortedEntries = [...decodedMap.entries()].sort((a, b) => a[1].localeCompare(b[1]));
for (const [call, decoded] of sortedEntries) {
    console.log(`${decoded.padEnd(40)} <- ${call}`);
}

// 保存映射表
const mapObj = {};
for (const [call, decoded] of decodedMap) {
    mapObj[call] = decoded;
}
fs.writeFileSync('D:/temp/破解/cursorpro-0.4.5/decoded_map.json', JSON.stringify(mapObj, null, 2));
console.log('\n映射表已保存到 decoded_map.json');

// 生成干净代码
let cleanCode = code;

// 替换所有解码调用
for (const [call, decoded] of decodedMap) {
    // 转义特殊字符
    const escapedCall = call.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
    const regex = new RegExp(escapedCall, 'g');

    // 正确转义字符串值
    const escapedDecoded = JSON.stringify(decoded);
    cleanCode = cleanCode.replace(regex, escapedDecoded);
}

// 移除混淆函数定义
// 移除 _0x81f8 函数
cleanCode = cleanCode.replace(/function _0x81f8\(\)\{[\s\S]*?return _0x81f8\(\);\}/, '');
// 移除 _0x3fbb 函数
cleanCode = cleanCode.replace(/function _0x3fbb\([\s\S]*?,_0x3fbb\(_0x91e0a,_0x2e3a7e\);\}/, '');
// 移除IIFE
const cleanIifeStart = cleanCode.indexOf("const _0x1ede40=");
const cleanIifeEnd = cleanCode.indexOf("var __createBinding");
if (cleanIifeStart >= 0 && cleanIifeEnd > cleanIifeStart) {
    cleanCode = cleanCode.substring(0, cleanIifeStart) + cleanCode.substring(cleanIifeEnd);
}
// 移除开头的 vip 声明
cleanCode = cleanCode.replace(/^var vip='cursor';'use strict';/, "'use strict';");

// 清理多余空白
cleanCode = cleanCode.replace(/\n\s*\n\s*\n/g, '\n\n');

// 保存干净代码
fs.writeFileSync('D:/temp/破解/cursorpro-0.4.5/client_clean.js', cleanCode);
console.log('干净代码已保存到 client_clean.js');

// 输出关键API信息
console.log('\n=== 关键API信息 ===');
console.log('DEFAULT_API_URL:', _0x3fbb(0x18a, 'yC20'));
console.log('/api/verify-key:', _0x3fbb(0x197, 'Kfdi'));
console.log('/api/switch-account:', _0x3fbb(0x141, 'z&uV'));

// 列出所有API端点
console.log('\n=== 所有API端点 ===');
const apiEndpoints = [...decodedMap.values()].filter(v => v.startsWith('/api/'));
apiEndpoints.forEach(ep => console.log(`  ${ep}`));
