mirror of
https://github.com/pysunday/rs-reverse.git
synced 2025-04-20 22:00:07 +08:00
feat: makecookie command support remote url gerente cookie
This commit is contained in:
parent
ccbcbcc3fa
commit
76e2d20d96
60
README.md
60
README.md
@ -1,4 +1,4 @@
|
|||||||
这个项目是瑞数加密的逆向研究,代码开发基于网站链接:`https://wcjs.sbj.cnipa.gov.cn/sgtmi`
|
该项目为瑞数加密的逆向研究,代码开发基于网站:`https://wcjs.sbj.cnipa.gov.cn/sgtmi`
|
||||||
|
|
||||||
研究包括动态代码生成原理及动态cookie生成原理。
|
研究包括动态代码生成原理及动态cookie生成原理。
|
||||||
|
|
||||||
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
## 0. 声明
|
## 0. 声明
|
||||||
|
|
||||||
该项目下代码仅用于个人学习、研究或欣赏。通过使用该仓库相关代码产生的风险与仓库代码作者无关。
|
该项目下代码仅用于个人学习、研究或欣赏。通过使用该仓库相关代码产生的风险与仓库代码作者无关!
|
||||||
|
|
||||||
|
该项目的研究网站仅做参考,项目不鼓励直接请求该研究网站,算法逆向研究请直接使用`example`目录下的样例文件,如:`node main.js makecookie -f example/codes/1-\$_ts.json`。
|
||||||
|
|
||||||
该瑞数cookie生成过程中的算法逆向仍存在以下问题:
|
该瑞数cookie生成过程中的算法逆向仍存在以下问题:
|
||||||
|
|
||||||
@ -22,7 +24,7 @@
|
|||||||
|
|
||||||
## 2. 瑞数算法还原
|
## 2. 瑞数算法还原
|
||||||
|
|
||||||
**`npx rs-reverse *`与在当前目录下运行`node main.js *`相对应**
|
**`npx rs-reverse *`与在当前目录下运行`node main.js *`相对应, 当然也支持npm全局安装(`npm install -g rs-reverse`),npm全局安装后也可以直接使用命令`rs-reverse`**
|
||||||
|
|
||||||
如npx运行的包不是最新的,可以加上-p参数后执行如:`npx -p rs-reverse@latest rs-reverse makecookie`,非官方源可能存在版本不同步问题,建议拉取时使用官方源:`--registry=https://registry.npmjs.org`。
|
如npx运行的包不是最新的,可以加上-p参数后执行如:`npx -p rs-reverse@latest rs-reverse makecookie`,非官方源可能存在版本不同步问题,建议拉取时使用官方源:`--registry=https://registry.npmjs.org`。
|
||||||
|
|
||||||
@ -35,10 +37,7 @@ npm包不能保证最新代码,最新代码以仓库代码为准!
|
|||||||
1. npx方式:`npx rs-reverse makecode`
|
1. npx方式:`npx rs-reverse makecode`
|
||||||
2. 文件方式:`node main.js makecode`
|
2. 文件方式:`node main.js makecode`
|
||||||
|
|
||||||
如运行:`npx rs-reverse makecode -u http://wcjs.sbj.cnipa.gov.cn/sgtmi`,后生成三个文件:
|
**命令后不接参数则从example文件中取**
|
||||||
|
|
||||||
1. 动态代码文件`output/dynamic-code.js`
|
|
||||||
2. `$_ts`文件`output/input_ts.json`和`output/output_ts.json`
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ npx rs-reverse makecode -h
|
$ npx rs-reverse makecode -h
|
||||||
@ -49,6 +48,7 @@ npm包不能保证最新代码,最新代码以仓库代码为准!
|
|||||||
Options:
|
Options:
|
||||||
-h 显示帮助信息 [boolean]
|
-h 显示帮助信息 [boolean]
|
||||||
-f, --file 含有nsd, cd值的json文件 [string]
|
-f, --file 含有nsd, cd值的json文件 [string]
|
||||||
|
-l, --level 日志打印等级,参考log4js,默认为info [string]
|
||||||
-u, --url 瑞数返回204状态码的请求地址 [string]
|
-u, --url 瑞数返回204状态码的请求地址 [string]
|
||||||
-v, --version 显示版本号 [boolean]
|
-v, --version 显示版本号 [boolean]
|
||||||
|
|
||||||
@ -60,24 +60,23 @@ Examples:
|
|||||||
调用示例:
|
调用示例:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ npx rs-reverse makecode
|
$ npx rs-reverse makecode -u https://wcjs.sbj.cnipa.gov.cn/sgtmi
|
||||||
|
|
||||||
输入ts:./output/output_ts.js
|
输出ts:/path/to/output/makecode_output_ts.json
|
||||||
输出ts:./output/output_ts.js
|
输出动态代码:/path/to/output/makecode_output_code.js
|
||||||
动态代码:./output/dynamic_code.js/input_ts.json
|
url方式提取的ts:/path/to/output/makecode_input_ts.json
|
||||||
|
url方式提取的静态文本:/path/to/output/makecode_input_immucfg.json
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.2. makecookie子命令
|
### 2.2. makecookie子命令
|
||||||
|
|
||||||
执行子命令`makecookie`生成动态代码, 可以传入包含`$_ts.nsd`和`$_ts.cd`的文本文件或者直接给url让程序自己去拿, 命令示例:
|
执行子命令`makecookie`生成cookie, 调用方式与`makecode`类型,调用示例:
|
||||||
|
|
||||||
1. npx方式:`npx rs-reverse makecookie`
|
1. npx方式:`npx rs-reverse makecookie`
|
||||||
2. 文件方式:`node main.js makecookie`
|
2. 文件方式:`node main.js makecookie`
|
||||||
|
|
||||||
该命令首先会执行`makecode`子命令拿到完整的`$_ts`值,再运行makecookie算法生成cookie。
|
该命令首先会执行`makecode`子命令拿到完整的`$_ts`值,再运行`makecookie`的还原算法生成cookie。
|
||||||
|
|
||||||
`makecookie`命令与`makecode`使用方式类似:
|
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ npx rs-reverse makecookie -h
|
$ npx rs-reverse makecookie -h
|
||||||
@ -88,7 +87,9 @@ rs-reverse makecookie
|
|||||||
Options:
|
Options:
|
||||||
-h 显示帮助信息 [boolean]
|
-h 显示帮助信息 [boolean]
|
||||||
-f, --file 含有nsd, cd值的json文件 [string]
|
-f, --file 含有nsd, cd值的json文件 [string]
|
||||||
|
-l, --level 日志打印等级,参考log4js,默认为info [string]
|
||||||
-u, --url 瑞数返回204状态码的请求地址 [string]
|
-u, --url 瑞数返回204状态码的请求地址 [string]
|
||||||
|
-a, --adapt 已经做了适配的网站名称,不传则为cnipa [string]
|
||||||
-v, --version 显示版本号 [boolean]
|
-v, --version 显示版本号 [boolean]
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@ -99,16 +100,19 @@ Examples:
|
|||||||
调用示例:
|
调用示例:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ npx rs-reverse makecookie
|
$ npx rs-reverse makecookie -u https://wcjs.sbj.cnipa.gov.cn/sgtmi
|
||||||
|
|
||||||
Cookie值: 06F5jRMo1hoEoEPOKmB6eAcYaJeWGRuYthzufuuJ4tkmcCMZLbouHGcYIm462aiARAwGlJIvr6M_vbi1K3kaer3n0ZE459rr3eKe8U.xTOaCdVxik6TW2XIle7cmudenUkPfU4UaEGoqOl8nAv38f_Qb_g6kZMpHn51J2qsIdscBqGgjQvcwWPFWk2r9SHbAJbRganpjSeTH1PksisGcKwHCFbHsXqYX1jAW672tcssl
|
url方式提取的ts:/path/to/output/makecookie_url_ts_1704391389883.json
|
||||||
|
url方式提取的静态文本:/path/to/output/makecookie_url_immutext_1704391389883.json
|
||||||
|
|
||||||
|
Cookie值: 0yk64LrpoFnc8Wi4Mmu_rijgRRoC2SHY1bQlR2_QZ805_CqRd1uOgGRnlEvHvXSoQuwkx_fwn4iQnPDFrQigm1b4GnD61Pf9vU5XKtJtAWIoWeG_22OLiccUwGjI0lQaJ_jaYIBFygNsPSPf_0GnJyT1umFrFgAkAoqh1s0G9IDE1uPEM3PV8M1J.wbKdSgMLg8T3bGD5w2sHHohKfnwsT7bMNbb8xbjSxsn8qb8AvY0
|
||||||
Cookie长: 236
|
Cookie长: 236
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.3. exec子命令
|
### 2.3. exec子命令
|
||||||
|
|
||||||
runcode子命令用于开发中或者演示时使用。命令示例:
|
exec子命令用于开发中或者演示时使用。命令示例:
|
||||||
|
|
||||||
1. npx方式:`npx rs-reverse exec -c 'gv.cp2'`
|
1. npx方式:`npx rs-reverse exec -c 'gv.cp2'`
|
||||||
2. 文件方式:`node main.js exec -c 'gv.cp2'`
|
2. 文件方式:`node main.js exec -c 'gv.cp2'`
|
||||||
@ -132,27 +136,15 @@ Examples:
|
|||||||
调用示例:
|
调用示例:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ npm rs-reverse exec -c '+ascii2string(gv.keys[21])'
|
$ npx rs-reverse exec -c '+ascii2string(gv.keys[21])'
|
||||||
|
|
||||||
输入:+ascii2string(gv.keys[21])
|
输入:+ascii2string(gv.keys[21])
|
||||||
输出:1718026159
|
输出:1718026159
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 手动获取动态代码和$_ts的方法
|
## 3. 技术交流
|
||||||
|
|
||||||
目录`example/codes/`下的文件为手动保存,用于验证代码功能,如运行:`npm run test`后会比对程序生成的动态代码与`$_ts`文件是否与相关静态文件文本内容一致。
|
加作者微信进技术交流群: `howduudu_tech`(备注rs-reverse)
|
||||||
|
|
||||||
当然也可以自己手动拿动态代码和$_ts以验证程序是否还有效,可以通过控制台拿到相关文本:
|
|
||||||
|
|
||||||
1. 在文件中`http://wcjs.sbj.cnipa.gov.cn/c5rxzYrjRT2h/cCdzB9ZjDFks.294cc83.js`找到代码`_$_q.call(_$gP, _$_y)`并打入断点(文件找不到可以通过其它两种方法定位);
|
|
||||||
2. 找到如第一条的js文件,搜索`.call(`找到调用方法;
|
|
||||||
2. 通过代理cookie变动的方式打断点通过堆栈找到调用方法。
|
|
||||||
|
|
||||||
断点后复制相关文本:
|
|
||||||
|
|
||||||
1. 拿到动态代码:`copy(_$_y)`
|
|
||||||
2. 拿到`$_ts`: `console.log(JSON.stringify(window.$_ts))`,这里有点蒙,可以用`JSON.stringify(window.$_ts)`或者`copy(JSON.stringify(window.$_ts))`试试
|
|
||||||
|
|
||||||
*初始的`$_ts`可以在这个文件入口处打断点获取。*
|
|
||||||
|
|
||||||
|
**后续开源补环境框架群内第一时间通知**
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rs-reverse",
|
"name": "rs-reverse",
|
||||||
"version": "1.1.3",
|
"version": "1.2.0",
|
||||||
"description": "瑞数算法逆向,website reverse engineering",
|
"description": "瑞数算法逆向,website reverse engineering",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -44,7 +44,10 @@ class GlobalVarible {
|
|||||||
// 返回密钥集合
|
// 返回密钥集合
|
||||||
return cache.keys;
|
return cache.keys;
|
||||||
}
|
}
|
||||||
setAttr(attr, value) {
|
_getAttr(attr) {
|
||||||
|
return cache[attr];
|
||||||
|
}
|
||||||
|
_setAttr(attr, value) {
|
||||||
cache[attr] = value;
|
cache[attr] = value;
|
||||||
if (attr === 'cp0') {
|
if (attr === 'cp0') {
|
||||||
cache.cp0_96 = _chunk(value, 96);
|
cache.cp0_96 = _chunk(value, 96);
|
||||||
|
@ -48,6 +48,6 @@ function makeBignum() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exports.init = function() {
|
exports.init = function() {
|
||||||
gv.setAttr('bignum', makeBignum());
|
gv._setAttr('bignum', makeBignum());
|
||||||
gv.setAttr('cfgnum', makeCfgnum());
|
gv._setAttr('cfgnum', makeCfgnum());
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@ module.exports = function(...params) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = []) {
|
function dynamicExec(taskItem, start = 0, args = [], loop_res = {}, global_res = {}) {
|
||||||
args = monitor(args, 'args', { getLog: true, setLog: true });
|
const { key, taskarr: task } = taskItem;
|
||||||
loop_res = monitor(loop_res, 'loop_res', { getLog: true, setLog: true, getCb: (key) => {if(['81', '83'].includes(key))debugger}});
|
args = monitor(args, '${key}_args', { getLog: true, setLog: true });
|
||||||
global_res = monitor(global_res, 'global_res', { getLog: true, setLog: true });
|
loop_res = monitor(loop_res, `${key}_loop_res`, { getLog: true, setLog: true });
|
||||||
if (typeof task === 'string') task = gv.r2mka(task).taskarr;
|
global_res = monitor(global_res, `${key}_global_res`, { getLog: true, setLog: true });
|
||||||
logger.trace(`动态代码运行,任务列表:${task}, 起点:${start},长度:${task.length}`);
|
logger.trace(`动态代码运行,任务列表:${key}, 起点:${start},长度:${task.length}`);
|
||||||
const data = [];
|
const data = [];
|
||||||
const ret = [];
|
const ret = [];
|
||||||
ret[0] = args;
|
ret[0] = args;
|
||||||
@ -32,7 +32,7 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
const len = task.length;
|
const len = task.length;
|
||||||
const notCheckTask = [11, 15, 27, 32, 48, 51, 59, 84, 104, 109];
|
const notCheckTask = [11, 15, 27, 32, 48, 51, 59, 84, 104, 109];
|
||||||
for (t_cursor = start; t_cursor < len; t_cursor++) {
|
for (t_cursor = start; t_cursor < len; t_cursor++) {
|
||||||
// console.log(`${notCheckTask.includes(task[t_cursor]) ? '[no]' : '[ok]'}【${++runtimes}, ${t_cursor}】运行 case(${task[t_cursor]})`);
|
logger.trace(`${notCheckTask.includes(task[t_cursor]) ? '[no]' : '[ok]'}【${++runtimes}, ${t_cursor}】${key} 运行 case(${task[t_cursor]})`);
|
||||||
switch (task[t_cursor]) {
|
switch (task[t_cursor]) {
|
||||||
case 0:
|
case 0:
|
||||||
temp1 = data[--d_cursor];
|
temp1 = data[--d_cursor];
|
||||||
@ -89,7 +89,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
case 11:
|
case 11:
|
||||||
// temp3 = task[++t_cursor];
|
// temp3 = task[++t_cursor];
|
||||||
// data[d_cursor++] = ret[3][temp3][task[++t_cursor]];
|
// data[d_cursor++] = ret[3][temp3][task[++t_cursor]];
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
return data[--d_cursor];
|
return data[--d_cursor];
|
||||||
@ -107,7 +106,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
case 15:
|
case 15:
|
||||||
// temp3 = task[++t_cursor];
|
// temp3 = task[++t_cursor];
|
||||||
// data[d_cursor++] = ret[1][temp3][task[++t_cursor]];
|
// data[d_cursor++] = ret[1][temp3][task[++t_cursor]];
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
d_cursor--;
|
d_cursor--;
|
||||||
@ -189,7 +187,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
case 32:
|
case 32:
|
||||||
// _$cG(_$$I, task[++t_cursor], task[++t_cursor], temp2 = task[++t_cursor], task[++t_cursor], t_cursor + 1, ret[2], ret);
|
// _$cG(_$$I, task[++t_cursor], task[++t_cursor], temp2 = task[++t_cursor], task[++t_cursor], t_cursor + 1, ret[2], ret);
|
||||||
// ret[4] ? t_cursor = len : t_cursor += temp2;
|
// ret[4] ? t_cursor = len : t_cursor += temp2;
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 33:
|
case 33:
|
||||||
tarkey = task[++t_cursor];
|
tarkey = task[++t_cursor];
|
||||||
@ -271,7 +268,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
case 48:
|
case 48:
|
||||||
// tarkey = task[++t_cursor];
|
// tarkey = task[++t_cursor];
|
||||||
// data[d_cursor++] = _$_w(_$$I._$hW[tarkey], ret);
|
// data[d_cursor++] = _$_w(_$$I._$hW[tarkey], ret);
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 49:
|
case 49:
|
||||||
d_cursor -= 2;
|
d_cursor -= 2;
|
||||||
@ -289,7 +285,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
// d_cursor -= temp2;
|
// d_cursor -= temp2;
|
||||||
// setTarget();
|
// setTarget();
|
||||||
// data[d_cursor++] = _$fH(target[tarkey], temp4);
|
// data[d_cursor++] = _$fH(target[tarkey], temp4);
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 52:
|
case 52:
|
||||||
temp1 = data[--d_cursor];
|
temp1 = data[--d_cursor];
|
||||||
@ -325,7 +320,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
// temp1 = _$kG[tarkey];
|
// temp1 = _$kG[tarkey];
|
||||||
// task[t_cursor] = temp1;
|
// task[t_cursor] = temp1;
|
||||||
// data[d_cursor++] = temp1;
|
// data[d_cursor++] = temp1;
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 60:
|
case 60:
|
||||||
temp1 = data[--d_cursor];
|
temp1 = data[--d_cursor];
|
||||||
@ -446,7 +440,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
// temp2 = target[temp1];
|
// temp2 = target[temp1];
|
||||||
// temp2 == _$an ? temp2 = task[++t_cursor] : ++t_cursor;
|
// temp2 == _$an ? temp2 = task[++t_cursor] : ++t_cursor;
|
||||||
// t_cursor += temp2;
|
// t_cursor += temp2;
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 85:
|
case 85:
|
||||||
setTarget();
|
setTarget();
|
||||||
@ -543,7 +536,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
// temp3 = task[++t_cursor];
|
// temp3 = task[++t_cursor];
|
||||||
// tarkey = task[++t_cursor];
|
// tarkey = task[++t_cursor];
|
||||||
// target = ret[1][temp3];
|
// target = ret[1][temp3];
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 105:
|
case 105:
|
||||||
tarkey = task[++t_cursor];
|
tarkey = task[++t_cursor];
|
||||||
@ -571,7 +563,6 @@ function dynamicExec(task, start = 0, args = [], loop_res = [], global_res = [])
|
|||||||
// d_cursor -= temp2;
|
// d_cursor -= temp2;
|
||||||
// setTarget();
|
// setTarget();
|
||||||
// temp1 = _$fH(target[tarkey], temp4);
|
// temp1 = _$fH(target[tarkey], temp4);
|
||||||
notCheckTask.push(task[t_cursor]);
|
|
||||||
break;
|
break;
|
||||||
case 110:
|
case 110:
|
||||||
temp1 = data[--d_cursor];
|
temp1 = data[--d_cursor];
|
||||||
|
@ -4,8 +4,8 @@ const logger = require('@utils/logger');
|
|||||||
|
|
||||||
function init(ts, r2mkaText) {
|
function init(ts, r2mkaText) {
|
||||||
const startTime = new Date().getTime();
|
const startTime = new Date().getTime();
|
||||||
gv.setAttr('utils', common);
|
gv._setAttr('utils', common);
|
||||||
gv.setAttr('ts', ts);
|
gv._setAttr('ts', ts);
|
||||||
require('./r2mka').init(r2mkaText);
|
require('./r2mka').init(r2mkaText);
|
||||||
require('./tscp').init();
|
require('./tscp').init();
|
||||||
require('./tscd').init();
|
require('./tscd').init();
|
||||||
|
@ -37,6 +37,7 @@ const parse = (() => {
|
|||||||
} else {
|
} else {
|
||||||
val.taskarr = str.split('').map(it => it.charCodeAt());
|
val.taskarr = str.split('').map(it => it.charCodeAt());
|
||||||
}
|
}
|
||||||
|
val.taskori = val.taskarr; // taskarr会被动态修改,因此存一个备份
|
||||||
val.key = `${deeps.join('>')}-${count++}`;
|
val.key = `${deeps.join('>')}-${count++}`;
|
||||||
valMap[val.key] = val;
|
valMap[val.key] = val;
|
||||||
val.child_one.map((it, idx) => {
|
val.child_one.map((it, idx) => {
|
||||||
@ -85,6 +86,6 @@ exports.parse = function(str = gt3) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.init = function(r2mkaText) {
|
exports.init = function(r2mkaText) {
|
||||||
gv.setAttr('r2mka', exports.parse(r2mkaText || gt3));
|
gv._setAttr('r2mka', exports.parse(r2mkaText || gt3));
|
||||||
logger.debug('头r2mka标识字符串完成解析!')
|
logger.debug('头r2mka标识字符串完成解析!')
|
||||||
}
|
}
|
||||||
|
7
src/handler/parser/task/index.js
Normal file
7
src/handler/parser/task/index.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
const gv = require('@src/handler/globalVarible');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
'0>one>21-23': (num) => {
|
||||||
|
return Math.abs(num) % gv.cp2[52];
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ const decrypt = require('./common/decrypt');
|
|||||||
const logger = require('@utils/logger');
|
const logger = require('@utils/logger');
|
||||||
const numToNumarr4 = require('./common/numToNumarr4');
|
const numToNumarr4 = require('./common/numToNumarr4');
|
||||||
const dynamicExec = require('./common/dynamicExec');
|
const dynamicExec = require('./common/dynamicExec');
|
||||||
|
const custask = require('./task');
|
||||||
|
const error = require('@utils/error');
|
||||||
|
|
||||||
function getValMaps() {
|
function getValMaps() {
|
||||||
let uid = gv.ts.cp[3];
|
let uid = gv.ts.cp[3];
|
||||||
@ -18,52 +20,51 @@ function getValMaps() {
|
|||||||
function parse(arr) {
|
function parse(arr) {
|
||||||
const len = arr.length;
|
const len = arr.length;
|
||||||
const valMap = getValMaps();
|
const valMap = getValMaps();
|
||||||
let idx = 0;
|
let idx = 4;
|
||||||
const task = [57, 132, 132, 132, 132, 132, 132].reverse();
|
|
||||||
do {
|
do {
|
||||||
// 逻辑概率来源为:idx初始值为4,此处为idx += gv.cp2[2], 如果之后task有变可尝试固定为该逻辑
|
idx += gv.cp2[2];
|
||||||
idx += gv.cp2[gv.r2mka("0>one>5-5").taskarr[task.pop()]];
|
|
||||||
const mod = idx % (len - idx > gv.cp2[2] ? gv.cp2[2] : len - idx);
|
const mod = idx % (len - idx > gv.cp2[2] ? gv.cp2[2] : len - idx);
|
||||||
arr[mod + idx] ^= valMap[mod];
|
if (mod + idx < arr.length) {
|
||||||
} while (idx < len && task.length);
|
arr[mod + idx] ^= valMap[mod];
|
||||||
|
}
|
||||||
|
} while (idx < len);
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTaskarr(arr, idx, ans = []) {
|
function getTaskarr(arr, idx, ans = {}) {
|
||||||
if (idx >= arr.length) return;
|
if (idx >= arr.length) return;
|
||||||
const start = idx + 1;
|
const start = idx + 1;
|
||||||
const end = start + arr[idx];
|
const end = start + arr[idx];
|
||||||
ans.push(arr.slice(start, end));
|
const key = arr[idx - 2];
|
||||||
|
ans[key] = gv.r2mka().child_one[key].taskarr = arr.slice(start, end);
|
||||||
getTaskarr(arr, end + 2, ans);
|
getTaskarr(arr, end + 2, ans);
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getOffset(arr) {
|
function getOffset(arr) {
|
||||||
const [task0, task1, task2, task3] = getTaskarr(arr, arr[3]);
|
const taskMap = getTaskarr(arr, arr[3]);
|
||||||
logger.trace([task0, task1, task3]);
|
|
||||||
const l81 = gv.r2mka("0-0").taskarr[42] + gv.cp2[56];
|
const l81 = gv.r2mka("0-0").taskarr[42] + gv.cp2[56];
|
||||||
const l83 = (gv.cp0_96(1, gv.r2mka("0-0").taskarr[57]).charCodeAt() + l81) * l81;
|
const l82 = gv.cp0_96(1, gv.r2mka("0-0").taskarr[57]).charCodeAt() + l81;
|
||||||
const offset = dynamicExec('0>one>22-24', 0, undefined, {
|
const l83 = l82 * l81;
|
||||||
20: function(...params) {
|
const global_res = {
|
||||||
return dynamicExec(task0, 0, params, {
|
|
||||||
8: function (...params) {
|
|
||||||
return dynamicExec(task1, 0, params);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
8: function(...params) {
|
|
||||||
return dynamicExec(task1, 0, params);
|
|
||||||
},
|
|
||||||
10: function(...params) {
|
|
||||||
return dynamicExec(task3, 0, params);
|
|
||||||
},
|
|
||||||
81: l81,
|
|
||||||
83: l83,
|
|
||||||
}, {
|
|
||||||
59: gv.cp2,
|
59: gv.cp2,
|
||||||
|
};
|
||||||
|
const loop_res = gv.r2mka().child_one.map((it, idx) => {
|
||||||
|
if (!it) return it;
|
||||||
|
return (...params) => {
|
||||||
|
if (taskMap[idx]) {
|
||||||
|
return dynamicExec(it, 0, params, loop_res, global_res);
|
||||||
|
}
|
||||||
|
if (custask[it.key]) {
|
||||||
|
return custask[it.key](...params);
|
||||||
|
}
|
||||||
|
error(1000, { key: it.key }); // 任务方法未适配终止方法运行
|
||||||
|
}
|
||||||
})
|
})
|
||||||
return offset;
|
loop_res[81] = l81;
|
||||||
|
loop_res[82] = l82;
|
||||||
|
loop_res[83] = l83;
|
||||||
|
return dynamicExec(gv.r2mka('0>one>22-24'), 0, undefined, loop_res, global_res);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.init = function() {
|
exports.init = function() {
|
||||||
@ -72,8 +73,10 @@ exports.init = function() {
|
|||||||
const end = (cdArr[0] << gv.cp2[52] | cdArr[1]) + start;
|
const end = (cdArr[0] << gv.cp2[52] | cdArr[1]) + start;
|
||||||
const one = parse(cdArr.slice(start, end)); // arr127
|
const one = parse(cdArr.slice(start, end)); // arr127
|
||||||
const offset = getOffset(one);
|
const offset = getOffset(one);
|
||||||
|
gv._setAttr('dynamicTaskOffset', offset);
|
||||||
|
gv._setAttr('dynamicTask', getTaskarr(one, one[3]));
|
||||||
const ans = cdArr.slice(end).map((item, idx) => { // arr1575
|
const ans = cdArr.slice(end).map((item, idx) => { // arr1575
|
||||||
return item ^ offset[idx % gv.cp2[52]];
|
return item ^ offset[idx % gv.cp2[52]];
|
||||||
})
|
})
|
||||||
const keys = []
|
const keys = []
|
||||||
for (let i = 0, op = 1; i < ans[0]; i ++) {
|
for (let i = 0, op = 1; i < ans[0]; i ++) {
|
||||||
@ -81,6 +84,6 @@ exports.init = function() {
|
|||||||
keys.push(ans.slice(op, op + gap));
|
keys.push(ans.slice(op, op + gap));
|
||||||
op += gap;
|
op += gap;
|
||||||
}
|
}
|
||||||
gv.setAttr('keys', keys);
|
gv._setAttr('keys', keys);
|
||||||
logger.debug('$_ts.cd完成解析!')
|
logger.debug('$_ts.cd完成解析!')
|
||||||
};
|
};
|
||||||
|
@ -4,8 +4,8 @@ const parse = require('./common/main');
|
|||||||
const logger = require('@utils/logger');
|
const logger = require('@utils/logger');
|
||||||
|
|
||||||
exports.init = function() {
|
exports.init = function() {
|
||||||
gv.setAttr('cp0', parse(gv.ts.cp[0]));
|
gv._setAttr('cp0', parse(gv.ts.cp[0]));
|
||||||
gv.setAttr('cp2', parse(gv.ts.cp[2]).map(Number));
|
gv._setAttr('cp2', parse(gv.ts.cp[2]).map(Number));
|
||||||
gv.setAttr('cp6', parse(gv.ts.cp[6]));
|
gv._setAttr('cp6', parse(gv.ts.cp[6]));
|
||||||
logger.debug('$_ts.cp完成解析!')
|
logger.debug('$_ts.cp完成解析!')
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ const Cookie = require('./handler/Cookie');
|
|||||||
const unescape = require('@utils/unescape');
|
const unescape = require('@utils/unescape');
|
||||||
const paths = require('@utils/paths');
|
const paths = require('@utils/paths');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const gv = require('@src/handler/globalVarible');
|
||||||
|
|
||||||
function parseR2mka(text) {
|
function parseR2mka(text) {
|
||||||
const start = text.indexOf('"') + 1;
|
const start = text.indexOf('"') + 1;
|
||||||
@ -32,6 +33,7 @@ function writefile(ts, immucfg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function (ts, immucfg) {
|
module.exports = function (ts, immucfg) {
|
||||||
|
gv._setAttr('_ts', ts);
|
||||||
if (immucfg) writefile(ts, immucfg);
|
if (immucfg) writefile(ts, immucfg);
|
||||||
const startTime = new Date().getTime();
|
const startTime = new Date().getTime();
|
||||||
const coder = new Coder(ts, immucfg);
|
const coder = new Coder(ts, immucfg);
|
||||||
|
14
utils/error.js
Normal file
14
utils/error.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
const gv = require('@src/handler/globalVarible');
|
||||||
|
const logger = require('./logger');
|
||||||
|
|
||||||
|
const errorMap = {
|
||||||
|
9999: '未知报错!',
|
||||||
|
1000: '解码cd值发现未定义任务方法',
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(type, data = {}) {
|
||||||
|
Object.assign(data, gv._getAttr('_ts'));
|
||||||
|
data.errType = type;
|
||||||
|
logger.fatal(`(${type})程序出错啦,请将该段报错文本贴到issue中:${JSON.stringify(data)}`);
|
||||||
|
throw new Error(errorMap[type || 9999])
|
||||||
|
}
|
@ -13,7 +13,7 @@ const appDirectory = (() => {
|
|||||||
const resolveApp = (...relativePath) => path.resolve(appDirectory, ...relativePath);
|
const resolveApp = (...relativePath) => path.resolve(appDirectory, ...relativePath);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
basePath: resolveApp(''),
|
basePath: resolveApp('.'),
|
||||||
modulePath: resolveApp('node_modules'),
|
modulePath: resolveApp('node_modules'),
|
||||||
binPath: resolveApp('node_modules', '.bin'),
|
binPath: resolveApp('node_modules', '.bin'),
|
||||||
package: resolveApp('package.json'),
|
package: resolveApp('package.json'),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user