利用AST解混淆常规思路及经验总结
很多星友问我,拿到一段混淆的代码不知道该如何下手,更不知道怎么还原,我在这里做个经验总结。
一. 变量定义的还原
如果初始值为字面量或者 Identifier 节点时,如果该变量的值没有被更改过,是可以进行还原的。
诸如:
var a = 123,b = -5,c = window....
等这类定义。
详细见星球里的 restoreVarDeclarator 插件。
如果变量是这么定义的:
var a = 123 + 456;
则可以先调用 constantFold 插件,再调用 restoreVarDeclarator 插件。
还有一类就是Array对象的还原,例如:
var a = [1,2,3,4,5];
等这类定义,其元素全部为字面量,并且变量a没有被更改时,也可以进行还原。
详细见星球里的 replaceArrayElements 插件。
总之,应该想方设法的对字面量进行还原。
二.CallExpression 节点的还原
当一个CallExpression节点,其实参(arguments子节点)均为字面量时,可以直接计算出该节点的值,再用结果值替换该节点即可。
诸如:
add(1,2),sub(3,4,5)....
这类节点有个特点,就是其实参均为字面量。其结果是一定可以计算出来的,当然有时可能需要缺啥补啥。
不过这都是小问题。
对于js中的全局函数的调用,诸如:
parseInt("12345",16);
等,可以使用 evaluateGlobalFunc 插件来进行值的替换。
而自定义的函数,你可以将函数的整个定义copy到解混淆的文件中去,再遍历 CallExpression节点,本地进行计算得出结果再进行替换即可。
只要函数可以能正常运行调用即可。
也可以使用 星球里的 CalcCallExpression 插件自识别函数调用计算并替换。
当遇到类似自执行函数,包含CallExpression子节点时,可以使用星球里的 resolveActualParams 插件。
还原前:
-
!function (a,b)
-
{
-
s = a + b;
-
}(2,3);
还原后:
-
!function () {
-
s = 2 + 3;
-
}();
三.ObjectExpression 节点的还原点的还原
这类节点的混淆在obfuscator混淆中很常见,因为其结构简单,因此还原起来难度也不大。直接使用最新版一键解ob混淆脚本里的 decodeObject 插件即可,都是这套路。
四.逗号表达式还原
这类节点直接用星球里的 resolveSequence 插件即可进行还原。
该插件思路奇特,代码优雅,非常的赞。
不过有时候需要配合 standardLoop 这个插件使用,例如有类似下面的代码:
-
for(a=100,b=2,c=3;a>0;a--)
-
a+=-5,b+=2,c+=3;
如果直接使用 resolveSequence 插件的话,会还原出错。而将这个for循环先处理下(使用standardLoop插件)再进行还原就可以正常了。
五.还原控制流平坦化的代码
核心思想:想方设法找到下一条执行的语句即可。
详细思路可参考下面三篇文章。
-
https://t.zsxq.com/EimyZbM
-
-
-
https://articles.zsxq.com/id_rgqhlihqrauf.html
-
-
-
https://articles.zsxq.com/id_dra3kh243dn2.html
六.删除无用的代码
这个没什么好讲的,直接看星球里的 removeDeadCode 插件即可。大家也可以学习这个插件写出更多更好的插件。
如果懒得写插件来删除 DeadCode,也可以手动分析,看看那些代码是不影响加密结果值的。分析方法我在直播的视频中讲过,这里不再赘述。
文章来源: blog.csdn.net,作者:悦来客栈的老板,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq523176585/article/details/112505003
- 点赞
- 收藏
- 关注作者
评论(0)