js代码反混淆之ast的使用

代码

const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const generator = require("@babel/generator").default;

let origin_code = `
function  _0x506bbd(v){
   const a= !![]
   console.log(a);
   return v.length
}
 console.log(_0x506bbd(‘\x69\x6e\x64\u0435\x78\x4f\x66‘));
`
let ast = parser.parse(origin_code);
pre_ast = ast.program.body.slice(0, 1)
const gen = generator(ast, {
    // 禁止自动格式化(针对反调试)
    compact: true
})
eval(gen.code)

function toSource(_ast) {
    let {code} = generator(_ast, {
        // 是否格式化
        compact: false,
        jsescOption: {
            // 自动转义
            minimal: true,
        }
    });
    return code.replace(/!!\[\]/g, ‘true‘).replace(/!\[\]/g, ‘false‘)
}

function getvalue(path) {
    const node = path.node
    if (t.isStringLiteral(node)) {
        if (node && node.exact) {
            delete path.node.exact
        }
    } else if (t.isCallExpression(node)) {
        const {callee} = path.node;
        if (t.isMemberExpression(callee) &&
            callee.object.name === "console" &&
            callee.property.name === "log") {
            node.arguments.map(item => {
                if (t.isCallExpression(item)) {
                    let _value = item.arguments
                    let _key = item.callee.name
                    const func = eval(_key)
                    let new_value = func(..._value.map(v => v.value))
                    let value_type = Object.prototype.toString.call(new_value)
                    let new_node;
                    if (value_type === "[object Number]") {
                        new_node = t.NumericLiteral(new_value)
                    } else if (value_type === "[object String]") {
                        new_node = t.stringLiteral(new_value)
                    }
                    path.node.arguments[0] = new_node
                }
            })
        }
    }


}

function traverse_ast(ast, opts) {
    traverse(ast, opts);
    return ast
}

let step1_ast = traverse_ast(ast, {StringLiteral: getvalue})

let step2_ast = traverse_ast(step1_ast, {CallExpression: getvalue})

let new_code = toSource(step2_ast)
console.log("before: =============")
console.log(origin_code)
console.log("after: =============")
console.log(new_code)

目标结果:

true
7
true
before: =============

function  _0x506bbd(v){
   const a= !![]
   console.log(a);
   return v.length
}
 console.log(_0x506bbd(‘indеxOf‘));

after: =============
function _0x506bbd(v) {
  const a = true;
  console.log(a);
  return v.length;
}

js代码反混淆之ast的使用

上一篇:[PHP]解决nginx php上传文件限制413 Request Entity Too Large


下一篇:状态机模式 与 ajax 的结合运用