《JavaScript AST其实很简单》二、Step1-函数调用还原

前言
本系列所有反混淆内容都是基于开源项目Tool进行的 。
打开网站后 , 使用如下配置对js源码进行混淆
下载混淆后的js文件 , 进行格式化后大概是这样的
备注:源文件见最下方附件内的ob.txt
可以看到第一个节点定义了一个大数组 , 第二和第三是一个立即执行函数和一个函数 , 这两个顺序不一定 。从上图中可以看到 , 被混淆后的js代码中 , 存在非常多的相同的函数调用 , 那么第一步就是要将这个函数调用的结果还原回去 。
1.语法分析
要反混淆第一步就是对现有的代码做分析 , 找到其加密的规律 , 然后按照这个规律进行还原
首先将混淆后的代码复制到AST  , 其中使用的解析器是 , 我用用node的模块也是这个
可以看到很快就可以将源代码转换成抽象语法树 , 然后随便点击一个函数调用的地方
可以看到 , 其中的类型为 , 那么现在就可以找所有的了 , 但是并不是所有的函数调用都是需要还原的 , 只有名称为的才需要 。
但是并不能将这个函数名写死 , 因为这个函数名是随机的 , 所以要先确定函数名 。由前面可知 , 函数的定义一定会出现在第二或者第三个节点 , 那么只要查找第二和第三个节点 , 看看哪个是函数定义 , 就可以知道函数名了 。只知道函数名还不够 , 还需要里面的参数 。
在的子节点在有一个的节点 , 里面就有函数调用的参数了 。此时就已经获取了函数名和所有调用的参数
2.函数调用计算
我们首先编写一个node的命令行文件 , 用于将js代码转换为json,保存为文件:.js
const fs = require('fs');const esprima = require('esprima')const escodegen = require('escodegen')var inputtext = process.argv[2];var outputtext = process.argv[3];var data = http://www.kingceram.com/post/fs.readFileSync(inputtext);var ast = esprima.parseScript(data.toString());var ast_to_json = JSON.stringify(ast);fs.writeFileSync(outputtext, ast_to_json);
再编写一个相反的 , 将json转换为js代码,保存为文件:.js
const fs = require('fs');const esprima = require('esprima')const escodegen = require('escodegen')var inputtext = process.argv[2];var outputtext = process.argv[3];var data = http://www.kingceram.com/post/fs.readFileSync(inputtext);var ast = JSON.parse(data.toString());var code = escodegen.generate(ast, {format: {compact: true,escapeless: true}});fs.writeFileSync(outputtext, code);
先读取转换的json , 并将前3个节点输出 , 用于后面计算结果
inputfile = 'ob'os.system('node js2jsonyuge '+inputfile+'.js '+inputfile+'.json')with open(inputfile+'.json', 'r', encoding='utf-8') as f:data = http://www.kingceram.com/post/f.read()# 删除缓存os.remove(inputfile+'.json')data = json.loads(data)# 定义替换函数的jsontempstep1 = {'type': 'Program','body': data['body'][:3],'sourceType': 'script'}# 写出第一步替换的函数体with open(inputfile+'_step1.json', 'w', encoding='utf-8') as f:f.write(json.dumps(tempstep1, ensure_ascii=False, separators=(',', ':')))os.system('node json2jsyuge '+inputfile+'_step1.json '+inputfile+'_step1.js')
运行后会得到一个.json和.js , 打开.js并在第二行输入
console.log(_0x166e('0x305'));