fiddler定位到cookie m。
通过hook cookie
定位到:
document[$b('\x30\x78\x36\x34', '\x47\x4e\x47\x28') + $b('\x30\x78\x64\x37', '\x64\x73\x5e\x52')] = f[$b('\x30\x78\x66\x66', '\x47\x28\x6a\x44') + '\x48\x75'](f[$b('\x30\x78\x31\x31\x30', '\x64\x37\x37\x42') + '\x48\x75']('\x6d\x3d', f['\x4c\x4a\x78' + '\x44\x57'](m, 0x1)[$b('\x30\x78\x31\x32\x36', '\x37\x6a\x34\x62') + $b('\x30\x78\x64\x30', '\x49\x4f\x29\x37') + '\x6e\x67']()), res) + ('\x3b\x20\x70' + $b('\x30\x78\x34\x65', '\x63\x6a\x57\x36') + '\x3d\x2f');
是赋值的位置。
使用AST:AST explorer
结构很清晰:前3项是数组还原及调用还原。前3项js取出,命名为:9_1_array_revert.js。
后三项取出,命名为9_mid-1.js,并生成对应的json
node JsToJson.js 9_mid-1.js 9_mid-1.json
需要用到的脚本:
// js 转 json
const fs = require('fs');
const esprima = require('esprima')
const escodegen = require('escodegen')
const input_text = process.argv[2];
const output_text = process.argv[3];
const data = fs.readFileSync(input_text);
const ast = esprima.parseScript(data.toString());
const ast_to_json = JSON.stringify(ast);
fs.writeFileSync(output_text, ast_to_json);
// json 转 js
const fs = require('fs');
const esprima = require('esprima')
const escodegen = require('escodegen')
const input_text = process.argv[2];
const output_text = process.argv[3];
const data = fs.readFileSync(input_text);
const ast = JSON.parse(data.toString());
const code = escodegen.generate(ast, {
format: {
compact: true,
escapeless: true
}
});
fs.writeFileSync(output_text, code);
一、大数组还原
直接浏览器中执行,即可得到$a的值,因为有格式化校验,若格式化,需要去除对应的检查,否则会死循环。
$a=['\x4a\x73\x4b\x54\x77\x6f\x34\x3d','\x4e\x32\x37\x43\x75\x77\x3d\x3d','\x77\x6f\x46\x2f\x77\x6f\x63\x3d','\x51\x42\x55\x32','\x77\x72\x74\x76\x77\x36\x59\x3d','\x77\x70\x5a\x4b\x66\x67\x3d\x3d','\x77\x6f\x4c\x43\x6f\x79\x34\x3d','\x77\x71\x46\x52\x64\x41\x3d\x3d','\x46\x55\x7a\x43\x73\x77\x3d\x3d','\x77\x37\x6b\x6f\x59\x67\x3d\x3d','\x4f\x77\x56\x6b','\x77\x72\x34\x71\x63\x77\x3d\x3d','\x4c\x6d\x6e\x44\x76\x41\x3d\x3d','\x77\x35\x6b\x39\x55\x41\x3d\x3d','\x77\x37\x55\x41\x61\x51\x3d\x3d','\x53\x45\x76\x44\x6d\x41\x3d\x3d','\x77\x35\x67\x4a\x4f\x77\x3d\x3d','\x77\x6f\x6f\x35\x77\x72\x30\x3d','\x77\x6f\x46\x78\x77\x36\x49\x3d','\x77\x37\x68\x71\x77\x34\x30\x3d','\x77\x70\x54\x44\x6f\x73\x4b\x68','\x57\x38\x4f\x57\x46\x67\x3d\x3d','\x45\x38\x4f\x6d\x46\x41\x3d\x3d','\x65\x7a\x63\x53','\x77\x34\x59\x72\x77\x37\x45\x3d','\x65\x31\x59\x76','\x77\x70\x67\x56\x77\x71\x6f\x3d','\x77\x34\x34\x7a\x58\x41\x3d\x3d','\x46\x47\x4c\x44\x73\x77\x3d\x3d','\x77\x71\x41\x33\x4f\x51\x3d\x3d','\x77\x70\x58\x44\x67\x4d\x4b\x46','\x55\x73\x4f\x4d\x48\x41\x3d\x3d','\x4b\x63\x4b\x33\x77\x70\x77\x3d','\x4d\x47\x48\x43\x75\x41\x3d\x3d','\x77\x70\x30\x46\x77\x72\x4d\x3d','\x53\x56\x46\x64','\x77\x6f\x64\x65\x4b\x77\x3d\x3d','\x77\x6f\x56\x4d\x66\x51\x3d\x3d','\x77\x6f\x64\x36\x4b\x51\x3d\x3d','\x56\x67\x49\x35','\x77\x70\x44\x44\x6c\x63\x4b\x54','\x4f\x78\x30\x31','\x4e\x77\x74\x79','\x77\x70\x62\x43\x67\x30\x73\x3d','\x77\x71\x6e\x43\x67\x4d\x4f\x64','\x44\x46\x73\x61','\x59\x57\x55\x31','\x77\x35\x38\x64\x77\x35\x67\x3d','\x77\x6f\x6e\x44\x69\x63\x4b\x79','\x77\x35\x30\x74\x41\x51\x3d\x3d','\x50\x63\x4b\x6f\x77\x6f\x30\x3d','\x77\x70\x64\x64\x66\x67\x3d\x3d','\x55\x47\x77\x69','\x77\x70\x33\x43\x67\x45\x73\x3d','\x77\x6f\x35\x45\x64\x77\x3d\x3d','\x4e\x77\x51\x71','\x77\x36\x6b\x45\x66\x77\x3d\x3d','\x49\x44\x30\x52','\x77\x37\x78\x45\x77\x37\x77\x3d','\x42\x4d\x4f\x36\x5a\x51\x3d\x3d','\x77\x35\x77\x62\x77\x37\x34\x3d','\x57\x33\x38\x35','\x77\x35\x67\x53\x50\x41\x3d\x3d','\x77\x34\x73\x64\x77\x6f\x73\x3d','\x77\x6f\x73\x55\x77\x72\x55\x3d','\x77\x37\x51\x5a\x77\x34\x51\x3d','\x43\x41\x7a\x43\x6b\x41\x3d\x3d','\x49\x42\x66\x43\x74\x67\x3d\x3d','\x77\x6f\x52\x4f\x77\x37\x67\x3d','\x42\x44\x34\x75','\x4f\x46\x30\x66','\x44\x63\x4b\x34\x54\x41\x3d\x3d','\x46\x38\x4b\x41\x77\x71\x6f\x3d','\x50\x7a\x30\x61','\x62\x46\x2f\x44\x6a\x41\x3d\x3d','\x4a\x4d\x4b\x36\x77\x72\x51\x3d','\x77\x34\x73\x68\x56\x51\x3d\x3d','\x62\x46\x42\x54','\x4f\x38\x4b\x70\x77\x36\x51\x3d','\x5a\x55\x6f\x5a','\x42\x73\x4b\x78\x77\x72\x6b\x3d','\x57\x32\x30\x63','\x77\x6f\x66\x43\x73\x73\x4f\x72','\x77\x36\x67\x68\x45\x67\x3d\x3d','\x77\x71\x7a\x44\x75\x63\x4b\x65','\x77\x72\x66\x43\x6a\x4d\x4f\x43','\x45\x4d\x4b\x66\x77\x70\x77\x3d','\x56\x4d\x4f\x56\x48\x67\x3d\x3d','\x41\x6d\x44\x44\x71\x77\x3d\x3d','\x77\x36\x70\x6f\x4d\x77\x3d\x3d','\x77\x71\x58\x44\x73\x68\x51\x3d','\x77\x36\x51\x47\x5a\x67\x3d\x3d','\x77\x34\x31\x30\x43\x67\x3d\x3d','\x77\x70\x52\x65\x57\x67\x3d\x3d','\x45\x57\x66\x43\x72\x51\x3d\x3d','\x50\x73\x4b\x77\x77\x37\x6f\x3d','\x61\x58\x73\x57','\x77\x6f\x67\x74\x45\x41\x3d\x3d','\x77\x71\x78\x66\x77\x71\x77\x3d','\x77\x34\x48\x43\x6d\x42\x63\x3d','\x77\x36\x48\x43\x6a\x63\x4b\x4d','\x58\x51\x45\x66','\x77\x37\x6c\x4c\x4f\x67\x3d\x3d','\x77\x36\x48\x43\x67\x44\x63\x3d','\x77\x36\x78\x43\x77\x36\x73\x3d','\x43\x4d\x4b\x66\x77\x36\x59\x3d','\x77\x72\x72\x44\x69\x68\x67\x3d','\x51\x4d\x4b\x74\x64\x41\x3d\x3d','\x61\x6d\x68\x41','\x77\x36\x2f\x43\x6e\x79\x73\x3d','\x5a\x55\x44\x44\x68\x51\x3d\x3d','\x77\x35\x34\x7a\x58\x67\x3d\x3d','\x77\x36\x78\x51\x77\x36\x73\x3d','\x77\x71\x67\x31\x61\x77\x3d\x3d','\x48\x6d\x33\x44\x74\x67\x3d\x3d','\x45\x4d\x4b\x46\x77\x35\x6f\x3d','\x4b\x4d\x4b\x66\x77\x34\x6b\x3d','\x4f\x73\x4b\x45\x77\x6f\x41\x3d','\x55\x30\x6a\x44\x6a\x77\x3d\x3d','\x77\x71\x7a\x44\x75\x63\x4b\x2b','\x77\x72\x70\x4a\x77\x34\x6b\x3d','\x77\x36\x72\x43\x70\x38\x4f\x54','\x77\x37\x6a\x43\x76\x73\x4f\x43','\x77\x70\x76\x44\x6f\x41\x38\x3d','\x77\x6f\x46\x59\x77\x37\x34\x3d','\x4c\x6e\x44\x44\x72\x67\x3d\x3d','\x77\x6f\x74\x31\x77\x36\x49\x3d','\x77\x70\x4c\x43\x73\x63\x4f\x63','\x55\x6c\x37\x44\x67\x77\x3d\x3d','\x49\x53\x39\x42','\x77\x71\x31\x50\x45\x77\x3d\x3d','\x63\x73\x4f\x6b\x4e\x77\x3d\x3d','\x44\x67\x33\x43\x70\x77\x3d\x3d','\x62\x55\x5a\x33','\x77\x35\x68\x31\x46\x67\x3d\x3d','\x77\x35\x77\x62\x77\x34\x67\x3d','\x77\x37\x68\x4c\x44\x77\x3d\x3d','\x4f\x54\x77\x56','\x56\x79\x6a\x43\x76\x77\x3d\x3d','\x44\x6c\x64\x32','\x77\x34\x54\x43\x6c\x63\x4f\x68','\x41\x6e\x58\x44\x71\x41\x3d\x3d','\x77\x6f\x73\x6c\x77\x35\x59\x3d','\x77\x70\x6e\x44\x73\x54\x51\x3d','\x57\x73\x4f\x65\x58\x67\x3d\x3d','\x77\x34\x73\x41\x77\x35\x6f\x3d','\x48\x57\x39\x76','\x77\x70\x2f\x43\x6a\x63\x4b\x78','\x47\x41\x6a\x43\x6b\x41\x3d\x3d','\x77\x36\x4e\x5a\x77\x36\x63\x3d','\x77\x36\x72\x44\x70\x4d\x4f\x45','\x77\x35\x58\x44\x67\x79\x6f\x3d','\x4d\x78\x35\x6b','\x77\x35\x4d\x66\x77\x71\x55\x3d','\x77\x70\x66\x44\x6e\x63\x4b\x73','\x42\x47\x7a\x44\x73\x77\x3d\x3d','\x77\x71\x74\x68\x56\x51\x3d\x3d','\x77\x37\x58\x44\x6d\x73\x4b\x55','\x77\x37\x67\x55\x77\x36\x63\x3d','\x4a\x6b\x66\x44\x6e\x77\x3d\x3d','\x56\x46\x4c\x44\x69\x41\x3d\x3d','\x43\x4d\x4b\x43\x77\x70\x6f\x3d','\x43\x6c\x2f\x43\x6f\x41\x3d\x3d','\x77\x70\x42\x73\x77\x36\x77\x3d','\x56\x78\x51\x39','\x47\x73\x4b\x4b\x77\x71\x34\x3d','\x64\x52\x67\x2f','\x4e\x6b\x49\x6a','\x77\x36\x35\x52\x77\x37\x63\x3d','\x77\x6f\x58\x44\x72\x54\x77\x3d','\x77\x72\x6c\x50\x49\x67\x3d\x3d','\x77\x72\x50\x44\x73\x4d\x4b\x50','\x45\x77\x35\x72','\x63\x56\x45\x67','\x48\x41\x76\x43\x6f\x51\x3d\x3d','\x77\x71\x44\x44\x68\x73\x4b\x65','\x77\x36\x6e\x44\x6d\x73\x4f\x50','\x77\x34\x77\x73\x51\x67\x3d\x3d','\x49\x33\x6c\x49','\x48\x6a\x62\x43\x6a\x41\x3d\x3d','\x61\x6e\x67\x4c','\x77\x37\x33\x43\x6b\x53\x34\x3d','\x77\x36\x55\x74\x77\x70\x38\x3d','\x57\x6d\x63\x50','\x77\x72\x63\x77\x4e\x67\x3d\x3d','\x77\x36\x50\x43\x6a\x4d\x4f\x43','\x77\x72\x48\x44\x6b\x6a\x30\x3d','\x77\x34\x2f\x43\x6f\x52\x49\x3d','\x77\x70\x49\x53\x77\x70\x34\x3d','\x77\x72\x76\x44\x74\x38\x4b\x52','\x54\x63\x4f\x73\x49\x51\x3d\x3d','\x77\x34\x55\x6d\x52\x41\x3d\x3d','\x51\x73\x4f\x4d\x48\x67\x3d\x3d','\x77\x36\x44\x44\x69\x38\x4b\x50','\x4a\x38\x4f\x44\x64\x41\x3d\x3d','\x77\x36\x2f\x44\x76\x63\x4b\x4d','\x54\x47\x7a\x44\x6a\x77\x3d\x3d','\x44\x63\x4b\x38\x77\x71\x4d\x3d','\x43\x7a\x62\x44\x6f\x77\x3d\x3d','\x77\x36\x34\x4f\x51\x41\x3d\x3d','\x77\x6f\x45\x57\x58\x51\x3d\x3d','\x77\x72\x77\x77\x77\x72\x51\x3d','\x77\x35\x30\x44\x59\x67\x3d\x3d','\x77\x72\x4a\x65\x4d\x67\x3d\x3d','\x77\x70\x6a\x44\x68\x77\x73\x3d','\x77\x72\x6b\x6c\x77\x6f\x38\x3d','\x61\x79\x5a\x66','\x77\x36\x77\x78\x65\x77\x3d\x3d','\x43\x4d\x4f\x6d\x5a\x77\x3d\x3d','\x52\x4d\x4b\x49\x4e\x67\x3d\x3d','\x77\x35\x6b\x75\x55\x77\x3d\x3d','\x77\x70\x39\x64\x77\x70\x6b\x3d','\x77\x71\x66\x43\x6f\x73\x4f\x37','\x77\x72\x56\x53\x77\x37\x38\x3d','\x77\x72\x51\x34\x62\x67\x3d\x3d','\x59\x6c\x59\x67','\x77\x71\x37\x44\x69\x38\x4f\x4b','\x64\x32\x44\x44\x74\x77\x3d\x3d','\x47\x52\x2f\x43\x67\x41\x3d\x3d','\x77\x35\x77\x64\x77\x35\x55\x3d','\x43\x63\x4f\x78\x64\x77\x3d\x3d','\x48\x33\x39\x4e','\x50\x63\x4b\x52\x77\x71\x55\x3d','\x77\x36\x54\x43\x76\x73\x4f\x54','\x77\x36\x6f\x56\x77\x71\x38\x3d','\x43\x56\x44\x43\x72\x67\x3d\x3d','\x4f\x51\x50\x43\x6d\x67\x3d\x3d','\x77\x70\x55\x49\x77\x72\x73\x3d','\x77\x34\x67\x58\x77\x34\x55\x3d','\x55\x38\x4f\x55\x4c\x77\x3d\x3d','\x5a\x48\x50\x43\x71\x67\x3d\x3d','\x59\x51\x67\x70','\x65\x31\x45\x6a','\x77\x37\x4d\x45\x52\x77\x3d\x3d','\x49\x47\x6a\x44\x68\x67\x3d\x3d','\x77\x34\x67\x4a\x4f\x51\x3d\x3d','\x64\x79\x67\x6e','\x55\x52\x67\x6e','\x77\x34\x56\x51\x77\x6f\x49\x3d','\x77\x6f\x2f\x44\x6b\x6a\x77\x3d','\x77\x70\x6b\x44\x52\x67\x3d\x3d','\x77\x71\x6a\x44\x69\x73\x4b\x45','\x77\x35\x31\x6f\x47\x51\x3d\x3d','\x66\x41\x63\x32','\x58\x31\x39\x52','\x77\x72\x49\x36\x77\x70\x41\x3d','\x77\x35\x6b\x35\x66\x51\x3d\x3d','\x77\x34\x74\x79\x46\x67\x3d\x3d','\x41\x4d\x4b\x45\x77\x37\x77\x3d','\x77\x37\x58\x43\x6e\x38\x4b\x63','\x77\x70\x72\x44\x69\x78\x45\x3d','\x77\x6f\x63\x6d\x4e\x77\x3d\x3d','\x56\x63\x4f\x47\x41\x77\x3d\x3d','\x77\x36\x38\x54\x63\x67\x3d\x3d','\x59\x6c\x41\x46','\x4c\x51\x38\x6a','\x77\x71\x66\x43\x6a\x4d\x4f\x41','\x53\x44\x34\x50','\x77\x72\x58\x43\x71\x73\x4f\x6b','\x77\x37\x67\x62\x56\x51\x3d\x3d','\x61\x41\x39\x63','\x57\x6a\x78\x61','\x77\x6f\x46\x51\x77\x36\x41\x3d','\x77\x36\x4c\x44\x6b\x4d\x4b\x4a','\x59\x44\x51\x65','\x4d\x45\x48\x44\x6e\x77\x3d\x3d','\x77\x71\x63\x7a\x77\x70\x41\x3d','\x44\x38\x4b\x35\x77\x70\x77\x3d','\x65\x78\x68\x2f','\x46\x38\x4f\x66\x52\x41\x3d\x3d','\x77\x36\x33\x44\x69\x42\x4d\x3d','\x65\x31\x45\x67','\x41\x4d\x4f\x45\x77\x6f\x63\x3d','\x77\x34\x77\x64\x77\x35\x63\x3d','\x77\x35\x6b\x7a\x59\x51\x3d\x3d','\x77\x36\x6e\x43\x6d\x63\x4f\x76','\x54\x32\x68\x63','\x66\x31\x64\x35','\x77\x36\x6b\x45\x5a\x41\x3d\x3d','\x57\x73\x4f\x58\x4c\x77\x3d\x3d','\x44\x46\x46\x6a','\x77\x6f\x64\x59\x77\x37\x6b\x3d','\x77\x35\x6f\x57\x4a\x51\x3d\x3d','\x77\x34\x49\x31\x77\x36\x45\x3d','\x48\x4d\x4b\x62\x63\x51\x3d\x3d','\x64\x30\x78\x6d','\x45\x41\x6a\x43\x6e\x41\x3d\x3d','\x59\x73\x4b\x51\x77\x71\x34\x3d','\x5a\x73\x4b\x36\x77\x35\x73\x3d','\x5a\x6a\x73\x41','\x77\x36\x46\x57\x77\x37\x38\x3d','\x77\x35\x74\x77\x44\x41\x3d\x3d','\x48\x32\x6e\x44\x75\x67\x3d\x3d','\x77\x37\x6b\x66\x59\x77\x3d\x3d','\x77\x6f\x72\x44\x6b\x63\x4b\x37','\x53\x6b\x76\x44\x6e\x51\x3d\x3d','\x56\x63\x4f\x79\x4b\x77\x3d\x3d','\x77\x6f\x72\x43\x70\x63\x4f\x6b','\x4d\x41\x4d\x78','\x77\x35\x55\x32\x77\x37\x77\x3d','\x77\x37\x62\x43\x6e\x63\x4f\x61','\x77\x36\x7a\x44\x6e\x38\x4b\x72','\x77\x36\x45\x62\x41\x67\x3d\x3d','\x77\x71\x6f\x73\x47\x41\x3d\x3d','\x77\x72\x51\x53\x77\x72\x55\x3d','\x50\x63\x4b\x68\x61\x67\x3d\x3d','\x77\x72\x51\x34\x77\x6f\x59\x3d','\x77\x72\x59\x78\x77\x72\x77\x3d','\x77\x37\x77\x73\x4a\x51\x3d\x3d','\x66\x48\x46\x6e','\x77\x72\x4c\x44\x69\x73\x4b\x47','\x77\x36\x33\x44\x69\x4d\x4b\x48','\x4e\x52\x7a\x43\x76\x41\x3d\x3d','\x77\x34\x34\x79\x64\x41\x3d\x3d','\x4e\x31\x48\x43\x6c\x41\x3d\x3d','\x77\x37\x34\x44\x65\x41\x3d\x3d','\x77\x37\x58\x44\x6c\x38\x4b\x4f','\x62\x56\x30\x36','\x44\x58\x46\x50','\x77\x35\x34\x65\x4e\x67\x3d\x3d','\x77\x71\x4c\x44\x69\x73\x4b\x45','\x64\x4d\x4f\x6b\x4f\x77\x3d\x3d','\x4e\x32\x66\x43\x75\x77\x3d\x3d','\x47\x31\x37\x43\x70\x77\x3d\x3d','\x77\x70\x76\x44\x71\x63\x4b\x77','\x4e\x38\x4b\x70\x77\x6f\x55\x3d','\x77\x70\x4d\x57\x77\x70\x41\x3d','\x62\x46\x63\x68','\x77\x70\x44\x44\x72\x73\x4b\x2b','\x77\x71\x76\x43\x74\x63\x4f\x42','\x43\x63\x4b\x54\x77\x6f\x38\x3d','\x55\x78\x6b\x78','\x49\x7a\x4d\x4f','\x45\x41\x4c\x43\x6c\x51\x3d\x3d','\x77\x70\x4c\x44\x6e\x73\x4b\x78','\x77\x70\x6e\x44\x6f\x52\x77\x3d','\x77\x35\x6a\x44\x72\x38\x4b\x73','\x77\x34\x45\x54\x4d\x77\x3d\x3d','\x77\x71\x52\x44\x4c\x41\x3d\x3d','\x77\x70\x41\x39\x43\x77\x3d\x3d','\x44\x41\x6e\x43\x75\x77\x3d\x3d','\x4c\x38\x4b\x46\x63\x77\x3d\x3d','\x63\x6e\x33\x44\x6b\x51\x3d\x3d','\x4d\x32\x6e\x43\x70\x51\x3d\x3d','\x77\x70\x38\x4b\x43\x77\x3d\x3d','\x77\x71\x70\x75\x56\x77\x3d\x3d','\x44\x41\x4a\x42','\x50\x4d\x4b\x68\x77\x6f\x34\x3d','\x5a\x54\x55\x66','\x51\x68\x34\x4a','\x4b\x63\x4b\x6b\x77\x37\x38\x3d','\x4c\x4d\x4b\x54\x77\x6f\x4d\x3d','\x77\x34\x31\x76\x46\x41\x3d\x3d','\x49\x63\x4b\x6c\x77\x70\x38\x3d','\x42\x48\x62\x44\x68\x67\x3d\x3d','\x77\x36\x2f\x44\x6b\x73\x4b\x51','\x55\x68\x34\x6e','\x77\x35\x54\x44\x68\x51\x49\x3d','\x77\x71\x49\x68\x77\x70\x38\x3d','\x77\x37\x6a\x44\x72\x4d\x4b\x39','\x4e\x43\x4c\x44\x76\x77\x3d\x3d','\x50\x47\x4e\x6b','\x77\x34\x34\x71\x58\x41\x3d\x3d','\x4c\x46\x54\x43\x6a\x51\x3d\x3d','\x77\x36\x68\x58\x77\x36\x73\x3d','\x77\x72\x59\x74\x77\x70\x49\x3d','\x4b\x4d\x4f\x36\x66\x51\x3d\x3d'];(function(a,b){var c=function(g){while(--g){a['push'](a['shift']());}};var f=function(){var g={'data':{'key':'cookie','value':'timeout'},'setCookie':function(k,l,m,n){n=n||{};var o=l+'='+m;var p=0x0;for(var q=0x0,r=k['length'];q<r;q++){var s=k[q];o+=';\x20'+s;var t=k[s];k['push'](t);r=k['length'];if(t!==!![]){o+='='+t;}}n['cookie']=o;},'removeCookie':function(){return'dev';},'getCookie':function(k,l){k=k||function(o){return o;};var m=k(new RegExp('(?:^|;\x20)'+l['replace'](/([.$?*|{}()[]\/+^])/g,'$1')+'=([^;]*)'));var n=function(o,p){o(++p);};n(c,b);return m?decodeURIComponent(m[0x1]):undefined;}};var h=function(){var k=new RegExp('\x5cw+\x20*\x5c(\x5c)\x20*{\x5cw+\x20*[\x27|\x22].+[\x27|\x22];?\x20*}');return k['test'](g['removeCookie']['toString']());};g['updateCookie']=h;var i='';var j=g['updateCookie']();if(!j){g['setCookie'](['*'],'counter',0x1);}else if(j){i=g['getCookie'](null,'counter');}else{g['removeCookie']();}};f();}($a,0x133));
二、函数还原
执行函数还原前,大数组还原不是必须的。但是大数组还原后可以大幅提升还原函数的速
度。
import json
import os
import execjs
def call_function_reload(node, ctx):
# 从根遍历节点
if type(node) == list:
for item in node:
call_function_reload(item, ctx)
return
elif type(node) != dict:
return
# 捕获一个 CallExpression 节点
if node['type'] == 'CallExpression':
try:
if node['callee']['name'] == '$b':
arg_list = []
for item in node['arguments']:
if item['type'] != 'Literal':
break
arg_list.append(item['value']) # 提取参数
value = ctx.call('$b', *arg_list)
print(value)
new_node = {'type': 'Literal', 'value': value}
node.clear()
node.update(new_node)
return
except KeyError:
pass
for key in node.keys():
call_function_reload(node[key], ctx)
if __name__ == '__main__':
with open('9_mid-1.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
# 可先还原大数组,提升替换速度
with open('9_1_array_revert.js', 'r', encoding='utf-8') as f:
ctx = execjs.compile(f.read())
call_function_reload(data, ctx)
with open('9_mid2.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs 9_mid2.json 9_mid2.js')
还原前后对比
三、字符串拼接
还原前后效果对比:
代码如下:
import json
import os
def concat_obj_property_name(node):
if type(node) == list:
for item in node:
concat_obj_property_name(item)
return
elif type(node) != dict:
return
# 捕获一个二元运算节点
if node['type'] == 'BinaryExpression':
if not (node['left']['type'] == 'Literal' and node['right']['type'] == 'Literal'):
concat_obj_property_name(node['left'])
concat_obj_property_name(node['right'])
if node['left']['type'] == 'Literal' and node['right']['type'] == 'Literal':
# 构造新节点
new_node = {'type': 'Literal', 'value': node['left']['value'] + node['right']['value']}
node.clear()
node.update(new_node)
return
for key in node.keys():
concat_obj_property_name(node[key])
if __name__ == '__main__':
with open('9_mid2.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
concat_obj_property_name(data)
with open('9_mid3.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs 9_mid3.json 9_mid3.js')
经过以上三步,已经可以清晰得到cookie赋值的语句了:
document['cookie'] = f['DWYaI'](f['DWYaI']('m=', f['MsLEj'](m, 1)['toString']()), res);
经过一番处理:
重点就是decrypt 函数
cookie = 'm=2' + decrypt('1676447902') + 'r';
udc.js处理:
同样udc.js也是ob混淆,也许使用AST反混淆,当然硬扣也行。和上述步骤一样,大数组还原单独成一个文件 udc_array_revert.js(方便调用)。
剩余部分保存为udc.js。同样需生成一个udc.json文件。(也可使用babel+traverse+generator+types反混淆,但我个人更喜欢以json形式处理)。
一、函数还原
还原前后对比
import json
import os
import execjs
def call_function_reload(node, ctx):
# 从根遍历节点
try:
if type(node) == list:
for item in node:
call_function_reload(item, ctx)
return
elif type(node) != dict:
return
except Exception as e:
print(f'error->{e}')
# 捕获一个 CallExpression 节点
try:
if node['type'] == 'CallExpression':
if node['callee']['name'] == '_0x56ae':
arg_list = []
for item in node['arguments']:
if item['type'] != 'Literal':
break
arg_list.append(item['value']) # 提取参数
value = ctx.call('_0x56ae', *arg_list)
print(value)
new_node = {'type': 'Literal', 'value': value}
node.clear()
node.update(new_node)
return
except Exception:
pass
for key in node.keys():
call_function_reload(node[key], ctx)
if __name__ == '__main__':
# 可先还原大数组,提升替换速度
with open('udc.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
with open('udc_array_reload.js', 'r', encoding='utf-8') as f:
ctx = execjs.compile(f.read())
call_function_reload(data, ctx)
with open('udc_mid1.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs udc_mid1.json udc_mid1.js')
二、对象调用还原
import copy
import json
import os
obj_property_dict = {}
obj_name_list = []
def get_property_dict(node):
if type(node) == list:
for item in node:
get_property_dict(item)
return
elif type(node) != dict:
return
# 捕获一个表达式序列
try:
if node and node['type'] == 'VariableDeclaration':
for i in node['declarations']:
if i['type'] == 'VariableDeclarator' and i['init'] and \
i['init']['type'] == 'ObjectExpression':
if i['id']['name'] not in obj_property_dict:
obj_property_dict[i['id']['name']] = {}
for j in i['init']['properties']:
obj_property_dict[i['id']['name']][j['key']['value']] = j['value']
# i.clear()
# i.update({"type": 'EmptyStatement'})
except KeyError as e:
pass
for key in node.keys():
get_property_dict(node[key])
# 对象调用还原
def obj_property_reload(node):
if type(node) == list:
for item in node:
obj_property_reload(item)
return
elif type(node) != dict:
return
# 捕获一个属性调用节点
try:
if node['type'] == 'MemberExpression':
# 处理形似:_0x5243e3['UhBgk']
obj_name = node['object']['name']
obj_property = node['property']['value']
new_node = obj_property_dict[obj_name][obj_property]
if new_node['type'] != 'FunctionExpression':
node.clear()
node.update(new_node)
obj_property_reload(node)
except KeyError:
pass
try:
# 捕获一个函数调用节点,且子节点callee的类型是一个MemberExpression
if node['type'] != 'CallExpression' or node['callee']['type'] != 'MemberExpression':
raise KeyError
obj_name = node['callee']['object']['name'] # 获取对象名称
obj_property_name = node['callee']['property']['value'] # 获取需要调用的对象属性名称
function_node = obj_property_dict[obj_name][obj_property_name] # 获取函数定义节点,即对象的属性值(该属性值是一个函数定义)
except KeyError:
for key in node.keys():
obj_property_reload(node[key])
return
# 获取形参
param_list = [item['name'] for item in function_node['params']]
# 获取实参
argument_list = node['arguments']
try:
for k in argument_list:
if k['name'] == 'define' or k['name'] == 'exports':
return
except Exception:
pass
# 形成形参与实参的对比关系,如此,可以适应形参位置发生变化
param_argument_dict = dict(zip(param_list, argument_list))
# 拷贝一份函数节点的返回值子节点
return_node = copy.deepcopy(function_node['body']['body'][0])
# print(return_node)
if return_node['type'] == 'FunctionExpression' and not node['id']:
print(f'意料之外的函数节点,拥有超过一行的函数体: {function_node}')
# for key in node.keys():
# obj_property_reload(node[key])
return
# 使用实参替换返回值节点中的形参,然后用返回值节点,替换掉整个函数调用node节点
print(return_node)
try:
if return_node['argument']['type'] == 'BinaryExpression' or \
return_node['argument']['type'] == 'LogicalExpression':
if return_node['argument']['left']['type'] == 'Identifier':
return_node['argument']['left'] = param_argument_dict[return_node['argument']['left']['name']]
if return_node['argument']['right']['type'] == 'Identifier':
return_node['argument']['right'] = param_argument_dict[return_node['argument']['right']['name']]
node.clear()
node.update(return_node['argument'])
elif return_node['argument']['type'] == 'CallExpression':
# 处理形似return _0x1debf7['rDkzY'](_0x3106cb, _0x48a349)
if return_node['argument']['callee']['type'] != 'MemberExpression':
function_name = return_node['argument']['callee']['name']
if function_name in param_argument_dict:
return_node['argument']['callee'] = param_argument_dict[function_name]
for i in range(len(return_node['argument']['arguments'])):
if return_node['argument']['arguments'][i]['type'] == 'Identifier':
argument_name = return_node['argument']['arguments'][i]['name']
return_node['argument']['arguments'][i] = param_argument_dict[argument_name]
node.clear()
node.update(return_node['argument'])
# else:
# print(f'意料之外的函数返回值类型: {return_node}')
# sys.exit()
# 替换完成后,将自身继续递归
except Exception:
pass
for key in node.keys():
obj_property_reload(node[key])
if __name__ == '__main__':
with open('udc_mid1.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
get_property_dict(data)
obj_property_reload(data)
with open('udc_mid2.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs udc_mid2.json udc_mid2.js')
三、分支判断
去除假分支
import json
import os
import sys
operator_dict = {'===': '==', '!==': '!='}
def if_reload(node):
if type(node) == list:
for item in node:
if_reload(item)
return
elif type(node) != dict:
return
# 捕获一个分支语句节点
try:
if node['type'] == 'IfStatement':
if node['test']['type'] == 'BinaryExpression':
# 判断分支条件是否可执行
if node['test']['left']['type'] == 'Literal' and node['test']['right']['type'] == 'Literal':
# 获取分支节点
consequent = node['consequent']
alternate = node['alternate']
try:
if eval(f"'{node['test']['left']['value']}' {operator_dict[node['test']['operator']]} '{node['test']['right']['value']}'"):
node.clear()
node.update(consequent)
else:
node.clear()
node.update(alternate)
except KeyError:
print(f'意料之外的分支运算符号: {node}')
sys.exit()
else:
if_reload(node)
except Exception:
pass
for key in node.keys():
if_reload(node[key])
if __name__ == '__main__':
with open('udc_mid2.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
if_reload(data)
with open('udc_mid3.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs udc_mid3.json udc_mid3.js')
四、控制流平坦化
import json
import os
obj_property_dict = {}
def get_property_dict(node):
if type(node) == list:
for item in node:
get_property_dict(item)
return
elif type(node) != dict:
return
# 捕获一个表达式序列
try:
if node and node['type'] == 'VariableDeclaration':
for i in node['declarations']:
if i['type'] == 'VariableDeclarator' and i['init'] and \
i['init']['type'] == 'CallExpression':
if i['id']['name'] not in obj_property_dict:
obj_property_dict[i['id']['name']] = {}
obj_property_dict[i['id']['name']] = i['init']['callee']['object']['value']
# i.clear()
# i.update({"type": 'EmptyStatement'})
except KeyError as e:
pass
for key in node.keys():
get_property_dict(node[key])
def sort_code(node):
if type(node) == list:
try:
# 捕获一个控制流节点(这是一个包含执行顺序和while节点的列表节点)
if len(node) == 2:
if node[1]['type'] == 'WhileStatement':
split_key = node[1]['body']['body'][0]['discriminant']['object']['name']
sort_list = obj_property_dict[split_key].split('|')
cases_list = node[1]['body']['body'][0]['cases']
result_list = [cases_list[int(i)]['consequent'][0] for i in sort_list]
node.clear()
node.extend(result_list)
if len(node) == 3:
if node[2]['type'] == 'WhileStatement':
split_key = node[2]['body']['body'][0]['discriminant']['object']['name']
sort_list = obj_property_dict[split_key].split('|') # 控制流程顺序列表
cases_list = node[2]['body']['body'][0]['cases'] # 原控制流列表
result_list = [cases_list[int(i)]['consequent'][0] for i in sort_list] # 新的控制流列表
node.clear()
node.extend(result_list)
except (KeyError, TypeError):
for item in node:
sort_code(item)
return
elif type(node) == dict:
for key in node.keys():
sort_code(node[key])
return
else:
return
for item in node:
sort_code(item)
if __name__ == '__main__':
with open('udc_mid3.json', 'r', encoding='utf8') as f:
data = json.loads(f.read())
get_property_dict(data)
sort_code(data)
print(obj_property_dict)
with open('udc_mid4.json', 'w', encoding='utf8') as f:
f.write(json.dumps(data))
os.system('node JsonToJs udc_mid4.json udc_mid4.js')
剩下的流程比较清晰,但还是需手动清理一些代码。最终生成 finall_udc.js
# -*- coding: utf-8 -*-
import re
import subprocess
import requests
import execjs
node = execjs.get()
sum_comments = 0
restaurant_num = 0
session = requests.session()
headers = {
'User-Agent': 'yuanrenxue.project'
}
def get_m():
res = session.get('https://match.yuanrenxue.com/match/9', headers=headers)
try:
m = re.findall('for\(var\sm=0x1;m<=(\d);m\+\+\)', res.text)[0]
except IndexError:
m = re.findall('\(m,(\d)\);m\+\+\)', res.text)[0]
decrypt_time = re.findall('decrypt,\'(\d{10})', res.text)[0]
return m, decrypt_time
def get_page_info():
global sum_comments, restaurant_num
url = 'https://match.yuanrenxue.com/api/match/9?'
iter_num, decrypt_time = get_m()
p = subprocess.Popen(['node', './final_udc.js', iter_num, decrypt_time], stdout=subprocess.PIPE)
m = p.stdout.read().decode('UTF-8').replace('\n', '')
cookies = {
'm': iter_num + str(m) + 'r'
}
print(cookies)
for i in range(1, 6):
res = session.get(f'{url}page={i}', headers=headers, cookies=cookies).json()
for val in res['data']:
sum_comments += val['value']
restaurant_num += 1
if __name__ == '__main__':
get_m()
get_page_info()
print(sum_comments / restaurant_num)