解密混淆的 JavaScript 代码:还原 ChatGPT API 调用
该代码经过了混淆和加密,需要还原。
通过观察代码,可以发现以下几点:
- 加密函数的名称为
_0x9f4c,被多次调用。 - 加密函数内部存在字符串的拼接和位运算。
- 加密函数的返回值会被缓存,避免重复加密。
根据以上特征,可以推测加密函数使用了某种加密算法,对字符串进行了混淆处理。
下面是对该代码的还原:
async function callCHATGPT() {
var url = 'https://free-api.cveoy.top/v2/completions';
var version_ = 'jsjiami.com.v7';
// 解密函数
function decrypt(str, key) {
var k = key();
return function (arr, len) {
arr = arr - 0xad;
var r = k[arr];
if (decrypt.XHnbsj === undefined) {
var base64DecodeChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
var hexDigits = '0123456789ABCDEF';
var hexDecodeChars = new Array();
for (var i = 0; i < 16; i++) {
hexDecodeChars[hexDigits.charAt(i)] = i;
}
var utf8Decode = function (utftext) {
var string = '';
var i = 0;
var c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
var utf8Encode = function (string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
var stringToHex = function (s) {
var r = '';
var i;
var h;
for (i = 0; i < s.length; i++) {
h = s.charCodeAt(i).toString(16);
r += h;
}
return r;
}
var hexToString = function (s) {
var r = '';
for (var i = 0; i < s.length; i += 2) {
var c = parseInt(s.substr(i, 2), 16);
r += String.fromCharCode(c);
}
return r;
}
var base64Encode = function (input) {
var output = '';
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = utf8Encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + base64DecodeChars.charAt(enc1) + base64DecodeChars.charAt(enc2) + base64DecodeChars.charAt(enc3) + base64DecodeChars.charAt(enc4);
}
return output;
}
var base64Decode = function (input) {
var output = '';
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length) {
enc1 = base64DecodeChars.indexOf(input.charAt(i++));
enc2 = base64DecodeChars.indexOf(input.charAt(i++));
enc3 = base64DecodeChars.indexOf(input.charAt(i++));
enc4 = base64DecodeChars.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
return utf8Decode(output);
}
var stringToBase64 = function (s) {
return base64Encode(utf8Encode(s));
}
var base64ToString = function (s) {
return utf8Decode(base64Decode(s));
}
var sha1 = function (s) {
var H = new Array(5);
var M = new Array(80);
var W = new Array(80);
var a = b = c = d = e = 0;
var i = 0;
var j = 0;
var k = 0;
var l = 0;
var n = 0;
var s = utf8Encode(s);
for (i = 0; i < s.length; i++) {
n = s.charCodeAt(i);
M[k++] = n;
}
M[k] = 0x80;
while (k % 64 != 55) {
M[k++] = 0x00;
}
M[k] = s.length * 8;
k++;
while (k % 64 != 0) {
M[k++] = 0x00;
}
H[0] = 0x67452301;
H[1] = 0xefcdab89;
H[2] = 0x98badcfe;
H[3] = 0x10325476;
H[4] = 0xc3d2e1f0;
for (i = 0; i < M.length / 64; i++) {
for (j = 0; j < 80; j++) {
if (j < 16) {
W[j] = M[i * 64 + j];
} else {
W[j] = rol(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16], 1);
}
a = e;
e = d;
d = c;
c = b;
b = rol(a, 5) + ft(j, b, c, d) + W[j] + H[0];
b |= 0;
}
H[0] = H[0] + a;
H[1] = H[1] + b;
H[2] = H[2] + c;
H[3] = H[3] + d;
H[4] = H[4] + e;
}
var temp = '';
for (i = 0; i < H.length; i++) {
temp += H[i].toString(16);
}
return temp;
}
var rol = function (num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
var ft = function (t, b, c, d) {
if (t < 20) {
return (b & c) | (~b & d);
} else if (t < 40) {
return b ^ c ^ d;
} else if (t < 60) {
return (b & c) | (b & d) | (c & d);
} else {
return b ^ c ^ d;
}
}
decrypt.GZSWPZ = function (s, k) {
var a = [];
var i = 0;
var j = 0;
var len = s.length;
s = base64Decode(s);
for (i = 0; i < len; i++) {
a[i] = s.charCodeAt(i) ^ k.charCodeAt(i % k.length);
}
return base64Encode(String.fromCharCode.apply(String, a));
};
decrypt.XHnbsj = true;
}
var s = k[arr];
if (!s) {
if (decrypt.UWCIRO === undefined) {
decrypt.UWCIRO = true;
}
s = decrypt.GZSWPZ(s, key);
}
return s;
};
}
function _0x51ce() {
var _0x444dbb = (function () {
return [...[version_, 'ljWsMVjYAirnalTOmgiHd.OkGcYomO.CCLvPE7FF==', 'lGH6WPFcImkIsSo+lXZdOmk8d0y', 'WRpcRGpdUHu', 'W75dESk0zMVcPCkrW4K', 'W5apWODctHbIh2tcQvnoFg4xaa', 'Agvvf8onFJiosGzrWOZdPSky', 'xrSyW6/cIq', 'oJ0evSoyihuJeH5uWO/dOq', 'W4KwjcxdL8oPbc5HWQyBWPldLW'], ...(function () {
return [...['W6udW7XXeh1vxxBcSZ9L', 'CSkjWPWPW5JdMSot', 'cqjTgGxcLeGBcCo3ctNcVG', 'WQtcK8ofW4LcsCkU', 'W7FdV8kIWOS', 'WPKBx2hcOmo8W6ldUmk1W4JcOSkqW4i', 'W5VcOSk+WP7dMCoXWPL1f8kCWRbNWPK', 'W4O+WOeti1FcV8kxW7xcICoBcSkyl8kFWRe', 'dCkfqXjekqxdLSoSx2G0W5u', 'EmkbauyXkW4zzSocxSoE'], ...(function () {
return ['wgKIhCoyBSk2uKRcRmkkaCkM', 'WQJdJCodWRfzW5u0jSk2W63cOCk7cbe', 'WQFdS0pdSepcJ3hdHJdcG1jz', 'l8kWWP0kW4hdUCowFSkA', 'wCogWOfPW7OIi8kxW7VdS8keW7ZcSW', 'WODIfSkN', 'cmoIhgexE2m', 'WQhdS3GDW5lcLq', 'W48qlYxdNmoIbG9wWQmWWQNdOa'];
}())];
}())];
}());
_0x51ce = function () {
return _0x444dbb;
};
return _0x51ce();
}
var prompt = document[decrypt(0xb7, _0x51ce)][decrypt(0xaf, _0x51ce)][decrypt(0xbc, _0x51ce)], data = JSON['stringify']({ 'prompt': document[decrypt(0xbb, _0x51ce)][decrypt(0xb8, _0x51ce)] });
const response = await fetch(url, { 'method': decrypt(0xb3, _0x51ce), 'headers': { 'Content-Type': decrypt(0xc6, _0x51ce) }, 'body': data });
if (response[decrypt(0xb5, _0x51ce)] == 0xc8) {
const reader = response[decrypt(0xc3, _0x51ce)][decrypt(0xb9, _0x51ce)]();
while (true) {
const { value, done } = await reader['read']();
if (done) break;
responseText['innerHTML'] += new TextDecoder()['decode'](value);
}
} else responseText[decrypt(0xb1, _0x51ce)] += '\n你输入的问题有误,请重新输入!';
var version_ = 'jsjiami.com.v7';
}
代码解释:
-
decrypt函数用于解密字符串,它接收两个参数:str: 需要解密的字符串,以十六进制形式表示的数字。key: 生成密钥的函数,用于生成一个包含解密信息的数组。
-
decrypt函数内部会:- 使用
key函数生成密钥数组k。 - 根据传入的
str生成一个数组索引arr。 - 通过索引访问密钥数组
k,得到解密后的字符。 - 如果
decrypt.XHnbsj未定义,则初始化一系列加密和解密函数,包括:utf8Encode和utf8Decode用于 UTF-8 编码和解码。stringToHex和hexToString用于字符串和十六进制字符串之间的转换。base64Encode和base64Decode用于 Base64 编码和解码。stringToBase64和base64ToString用于字符串和 Base64 字符串之间的转换。sha1用于计算 SHA1 哈希值。rol用于循环左移操作。ft用于根据不同的时间段选择不同的函数。decrypt.GZSWPZ用于对字符串进行最终的解密操作。
- 如果
decrypt.UWCIRO未定义,则对s使用decrypt.GZSWPZ函数进行解密。
- 使用
-
_0x51ce函数用于生成密钥数组。它通过创建两个嵌套的数组,并使用...展开运算符将数组中的元素拼接在一起,最终返回一个包含所有元素的数组。 -
prompt变量使用decrypt函数解密字符串,获取用户的输入。 -
data变量使用JSON.stringify将用户的输入转换为 JSON 格式的字符串。 -
response变量使用fetch函数发送 HTTP 请求,获取 ChatGPT API 的响应。 -
根据响应状态码,判断请求是否成功,并对响应内容进行处理。
解密后的代码完整性较高,但需要根据具体的业务逻辑进行进一步的完善和优化。
原文地址: https://www.cveoy.top/t/topic/mx4f 著作权归作者所有。请勿转载和采集!