164 lines
8.3 KiB
JavaScript
164 lines
8.3 KiB
JavaScript
/**
|
|
* CursorPro 反编译脚本 v4
|
|
* 直接执行原版解码逻辑
|
|
*/
|
|
const fs = require('fs');
|
|
|
|
// 读取原版代码
|
|
const code = fs.readFileSync('D:/temp/破解/cursorpro-0.4.5/原版本/extension/out/api/client.js', 'utf8');
|
|
|
|
// 字符串数组 - 直接从原版代码提取
|
|
var vip = 'cursor';
|
|
const _0x81f8 = function() {
|
|
const _0xb6f8e4 = (function() {
|
|
return [vip, 'XenNcturgdsoIeKrHRBCjEhRpemLPbyB==', 'W7mXWPBdNJZdL1O', 'yXhcLSkQWPa', 'EubBWPfh', 'WRNcKNekna', 'sd/cJCkmWOpdIW', 'W7qLW7bCkW', 'bmkbESkVWPK', 'WRBcVmkNWOldNfpcM0FdTsi', 'W6OCW4hcNCoNCua', 'acLXq0C', 'WROrW7NcS1Gw', 'W6aWW6H5pHiGW6v/WQ5Tb8k2WQmwga', 'nJrJW6ddUmogvCkeaHHyWOu', 'W6ehWRGiW48yfINcRahcOmkZnI8NmuO', 'WRZdOmoxFCky', 'Cmk8w8okW4DEcb7cQSk3WRpdVCk4WQC2WR0kC8oXCmkAW57dV8op', 'uNDGWPHyWRLXnmk1qCkNWQOne8odW7jZW5CcW5SZWOWOW4a', 'W78KAJNdLG', 'eCkJFqBcTCk0W53dGtvUlYWRWQ3dJCkBW6pdJSo3eSozWP7cSItdLd1nW5VdTdxdMejrW6C', 'dCoWWRbuW4KE', 'W7qUWO3dJI/dMa', 'WOORW5pcPLC', 'WOuWW5NcNLa', 'c8owW6m/', 'WQddQrRcHSkW', 'c8opWPpcTaO', 'W4tcNw8cs8koi281W4/dMX0TW5VdU1HKWRrfWPJdHmkHWQWbnSkp', 'DCkzW68eeW', 'WOe6W6ZcPve', 'iCoZWRftW5W3amovWQSF', 'jCosWPfVW6yGn8oHWPe+W6VdHq', 'k391WRVdKq', 'fCoHWOXIFCooWOzTWRxcL3i', 'nGH1A2jK', 'W4OautxdLq', 'F0zDWQbx', 'eMeBzSoYDLRdOSkLoxKx', 'W5xdOCotW7/dHW', 'umohahq2dthcJLj8FxlcV8kD', 'ddDyWOhcRa', 'W5LoWRbMt8klWRj0wa', 'r8kgxb3dLG', 'W5bwWPFcVNW', 'W60MW7nB', 'W6yNWORdUa7dKvpcI34rW64MW6ZcR8oNW5VcR8koW4JdUq', 'WQa+yulcNW', 'WQShW67cJ1KsWOn5iSoMW4SuW55OqNG', 'W6qEBW', 'WOtdLKPlWR/dJqJcGLO', 'ESoOo0GZ', 'W7CGW69D', 'WQ7dL3VcQKaiWQNdQSoWW5C', 'WRmPWQ9jBrP0W6O7', 'dmoTW6CbEa', 'W6uMWPSnW70', 'WOlcKNWheCkzi30', 'W7msWQG6W54CkZFcPGRcQSkZnI8NmuO', 'fSkqq8ktWQ5zjmkrpSk+FCkfhwRcPJKylW', '57+u57Uq6lYa5O2Y5Ash6lE477+36kYX5Qoo5PYF57YB57Mw', 'DSkuesZdUG', 'wNBcSrL4Fsrr', 'o8kigCksCSk6bW', 'WPpcUCoNiW0', 'FHNcSSkS', 'W5GkW7LgeGKHW6nNWP0', 'FCkQBWJdKa', 'WOZdNdveWO/cN8kbW6ZcNq', 'WRpcNSoDaedcTHO2dJpdPc3cOH3cOmkoWQtcQrL2WQFdK8oDxq', 'f8oJWRDvW4KqhSoc', 'W4utW5z+oG', 'Eaf/FSoW', 'AgKPWPtcOCkvFG', 'W4ZdISoWW6xdVq', 'omoAf8kLuMCVyc3cRSok', 'ivlcOtJcNeNcOW', 'fmoTW5WtBa', 'WQinFuxcOCoWnKJdR0NcRSoAy8kAW5K3z8kUBG', 'oSkeqCkWWQ4', 'aCoHWQ5nW4ere8otWQ0cW4dcRGRcJmkNnG', 'WRSvW5FcPwK', 'aMxcQaq2As1gq2ddM1pcISkVwW', 'W47cU8o9xmkuCXzn', 'e29dWORdLCk9zmoNcgCnW4rQWPVcGq', 'W7HEWOjAWPzhdmkG', 'jCoxWOtcLaRdM0Hm', 'WQ8dW5ZcNCoFDhNcNSkQ', 'WQRdVrr2WQdcT8kHW5dcUmkUFCo6', 'W6ddKSoCW7VdUW', 'g0fAWORdVa', 'WReCrMtcGa', 'W4urWRFdJW', 'f8k7W4eClCoeWPC', 'iCoCWPtcIX7dMeG', 'W4iLW512ea', 'pJTtr2y', 'kmkTx8keWQ4', 'tSk+nqZdHa', 'gNnKWR4aWQrej8k3xCkNWQSkrCoKW7HUW5izW5u', 'WORdUa/cJSkiW7nk', 'W5ddQCofC8o9sIbUgWyekG', 'ySk8xmoTW54', 'W4aqW4G', 'WQeEWQDhWQ8', 'WQVdPCoKW5NcPexcSuVdVsiYBINcSCkOW6JdHgfRyaSfW4m8WOi1WRWjWQpcKWab', 'd8oRWRHwW4e', 'CLVcVr5uCcXbrMm', 'FCkkW5pdJeZcJHH6Dmo2zmkqWQu', 'gCkay8kI', 'WR51tmk4pmk2WQtdJmkJjaG3cSoSWRJcO2apx8k3wSk3WOpcSCoNkLm', 'WQOwW6lcPCoM', 'W4tcNw8cs8koi281W4/dMX0TW5VdU1TSWRrtWOm', 'WRRcT0HaW4CDi8oEWPi', 'xZFdJCkLWQP4ySolWP7cHgbdW7/cJq', 'vsVdGSkHWR1P', 'amoqWQVcNbm', 'WRNcUgSNmG', 'CSoBESoDcW', 'WP3dSdz1WOu', 'p8o8W5yczSortSoMzCohe8oCnX4', 'umkWfJRdQa', 'EgJcIWDb', 'W5RdMSktW7ddN8o0W7BdVSkVWO3cNSkUwSo0hCokkW', 'CNWhW67dKeNdQHhdQmoCW4u', 'qgjWWRzBWRjYi8k7xmkUWR0kgCoeW7HUW5izW5u', 'h2xdLComW5xcImoJWOfZW5ZdKCkgW6G', 'cSkEeSoEcG', 'hCkBwCkJWQS', 'FCoSh1Op', 'nmo+tI9C', 'WPZdUSoqE8kMwq', 'dCkPEsddVSkbW7m', 'W5yNsaddRN4X', 'l8oOgCkZWOagysxcV8kUWQxdJSki', 'ASkFgSk+AmkomYtdSI0wWO3dSX8', 'wCkKFCoa', 'j1JcOYa', 'W5NcUWhdLviPWQNdKSob', 'WQddISkDW5FcJW', 'WRTji8obW7tdU2RcV2bcwCoE', 'W65wWQXV', 'WO3cNw9v', 'DN4iW6hdLdFcJaFdHmoXW7tdGCkk', 'WQxdRSk3', 'c8kXW4u6zSoXWRLbWPBcGNJdQmkcd8kVWRZcNhz1BW', 'W7msWQG6W54CkZFcPGRcQSkXoIiUlupdLai', 'uCoiefC0bWtcJW', 'iLlcSWRcJetcUSooECkonX/cLCkyzCkveq', 'WQ/dH8oMtG', 'Cb1PtSo6WPi8WQGhW5bpDa', 'kCo9u8orvCoCW6WRWRhcVIhdMspdLCoOWPJcU0VdGa', 'pCoSWOZcNdu', 'EIddICkOWOS', 'qvCHetpdOSo3ufrX', 'W6yPWO3dRZ7dNhpcHxeBW6G7W5K', 'WQShW67cK1iFWOD7iSogW4WHW4v2va'];
|
|
})();
|
|
return _0xb6f8e4;
|
|
};
|
|
|
|
// Base64解码 - 使用原版的非标准字母表
|
|
function base64Decode(str) {
|
|
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
|
|
let output = '';
|
|
let buffer = '';
|
|
|
|
for (let i = 0, charIndex; (charIndex = str.charAt(i++)); ~charIndex && (buffer = i % 4 ? buffer * 64 + charIndex : charIndex, i % 4) ? output += String.fromCharCode(0xff & buffer >> (-2 * i & 6)) : 0) {
|
|
charIndex = chars.indexOf(charIndex);
|
|
}
|
|
|
|
// URL decode
|
|
let result = '';
|
|
for (let i = 0; i < output.length; i++) {
|
|
result += '%' + ('00' + output.charCodeAt(i).toString(16)).slice(-2);
|
|
}
|
|
|
|
try {
|
|
return decodeURIComponent(result);
|
|
} catch (e) {
|
|
return output;
|
|
}
|
|
}
|
|
|
|
// RC4解密
|
|
function rc4Decrypt(str, key) {
|
|
let s = [];
|
|
let j = 0;
|
|
let result = '';
|
|
|
|
// 初始化 S盒
|
|
for (let i = 0; i < 256; i++) {
|
|
s[i] = i;
|
|
}
|
|
|
|
// KSA
|
|
for (let i = 0; i < 256; i++) {
|
|
j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
|
|
[s[i], s[j]] = [s[j], s[i]];
|
|
}
|
|
|
|
// PRGA
|
|
let x = 0;
|
|
j = 0;
|
|
for (let k = 0; k < str.length; k++) {
|
|
x = (x + 1) % 256;
|
|
j = (j + s[x]) % 256;
|
|
[s[x], s[j]] = [s[j], s[x]];
|
|
result += String.fromCharCode(str.charCodeAt(k) ^ s[(s[x] + s[j]) % 256]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// 解码函数 - 模拟 _0x3fbb
|
|
function decode(index, key) {
|
|
const array = _0x81f8();
|
|
const arrayIndex = index - 0x12e; // 302
|
|
|
|
if (arrayIndex < 0 || arrayIndex >= array.length) {
|
|
return `[OUT_OF_RANGE:${index}]`;
|
|
}
|
|
|
|
const encoded = array[arrayIndex];
|
|
const decoded = base64Decode(encoded);
|
|
const result = rc4Decrypt(decoded, key);
|
|
|
|
return result;
|
|
}
|
|
|
|
// 从代码中提取所有 _0x1ede40 和 _0x3fbb 调用
|
|
const callPattern = /_0x(?:1ede40|3fbb|355e79|4eb85c|182fa9|aaa62a|2df000|4fbc9f|de3d97|1b24d0|507ce6|36d9c0|15748f|1acc63|da86de|42cb20|3f99ea|eb43df|ac9b59|15aadd|12dfcf|42b4f6|1bebfa|5b4aa0|530ea9|207d6a|517f75)\s*\(\s*(0x[0-9a-fA-F]+)\s*,\s*'([^']+)'\s*\)/g;
|
|
|
|
console.log('=== CursorPro 原版代码解码 ===\n');
|
|
|
|
// 测试常用调用
|
|
const testCases = [
|
|
[0x18a, 'yC20', 'DEFAULT_API_URL'],
|
|
[0x151, 'pIfk', 'vscode require'],
|
|
[0x177, ']8Ci', 'workspace'],
|
|
[0x15b, 'j#7G', 'apiUrl config'],
|
|
[0x197, 'Kfdi', '/api/verify'],
|
|
[0x186, 'dpeu', 'POST'],
|
|
[0x141, 'z&uV', '/api/switch'],
|
|
[0x144, '*1hl', '__esModule'],
|
|
[0x1b6, 'mBo%', 'getApiUrl export'],
|
|
[0x146, 'pIfk', 'getOnlineStatus export'],
|
|
[0x145, 'j#7G', 'switchAccount export'],
|
|
[0x154, 'fjkd', 'updateProxyConfig export'],
|
|
[0x13e, '3nFX', 'getSeamlessStatus export'],
|
|
[0x193, 'HShS', 'getUserSwitchStatus export'],
|
|
[0x17f, 'fjkd', 'getSeamlessConfig export'],
|
|
[0x1c2, '0hHe', 'updateSeamlessConfig export'],
|
|
[0x1b7, 'csY!', 'injectSeamless export'],
|
|
[0x13c, 'fjkd', 'getSeamlessAccounts export'],
|
|
[0x173, 'j#7G', 'syncSeamlessAccounts export'],
|
|
[0x175, 'pIfk', 'getSeamlessToken export'],
|
|
[0x152, ')0X3', 'getLatestVersion export'],
|
|
[0x133, '3nFX', 'body'],
|
|
[0x19c, ']$%b', 'stringify'],
|
|
[0x172, ')0X3', 'json'],
|
|
[0x185, 'yC20', 'Content-Type'],
|
|
[0x181, '^UhV', 'offline message'],
|
|
];
|
|
|
|
const results = {};
|
|
for (const [index, key, desc] of testCases) {
|
|
try {
|
|
const decoded = decode(index, key);
|
|
results[desc] = decoded;
|
|
console.log(`${desc} (0x${index.toString(16)}, '${key}'): "${decoded}"`);
|
|
} catch (e) {
|
|
console.log(`${desc}: ERROR - ${e.message}`);
|
|
}
|
|
}
|
|
|
|
console.log('\n=== 关键解码信息 ===');
|
|
console.log('API 地址:', results['DEFAULT_API_URL']);
|
|
console.log('验证端点:', results['/api/verify']);
|
|
console.log('切换端点:', results['/api/switch']);
|
|
|
|
// 找出所有调用并解码
|
|
console.log('\n=== 扫描代码中的所有调用 ===');
|
|
let match;
|
|
const allDecoded = {};
|
|
const regex = /_0x[a-zA-Z0-9]+\s*\(\s*(0x[0-9a-fA-F]+)\s*,\s*'([^']+)'\s*\)/g;
|
|
|
|
while ((match = regex.exec(code)) !== null) {
|
|
const index = parseInt(match[1], 16);
|
|
const key = match[2];
|
|
const callStr = `${match[1]},'${key}'`;
|
|
|
|
if (!allDecoded[callStr]) {
|
|
try {
|
|
const decoded = decode(index, key);
|
|
allDecoded[callStr] = decoded;
|
|
} catch (e) {
|
|
allDecoded[callStr] = `ERROR: ${e.message}`;
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log('\n所有解码结果:');
|
|
for (const [call, decoded] of Object.entries(allDecoded)) {
|
|
console.log(` (${call}) => "${decoded}"`);
|
|
}
|