const fs = require('fs') const parser = require('@babel/parser') const traverse = require('@babel/traverse').default const t = require('@babel/types') const generator = require('@babel/generator').default let jscode = fs.readFileSync('./initCode.js', { encoding: 'utf-8' }).toString() let ast = parser.parse(jscode) let totalObj = {} function generatorObj(ast) { traverse(ast, { VariableDeclarator(path) { if (t.isObjectExpression(path.node.init)) { let objName = path.node.id.name if (!totalObj[objName]) totalObj[objName] = {} path.node.init.properties.map(p => { totalObj[objName][p.key.value] = p.value } ) } } }) } generatorObj(ast) traverse(ast, { VariableDeclarator(path) { if (t.isObjectExpression(path.node.init)) { path.node.init.properties.map(property => { let realNode = findRealFunc(property.value); realNode && (property.value = realNode) }) } } }) function findRealFunc(node) { if (t.isFunctionExpression(node) && t.isReturnStatement(node.body.body[0])) { let reCallee = node.body.body[0].argument.callee if (t.isMemberExpression(reCallee)) { let key = node.object.name let value = node.property.value if (totalObj[key] && totalObj[key][value]) { return findRealFunc(totalObj[key][value]) } else { false } } } else { return node } } generatorObj(ast) traverse(ast, { CallExpression(path) { if(!t.isMemberExpression(path.node.callee)) return let objName = path.node.callee.object.name let propValue = path.node.callee.property.value if(totalObj[objName] && totalObj[objName][propValue]){ let func = totalObj[objName][propValue] if(t.isFunctionExpression(func) && t.isReturnStatement(func.body.body[0])){ //判断对象值是函数表达式,且只有一条return语句 let reExpr = func.body.body[0].argument if(t.isBinaryExpression(reExpr)){ //如果是二项式 let binExpr = t.binaryExpression(reExpr.operator,path.node.arguments[0],path.node.arguments[1]) path.replaceInline(binExpr) }else if(t.isCallExpression(reExpr)){ //如果是函数调用 let funcName = path.node.arguments[0] let arguArray = path.node.arguments.slice(1) let callExpr = t.callExpression(funcName,arguArray) path.replaceInline(callExpr) } } } } }) let code = generator(ast).code fs.writeFileSync('./newCode.js', code)
【JS逆向解混淆】利用AST还原字符串花指令...