关注它,不迷路。
本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!
一.需求分析
如题,如何写一个通用的逗号表达式还原插件?
在所有的非jsvmp混淆代码中,最常见的就是逗号表达式,因为它可以穿插到各种表达式语句中,非常的烦人。之前写了通用的逗号表达式还原插件:
https://t.zsxq.com/19msvWVsO
代码非常的臃肿,其实就是穷举了逗号表达式在各表达式的情况,但是它有它的局限性,对于复杂一点的嵌套,它就无法进行处理了。
二.前置插件
因为需要将代码插入到当前的表达式语句中,这就存在一个代码先后执行的问题,所以,它需要先处理一些代码,再进行逗号表达式的还原才行。
1.规范循环表达式,给不规范的代码块加上{}:
https://t.zsxq.com/UXP4
2.分离变量定义,单个变量定义更好处理:
https://t.zsxq.com/EoDsq
三.需要过滤的情况
将一段代码中的逗号表达式给提到代码前面来,除了要考虑先后执行的情况,还需要考虑代码是否会执行的问题。
经过询问GPT,js语言中逗号表达式可能不会执行的代码,有两种节点,LogicalExpression 和 ConditionalExpression,举个例子:
var dd = a || aa && (b = 2,c = 3,d = 4) || d;
因为不知道 a的具体值,所以无法确定后面的逗号表达式是否会被执行,需要需要用代码过滤一下:
let canVisitFlag = true;
statementPath.traverse({
"LogicalExpression|ConditionalExpression"(_path) {
if (!_path.isAncestor(path)) {
return;
}
let key = _path.isLogicalExpression() ? "left" : "test";
let execPath = _path.get(key);
if (execPath != path && !execPath.isAncestor(path)) {
canVisitFlag = false;
_path.stop();
}
},
})
if (!canVisitFlag) return;
四.插件源码
完整源代码:
https://t.zsxq.com/19iczIKHG
目前还没有发现bug,并且还原效果非常好。
今天的分享就到这里,感谢阅读。
欢迎加入知识星球,学习更多AST和爬虫技巧。