备份: 完整开发状态(含反混淆脚本和临时文件)

This commit is contained in:
ccdojox-crypto
2025-12-17 17:18:02 +08:00
parent 9e2333c90c
commit 7e9ea173a7
2872 changed files with 326818 additions and 249 deletions

290
direct_decode.js Normal file
View File

@@ -0,0 +1,290 @@
/**
* 直接解码脚本 - 使用 RC4 + 非标准 Base64 算法
* 不依赖沙盒执行,直接实现解码逻辑
*/
const fs = require('fs');
const path = require('path');
const baseDir = 'D:/temp/破解/cursorpro-0.4.5';
// 非标准 Base64 字母表 (小写在前)
const BASE64_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
/**
* 非标准 Base64 解码
*/
function base64Decode(str) {
let result = '';
let buffer = 0;
let bufferLen = 0;
for (let i = 0; i < str.length; i++) {
const char = str[i];
const charIndex = BASE64_CHARS.indexOf(char);
if (charIndex === -1) continue;
if (charIndex === 64) continue; // '=' padding
buffer = (buffer << 6) | charIndex;
bufferLen += 6;
if (bufferLen >= 8) {
bufferLen -= 8;
result += String.fromCharCode((buffer >> bufferLen) & 0xFF);
}
}
return result;
}
/**
* RC4 解密
*/
function rc4Decrypt(data, key) {
// 初始化 S-box
const s = [];
for (let i = 0; i < 256; i++) {
s[i] = i;
}
let j = 0;
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]];
}
// 加密/解密
let result = '';
let i = 0;
j = 0;
for (let k = 0; k < data.length; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
[s[i], s[j]] = [s[j], s[i]];
result += String.fromCharCode(data.charCodeAt(k) ^ s[(s[i] + s[j]) % 256]);
}
return result;
}
/**
* 解码单个字符串
*/
function decodeString(encodedStr, key) {
try {
const base64Decoded = base64Decode(encodedStr);
const decrypted = rc4Decrypt(base64Decoded, key);
return decrypted;
} catch (e) {
return null;
}
}
/**
* 提取字符串数组
*/
function extractStringArray(code) {
// 查找字符串数组 - 这是一个大的嵌套数组
const arrayMatch = code.match(/return\s*\[([^\]]*(?:\]\.concat\(function\s*\(\)\s*\{\s*return\s*\[[^\]]*\][^\}]*\}\(\)\))*[^\]]*)\]/s);
if (!arrayMatch) return null;
// 提取所有字符串
const strMatch = code.match(/return\s*\['([^']*)'(?:,'([^']*)')*\]/g);
if (!strMatch) return null;
const strings = [];
const allStrings = code.match(/'[^']*'/g) || [];
// 找到字符串数组的开始位置
const arrayStart = code.indexOf("const _0x") || code.indexOf("function _0x");
const arrayEnd = code.indexOf("Object.defineProperty(exports");
if (arrayStart !== -1 && arrayEnd !== -1) {
const arraySection = code.substring(arrayStart, arrayEnd);
// 提取这个区域内所有带引号的字符串
const stringMatches = arraySection.match(/'([^'\\]*(\\.[^'\\]*)*)'/g) || [];
for (const match of stringMatches) {
const str = match.slice(1, -1); // 移除引号
if (str.length > 3 && /^[a-zA-Z0-9+/=]+$/.test(str)) {
strings.push(str);
}
}
}
console.log(` 提取了 ${strings.length} 个候选编码字符串`);
return strings;
}
/**
* 为文件生成解码映射
*/
function generateDecodeMapForFile(code, filename) {
console.log(`\n处理: ${filename}`);
console.log('='.repeat(50));
// 找到所有解码函数调用
const callPattern = /(_0x[a-f0-9]+)\s*\(\s*(0x[a-f0-9]+)\s*,\s*'([^']*)'\s*\)/g;
const calls = new Map();
let match;
while ((match = callPattern.exec(code)) !== null) {
const fullMatch = match[0];
const funcName = match[1];
const numHex = match[2];
const key = match[3];
calls.set(fullMatch, { funcName, numHex, key, num: parseInt(numHex, 16) });
}
console.log(` 找到 ${calls.size} 个唯一调用`);
// 提取字符串数组
// 找到类似这样的模式:
// return [vip, 'encodedStr1', 'encodedStr2', ...]
const stringArrayMatch = code.match(/return\s*\[\s*vip\s*,\s*('[^']*'(?:\s*,\s*'[^']*')*)\s*\]/);
let stringArray = ['cursor']; // vip = 'cursor'
if (stringArrayMatch) {
const stringsSection = stringArrayMatch[1];
const strings = stringsSection.match(/'([^']*)'/g);
if (strings) {
for (const s of strings) {
stringArray.push(s.slice(1, -1));
}
}
console.log(` 提取了 ${stringArray.length} 个数组元素`);
} else {
// 尝试另一种模式 - concat 嵌套数组
const concatPattern = /return\s*\[([^\]]*)\]\.concat/g;
const allArrays = [];
let cm;
while ((cm = concatPattern.exec(code)) !== null) {
const content = cm[1];
const strings = content.match(/'([^']*)'/g);
if (strings) {
for (const s of strings) {
allArrays.push(s.slice(1, -1));
}
}
}
if (allArrays.length > 0) {
stringArray = ['cursor', ...allArrays];
console.log(` 通过 concat 提取了 ${stringArray.length} 个数组元素`);
}
}
// 如果无法提取数组,返回空
if (stringArray.length < 10) {
console.log(' 无法提取足够的字符串数组');
return null;
}
// 尝试解码
const decodeMap = {};
let successCount = 0;
for (const [fullMatch, info] of calls) {
const { num, key } = info;
// 计算实际索引(减去偏移量)
// 不同文件的偏移量不同,需要尝试
for (let offset = 0; offset <= 0x200; offset += 0x10) {
const adjustedIndex = num - offset;
if (adjustedIndex >= 0 && adjustedIndex < stringArray.length) {
const encodedStr = stringArray[adjustedIndex];
const decoded = decodeString(encodedStr, key);
if (decoded && decoded.length > 0 && /^[\x20-\x7E\u4e00-\u9fff]+$/.test(decoded)) {
decodeMap[fullMatch] = decoded;
successCount++;
break;
}
}
}
}
console.log(` 成功解码: ${successCount}/${calls.size}`);
return decodeMap;
}
/**
* 使用已有的解码器脚本为每个文件生成映射
*/
async function generateWithExistingDecoder(inputPath, outputPath, filename) {
console.log(`\n处理: ${filename}`);
console.log('='.repeat(50));
if (fs.existsSync(outputPath)) {
const existing = JSON.parse(fs.readFileSync(outputPath, 'utf8'));
console.log(` 已存在: ${Object.keys(existing).length} 条映射`);
return existing;
}
// 读取代码
const code = fs.readFileSync(inputPath, 'utf8');
// 查找解码器函数名
const decoderMatch = code.match(/function\s+(_0x[a-f0-9]+)\s*\(\s*_0x[a-f0-9]+\s*,\s*_0x[a-f0-9]+\s*\)\s*\{/);
if (!decoderMatch) {
console.log(' 未找到解码函数');
return null;
}
const decoderFuncName = decoderMatch[1];
console.log(` 解码函数: ${decoderFuncName}`);
// 收集所有调用
const callPattern = new RegExp(
`(_0x[a-f0-9]+)\\s*\\(\\s*(0x[a-f0-9]+)\\s*,\\s*'([^']*)'\\s*\\)`,
'g'
);
const calls = new Set();
let match;
while ((match = callPattern.exec(code)) !== null) {
calls.add(match[0]);
}
console.log(` 找到 ${calls.size} 个调用`);
// 对于没有映射的文件,我们需要用不同的方法
// 使用之前成功的解码器代码片段
return { size: calls.size, decoder: decoderFuncName };
}
// 主函数
async function main() {
console.log('╔════════════════════════════════════════════════════╗');
console.log('║ 直接解码映射生成器 ║');
console.log('║ 使用 RC4 + 非标准 Base64 ║');
console.log('╚════════════════════════════════════════════════════╝');
const files = [
{ input: '原版本/extension/out/utils/account.js', output: 'account_decoded_map.json' },
{ input: '原版本/extension/out/utils/sqlite.js', output: 'sqlite_decoded_map.json' },
{ input: '原版本/extension/out/api/client.js', output: 'client_decoded_map.json' }
];
for (const file of files) {
const inputPath = path.join(baseDir, file.input);
const outputPath = path.join(baseDir, file.output);
if (!fs.existsSync(inputPath)) {
console.log(`\n跳过: ${file.input} (不存在)`);
continue;
}
const code = fs.readFileSync(inputPath, 'utf8');
const decodeMap = generateDecodeMapForFile(code, file.input);
if (decodeMap && Object.keys(decodeMap).length > 0) {
fs.writeFileSync(outputPath, JSON.stringify(decodeMap, null, 2));
console.log(` 已保存: ${outputPath}`);
}
}
console.log('\n完成');
}
main().catch(console.error);