Skip to content

Commit

Permalink
feat: 1. 增加makecode-high子命令 2. 增加basearr子命令
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenxianluo committed Apr 9, 2024
1 parent ae822c7 commit 7757ad5
Show file tree
Hide file tree
Showing 15 changed files with 528 additions and 80 deletions.
66 changes: 61 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,63 @@ Examples:

```

### 2.3. exec子命令
### 2.3. makecode-high子命令

执行子命令`makecode-high`生成cookie,解码两次请求返回的网站代码(功能涵盖makecode子命令),调用示例:

1. npx方式:`npx rs-reverse makecode-high -u url`
2. 文件方式:`node main.js makecode-high -u url`

该命令第一次请求生成cookie带入第二次请求,将两次请求返回的加密代码及动态代码解码后保存到`output/makecode-high`目录中,和makecode命令区别为该命令只提供-u方式执行!

```console
$ npx rs-reverse makecode-high -h
rs-reverse makecode-high

解码两次请求返回的网站代码(功能涵盖makecode子命令)

Options:
-h 显示帮助信息 [boolean]
-f
-l, --level 日志打印等级,参考log4js,默认为info [string]
-u, --url 瑞数返回204状态码的请求地址 [string] [required]
-a, --adapt 已经做了适配的网站名称,不传则为cnipa [string]
-v, --version 显示版本号 [boolean]

Examples:
rs-reverse makecode-high -u http://url/path
```

调用示例:

```bash
$ npx rs-reverse makecode-high -u https://wcjs.sbj.cnipa.gov.cn/sgtmi

第1次请求:

url方式提取的ts:/path/to/output/makecode-high/first/ts.json
url方式提取的静态文本:/path/to/output/makecode-high/first/immucfg.json
程序生成的ts:/path/to/output/makecode-high/first/ts-full.json
url方式提取的javascript代码:/path/to/output/makecode-high/first/cCdzB9ZjDFks.a728b22.js
url方式提取的html代码:/path/to/output/makecode-high/first/sgtmi.html
cCdzB9ZjDFks.a728b22.js生成的动态代码:/path/to/output/makecode-high/first/cCdzB9ZjDFks.a728b22-dynamic.js

第2次请求:

url方式提取的ts:/path/to/output/makecode-high/second/ts.json
url方式提取的静态文本:/path/to/output/makecode-high/second/immucfg.json
程序生成的ts:/path/to/output/makecode-high/second/ts-full.json
url方式提取的javascript代码:/path/to/output/makecode-high/second/cCdzB9ZjDFks.a728b22.js
url方式提取的html代码:/path/to/output/makecode-high/second/sgtmi.html
cCdzB9ZjDFks.a728b22.js生成的动态代码:/path/to/output/makecode-high/second/cCdzB9ZjDFks.a728b22-dynamic.js
url方式提取的javascript代码:/path/to/output/makecode-high/second/chunk-vendors.66e24864.js
url方式提取的javascript代码:/path/to/output/makecode-high/second/app.9f7a91c9.js
chunk-vendors.66e24864.js生成的解密代码:/path/to/output/makecode-high/second/chunk-vendors.66e24864-decrypt.js
app.9f7a91c9.js生成的解密代码:/path/to/output/makecode-high/second/app.9f7a91c9-decrypt.js

```

### 2.4. exec子命令

exec子命令用于开发中或者演示时使用。命令示例:

Expand Down Expand Up @@ -154,10 +210,10 @@ Examples:

适配文件配置在目录`./src/adapt/`下,已完成兼容配置:

网站 | 名称 | makecode | makecookie | 适配版本 | 是否逆向验证
---- | ---- | -------- | ---------- | -------- | --------------
商标网 | cnipa | 👌 | 👌 | - | Y
瑞数官网 | riversecurity | 👌 | 👌 | 版本1 | N
网站 | 名称 | makecode | makecookie | makecode-high | 适配版本 | 是否逆向验证
---- | ---- | -------- | ---------- | ------------- | -------- | --------------
商标网 | cnipa | 👌 | 👌 | 👌 | - | Y
瑞数官网 | riversecurity | 👌 | 👌 | N | 版本1 | N

以瑞数官网实例如:`npx rs-reverse makecookie -u https://www.riversecurity.com/resources.shtml -a riversecurity`

Expand Down
34 changes: 32 additions & 2 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const fs = require('fs');
const makeCode = require('@src/makeCode');
const makeCodeHigh = require('@src/makeCodeHigh');
const makeCookie = require('@src/makeCookie');
const basearrParse = require('@src/basearrParse');
const utils = require('@utils/');
const { logger, getCode } = utils;
const pkg = require(paths.package);
Expand Down Expand Up @@ -64,6 +65,7 @@ const commandHandler = (command, argv) => {
const ts = argv.url?.$_ts || argv.file || require(paths.exampleResolve('codes', `${gv.version}-\$_ts.json`));
logger.trace(`传入的$_ts.nsd: ${ts.nsd}`);
logger.trace(`传入的$_ts.cd: ${ts.cd}`);
gv._setAttr('argv', argv);
try {
if (argv.url) {
command(ts, adapt(argv.url, argv.adapt), argv.url);
Expand All @@ -88,8 +90,15 @@ module.exports = yargs
})
.command({
command: 'makecode-high',
describe: '生成动态代码-高级',
builder: commandBuilder,
describe: '解码两次请求返回的网站代码(功能涵盖makecode子命令)',
builder: {
...commandBuilder,
f: undefined,
u: {
...commandBuilder.u,
demandOption: true,
}
},
handler: commandHandler.bind(null, makeCodeHigh),
})
.command({
Expand Down Expand Up @@ -136,6 +145,27 @@ module.exports = yargs
console.log([`\n 输入:${argv.code}`, `输出:${output}\n`].join('\n '));
}
})
.command({
command: 'basearr',
describe: '接收压缩前数字数组的序列化文本并格式化解析',
builder: {
l: {
alias: 'level',
describe: '日志打印等级,参考log4js,默认为info',
type: 'string',
},
b: {
alias: 'basearr',
describe: '压缩前数字数组的序列化文本',
type: 'array',
demandOption: true,
}
},
handler: (argv) => {
debugLog(argv.level);
basearrParse(argv.basearr);
}
})
.updateStrings({
'Show version number': '显示版本号',
'Show help': '显示帮助信息',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"license": "ISC",
"dependencies": {
"cheerio": "^1.0.0-rc.12",
"fs-extra": "^11.2.0",
"jest": "^29.7.0",
"lodash": "^4.17.21",
"log4js": "^6.9.1",
Expand Down
6 changes: 3 additions & 3 deletions src/adapt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ module.exports = function({ jscode, url }, name) {
gv._setAttr('version', val);
return ans;
}
const idx = jscode.indexOf(val);
const idx = jscode.code.indexOf(val);
if (idx === -1) throw new Error(`${key}值数据未找到,请查看文档:src/adapt/readme.md`);
if (jscode.indexOf(val, idx + val.length) > -1) throw new Error(`${key}对应的值${val}在代码中非唯一,请检查!`);
const fullString = findFullString(jscode, val);
if (jscode.code.indexOf(val, idx + val.length) > -1) throw new Error(`${key}对应的值${val}在代码中非唯一,请检查!`);
const fullString = findFullString(jscode.code, val);
return { ...ans, [key]: fullString };
}, {});
}
Expand Down
165 changes: 165 additions & 0 deletions src/basearrParse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
const logger = require('@utils/logger');
const error = require('@utils/error');

const parseBlock = (item, id) => {
if (typeof id !== 'number') return { ...item, show: id };
const val = item.val;
let oper = 0;
const next = (val) => {
switch(val.type) {
case 'div':
oper += 1;
break;
case 'val':
case 'arr':
oper = val.idx + val.len;
break;
}
return val;
}
switch(id) {
case 0:
item.child = [
next(div(val, oper)),
next(value(val, oper, 1, 'window.navigator.maxTouchPoints')),
next(value(val, oper, 1, 'window.eval.toString().length')),
next(div(val, oper)),
next(value(val, oper, 4, 'window.navigator.userAgent')),
value(val, oper, 1, 'length'),
next(block(val, oper, 'window.navigator.platform')),
next(value(val, oper, 4, 'execNumberByTime')),
next(value(val, oper, 2, 'execRandomByNumber')),
next(div(val, oper)),
next(div(val, oper)),
next(value(val, oper, 4, '3136373737323136')),
next(value(val, oper, 4, '0')),
next(value(val, oper, 2, 'window.innerHeight')),
next(value(val, oper, 2, 'window.innerWidth')),
next(value(val, oper, 2, 'window.outerHeight')),
next(value(val, oper, 2, 'window.outerWidth')),
];
break;
case 1:
item.child = [
next(value(val, oper, 1, '0 < +ascii2string(gv.keys[24]) < 8')),
next(div(val, oper)),
next(value(val, oper, 4, 'r2mkaTime + runTime - startTime')),
next(value(val, oper, 4, '+ascii2string(gv.keys[19])')),
next(value(val, oper, 8, 'Math.floor(Math.random() * 1048575) * 4294967296 + (((currentTime + 1) & 4294967295) >>> 0)')),
next(value(val, oper, 1, '+ascii2string(gv.keys[24])')),
];
break;
case 2:
item.child = [
next(value(val, oper, 4, '16777216')),
next(value(val, oper, 4, '0')),
next(value(val, oper, 2, '5900')),
next(value(val, oper, 2, 'codeToStringUid')),
];
break;
case 4:
item.child = [ // 编号510方法执行返回
next(value(val, oper, 1, '1')),
next(value(val, oper, 2, '0')),
next(value(val, oper, 2, '0')),
next(value(val, oper, 1, 'window.document.hidden')),
next(value(val, oper, 8, 'encryptMode2(decrypt(ascii2string(gv.keys[22])), numarrAddTime(gv.keys[16])[0])')),
next(value(val, oper, 2, '+decode(decrypt(ascii2string(gv.keys[22])))')),
];
break;
case 5:
item.child = [
next(value(val, oper, 1, 'taskmap[ascii2string(gv.keys[29])]();')),
next(value(val, oper, 1, 'taskmap[ascii2string(gv.keys[30])]();')),
next(value(val, oper, 1, 'taskmap[ascii2string(gv.keys[31])]();')),
next(value(val, oper, 1, 'taskmap[ascii2string(gv.keys[32])]();')),
]
break;
case 6:
item.child = [
next(value(val, oper, 1, 'battery and connection operator')),
next(value(val, oper, 1, 'window.navigator.battery.level * 100')),
next(value(val, oper, 1, 'window.navigator.battery.chargingTime >> 8')),
next(value(val, oper, 1, 'window.navigator.battery.chargingTime & 255')),
next(value(val, oper, 1, 'window.navigator.connection')),
];
break;
}
return item;
}

function value(arr, oper, len, show) {
return {
show,
val: arr.slice(oper, oper + len),
idx: oper,
type: 'val',
len,
}
}

function block(arr, oper, id) {
const num = arr[oper++]
return parseBlock({ val: arr.slice(oper, num + oper), len: num, idx: oper, type: 'arr' }, id);
}

function div(arr, oper, show = '-------') {
return { show, val: arr[oper], idx: oper, type: 'div' };
}

function print(divarr, deep = 0, parentIdx = 0) {
divarr.forEach((it) => {
const idx = deep ? `(${it.idx}${it.idx + parentIdx})` : `(${it.idx})`;
console.log([new Array(deep * 4).fill(' ').join(''), idx, `[${it.val || '0'}]`, it.show].filter(Boolean).join(' '));
if (it.child) print(it.child, deep + 1, it.idx);
})
}

function parse(basearr) {
let oper = 0;
console.log('\n');
const next = (val) => {
if (!val) debugger;
switch(val.type) {
case 'div':
oper += 1;
break;
case 'val':
case 'arr':
oper = val.idx + val.len;
break;
}
return val;
}
print(new Array(8).fill('').reduce((ans, it, idx) => {
return [
...ans,
next(div(basearr, oper)),
value(basearr, oper, 1, 'length'),
next(block(basearr, oper, idx)),
];
}, []));
}

module.exports = function (basearrs) {
try {
basearrs = basearrs.map(it => {
basearr = JSON.parse(it);
if (!Array.isArray(basearr)) {
throw new Error('');
}
return basearr;
})
} catch (err) {
error('请传入序列化后的数字数组!');
}
basearrs.forEach(parse);
if (basearrs.length > 1) {
console.log('\n');
for (let i = 0, j = new Set(); i < Math.max(...basearrs.map(it => it.length)); i++) {
j.clear();
basearrs.forEach(it => j.add(it[i]));
if (j.size !== 1) console.log(`不同点下标${i}${basearrs.map(it => it[i]).join(' ')}`);
}
}
}
Loading

0 comments on commit 7757ad5

Please sign in to comment.