| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- const fs = require('fs')
- const parser = require('@babel/parser') // 解析 JavaScript 代码
- const traverse = require('@babel/traverse').default // 遍历 AST
- const generator = require('@babel/generator').default // 生成代码
- const t = require('@babel/types')
- // 定义文件路径
- const input_js = './encode.js'
- const output_js = './decode.js'
- // 读取文件内容并解析成 AST
- const js_code = fs.readFileSync(input_js, {encoding: 'utf-8'})
- const ast = parser.parse(js_code) // 解析代码为 AST
- // ------ 得出来 3元表达式
- // 只获取指纹数组的代码,全部获取还原后并不准确
- // 查找所有 lA()[Sr(l2)](rs, U3, pb) 和 Zb()[G9(Yx)].apply(null, [cg, N9])
- encode = {}
- const visitor_call = {
- ConditionalExpression(path) {
- js = path.toString()
- encode[js] = null;
- },
- CallExpression(path) {
- // 检查是否在三元表达式内部
- const isInsideTernary = path.findParent(p =>
- p.isConditionalExpression()
- );
- if (isInsideTernary) return;
- let {callee,} = path.node
- // let argumentsPathList = path.get('arguments')
- if (!t.isMemberExpression(callee)) return;
- // 匹配2种混淆表达式
- let {object, property} = callee
- if (!t.isCallExpression(object) && !t.isMemberExpression(object)) return;
- // 处理 参数中有 三元表达式的(没必要)
- // argumentsPathList.forEach(argPath => {
- // argPath.traverse({
- // ConditionalExpression(innerPath) {
- // js = innerPath.toString()
- // console.log('找到条件表达式完', js)
- // }
- // })
- // })
- // 更细节的处理
- if (t.isCallExpression(object) && t.isIdentifier(object.callee) && object.arguments.length === 0) {
- js = path.toString()
- encode[js] = null; // 要设置值为 null 否则转 json字符串时会无值,因为值为 undefind 的json转不了
- }
- if (t.isMemberExpression(object) && t.isIdentifier(property)) {
- // 跳过嵌套的成员表达式 只还原这种 Zb()[G9(Yx)].apply(null, [cg, N9])
- if (!t.isCallExpression(object.object)) return;
- js = path.toString()
- encode[js] = null;
- }
- // if(!t.isCallExpression(object) || !t.isMemberExpression(object)) return;
- //
- // if(!) return;
- // encode.push({key: js})
- },
- Program: {
- exit() {
- // console.log(encode)
- const jsonData = JSON.stringify(encode);
- console.log(jsonData); // 输出 JSON 字符串
- }
- }
- };
- decode = {
- "zK()[GQ(fp)](d5, X0)": "Object",
- "RP(typeof RT()[N5(Sj)], 'undefined') ? RT()[N5(xQ)].call(null, EN, BX7, Z2, OR) : RT()[N5(JI)](pN, tH7, QG, CF)": "keys",
- "HR(typeof pQ()[vP(b5)], 'undefined') ? pQ()[vP(TN)].apply(null, [jK, jc, B0, YU]) : pQ()[vP(OR)](DA7, Pd, cW, EN)": "map"
- }
- const visitor2 = {
- CallExpression(path) {
- let {callee,} = path.node
- // let argumentsPathList = path.get('arguments')
- if (!t.isMemberExpression(callee)) return;
- // 匹配2种混淆表达式
- let {object, property} = callee
- if (!t.isCallExpression(object) && !t.isMemberExpression(object)) return;
- // console.log(path.toString())
- // 更细节的处理
- if (t.isCallExpression(object) && t.isIdentifier(object.callee) && object.arguments.length === 0) {
- js = path.toString()
- if (decode[js] !== null) {
- value = decode[js]
- console.log(js, '=>', value)
- path.replaceWith(t.valueToNode(value))
- }
- }
- if (t.isMemberExpression(object) && t.isIdentifier(property)) {
- // 跳过嵌套的成员表达式 只还原这种 Zb()[G9(Yx)].apply(null, [cg, N9])
- if (!t.isCallExpression(object.object)) return;
- js = path.toString()
- // try {
- if (decode[js] !== null) {
- value = decode[js]
- console.log(js, '=>', value)
- path.replaceWith(t.valueToNode(value))
- }
- // } catch (e) {
- // console.log(e)
- // }
- }
- },
- ConditionalExpression(path) {
- js = path.toString()
- if (decode[js] !== null) {
- value = decode[js]
- console.log(js, '=>', value)
- path.replaceWith(t.valueToNode(value))
- }
- }
- };
- // traverse(ast, visitor_call) // 获取混淆的表达式
- traverse(ast, visitor2) // 还原
- // 使用 Babel 生成新的代码
- let {code} = generator(ast)
- // 将生成的代码写入指定的文件
- fs.writeFile(output_js, code, (err) => {
- })
|