AST还原实战|某数早期版本while-if 转 while-switch 语句
免责声明:
本篇文章仅作为学术研究和安全交流使用,切勿用于商业用途。如因违反规定产生任何法律纠纷,本人概不负责。如果本篇文章影响到官方利益,请添加文末的作者微信号告知,本人会在第一时间将文章删除。
一.需求
先看如下一段简单的代码:
-
function func (_$eE) {
-
var _$0n, _$2L, _$sC, _$o9, _$NU, _$qo, _$hK;
-
var _$tg, _$DM, _$ZZ = 0, _$Ce = [7, 3, 4, 0, 9, 2, 8, 6, 1, 5];
-
while (1) {
-
_$DM = _$Ce[_$ZZ++];
-
if (_$DM < 4) {
-
if (_$DM < 1) {
-
_$tg = !_$NU;
-
} else if (_$DM < 2) {
-
_$Uy(0);
-
} else if (_$DM < 3) {
-
_$NU = _$sC['$_ts'] = {};
-
} else {
-
_$sC = window, _$hK = String, _$o9 = Array;
-
}
-
} else if (_$DM < 8) {
-
if (_$DM < 5) {
-
_$NU = _$sC['$_ts'];
-
} else if (_$DM < 6) {
-
_$ZZ += -3;
-
} else if (_$DM < 7) {
-
return;
-
} else {
-
_$0n = [4, 16, 64, 256, 1024, 4096, 16384, 65536];
-
}
-
} else {
-
if (_$DM < 9) {
-
_$ZZ += 1;
-
} else {
-
if (!_$tg) _$ZZ += 1;
-
}
-
}
-
}
-
}
现在有这么一个需求,需要把 代码中的while - if 语句 还原成 while - switch语句,再通过 上面的分发器彻底还原。
彻底还原先放一边,我们来看看如何将 while - if 语句 还原成 while - switch 语句。
二.分析
俗话说,工欲善其事,必先利其器。 分析代码是还原过程中很重要的一环,只有分析透彻了,你才有思路去进行还原。
这是一个while + if 语句结构,由 _$Ce 这个数组来控制每一步走向哪个分支。_$Ce的元素 由 0 - 9组成,没有负值。
考虑下面的代码段:
-
if (_$DM < 1)
-
{
-
_$tg = !_$NU;
-
}
因为变量 _$DM 取自数组 _$Ce 。因此它不可能为负数,所以上面的代码等价于:
-
if (_$DM == 0)
-
{
-
_$tg = !_$NU;
-
}
-
同理下面这段代码:
-
else if (_$DM < 2)
-
{
-
_$Uy(0);
-
}
这里 _$DM < 2 ,符合条件的只有 _$DM = 0 和 _$DM = 1,而又因为上面 _$DM 的值已经是 0 了,所以只有当_$DM = 1时,才会走这个if分支,即:
-
else if (_$DM == 1)
-
{
-
_$Uy(0);
-
}
-
依葫芦画瓢,所有的if分支都可以改成这种形式:
-
if (_$DM == xxx)
-
{
-
somecode...
-
}
-
根据上面的思路,这段代码还原后,应该是这样的:
-
function func(_$eE) {
-
var _$0n, _$2L, _$sC, _$o9, _$NU, _$qo, _$hK;
-
-
-
var _$tg,
-
_$DM,
-
_$ZZ = 0,
-
_$Ce = [7, 3, 4, 0, 9, 2, 8, 6, 1, 5];
-
-
-
while (1) {
-
switch (_$Ce[_$ZZ++]) {
-
case 0:
-
_$tg = !_$NU;
-
break;
-
-
-
case 1:
-
_$Uy(0);
-
-
-
break;
-
-
-
case 2:
-
_$NU = _$sC['$_ts'] = {};
-
break;
-
-
-
case 3:
-
_$sC = window, _$hK = String, _$o9 = Array;
-
break;
-
-
-
case 4:
-
_$NU = _$sC['$_ts'];
-
break;
-
-
-
case 5:
-
_$ZZ += -3;
-
break;
-
-
-
case 6:
-
return;
-
-
-
case 7:
-
_$0n = [4, 16, 64, 256, 1024, 4096, 16384, 65536];
-
break;
-
-
-
case 8:
-
_$ZZ += 1;
-
break;
-
-
-
case 9:
-
if (!_$tg) _$ZZ += 1;
-
break;
-
}
-
}
-
}
-
三.思路
也许你会有疑问:这么简单的代码,直接手动处理不就完事了吗,还费劲的去写什么还原代码。我想说的是,对于这么几行,确实手动更省事,而成千上万行的混淆代码,手动去还原是非常不现实的,特别考验细心和耐心。
还原思路:
处理if语句,直接遍历最外层的if语句,在解析网站上可以看到,其父节点的父节点的类型为 WhileStatement 语句。
-
const if2Switch =
-
{
-
IfStatement(path)
-
{
-
let {node,parentPath} = path;
-
-
if (!parentPath.parentPath.isWhileStatement()) return; //定位到最外层的if语句
-
-
...
-
},
-
}
-
获取前一条语句节点,用其right节点构造siwtch的discriminant节点。
定义一个数组,用来保存每个if语句下面会真正执行的语句。
遍历这个path里面的 if语句,将符合条件的代码放在数组里。
遍历完成后,生成 switch节点,并进行替换即可。
完整代码我会放在星球里,仅供大家参考学习,需要的可自取。
三.结语
整个还原还是非常的容易,基本没啥需要注意的地方。整了个AST的交流群,有需要进群的可以加我微信,感谢阅读!
文章来源: blog.csdn.net,作者:悦来客栈的老板,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq523176585/article/details/122552030
- 点赞
- 收藏
- 关注作者
评论(0)