基于 Babel 对 JS 代码进行混淆与还原操作的网站 JS 代码混淆与还原 (wenhao.cn)
还原前言
AST 仅仅只是静态分析,但可以将还原出来的代码替换原来的代码,以便更好的动态分析找出相关点。在还原时,并不是所有的代码都能还原成一眼就识破代码执行逻辑的,ast 也并非万能,如果你拥有强大的 js 逆向能力,有时候动态调试甚至比 AST 静态分析来的事半功倍。
还原不出最原始的代码
标识符是可以随便定义的,只要变量不冲突,我可以随意定义,那么就已经决定我们还原不出源代码的变量名,所以能还原的只有一些花指令,使其代码变好看,方便调试。
还原也 不是万能的
混淆的方式有很多,与之对应还原的方式也有很多,上面那套混淆的还原可能只针对那一套混淆的代码,如果拿另一份混淆过的代码,然后执行这个还原程序的话,那程序多半有可能报错。所以绝对没有万能的还原代码,所有的还原程序,都需要针对不同的混淆手段来进行处理的。
我只是将我所遇到的混淆手段整合到一套代码上,而非所有的混淆手段都能进行还原处理的。
同时也别过于追求还原,因为还原很容易破坏原有代码,导致一些未知 bug。
如需要定制化还原,也可联系。(还是要说下,绝对无法还原出最原始代码)
例子
下文将会针对主流的一些混淆手段(至少是在我遇到的混淆中相对比较好还原的),并会附上对应代码供参考(不放置代码出处 )。
接下来我将要演示一个混淆代码是如何还原的,这个例子是我第一次接触混淆的例子,也可以说是我玩的最溜的一次还原了,反正折腾了也有 4,5 来次。
贴上代码 git 地址 js-de-obfuscator/example/deobfuscator/cx
注:该 js 文件是通过工具JavaScript Obfuscator Tool进行混淆处理的。
分析 AST
首先一定一定要将混淆的代码解析成 AST 树结构,任何混淆的还原都是如此。首先简单随便看看代码,不难发现这些代码中都有'\x6a\x4b\x71\x4b'
这样的十六进制编码字符,可以使用现成的工具,格式化便会限制编码前的结果,不过这边使用 ast 来进行操作
通过 AST 查看 node 节点,可以发现value
正是我们想要的数据,但这里确显示的是extra.raw
,实际上只需要遍历到相应的节点,然后 extra 属性给删除即可,同样的 Unicode 编码也是按上述方式显示。
具体遍历的代码如下
// 将所有十六进制编码与Unicode编码转为正常字符
hexUnicodeToString() {
traverse(this.ast, {
StringLiteral(path) {
var curNode = path.node;
delete curNode.extra;
},
NumericLiteral(path) {
var curNode = path.node;
delete curNode.extra;
}
})
}
然后将遍历后处理过的代码与 demo.js 替换一下,方便接下来的还原处理。不过处理完还是有大部分未知的字符串需要解密,当然也有一些没处理过的代码。
找解密函数
如果你 尝试过静态分析该代码,会发现一些参数都通过_0x3028 来调用,像这样
_0x3028['nfkbEK']
_0x3028('0x0', 'jKqK')
_0x3028('0x1', ')bls')