AST还原实战|某数早期版本while-if 转 while-switch 语句

举报
悦来客栈的老板 发表于 2022/01/19 00:03:13 2022/01/19
【摘要】 免责声明: 本篇文章仅作为学术研究和安全交流使用,切勿用于商业用途。如因违反规定产生任何法律纠纷,本人概不负责。如果本篇文章影响到官方利益,请添加文末的作者微信号告知,本人会在第一时间将文章删除。 一.需求 先看如下一段简单的代码: function func (_$eE) { var _$0n, _$2L, _$sC, ...

免责声明:

本篇文章仅作为学术研究和安全交流使用,切勿用于商业用途。如因违反规定产生任何法律纠纷,本人概不负责。如果本篇文章影响到官方利益,请添加文末的作者微信号告知,本人会在第一时间将文章删除。

一.需求

先看如下一段简单的代码:


       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 语句

二.分析

俗话说,工欲善其事,必先利其器。 分析代码是还原过程中很重要的一环,只有分析透彻了,你才有思路去进行还原。

  1. 这是一个while + if 语句结构,由 _$Ce 这个数组来控制每一步走向哪个分支。_$Ce的元素 由 0 - 9组成,没有负值。

  2. 考虑下面的代码段:

    
             if (_$DM < 1)
             {
                _$tg = !_$NU;
             }
         
        

    因为变量 _$DM 取自数组 _$Ce 。因此它不可能为负数,所以上面的代码等价于:

    
             if (_$DM == 0)
             {
                _$tg = !_$NU;
             }
         
        
  3. 同理下面这段代码:

    
             else if (_$DM < 2)
             {
                _$Uy(0);
             }
         
        

    这里 _$DM < 2 ,符合条件的只有 _$DM = 0 和 _$DM = 1,而又因为上面 _$DM 的值已经是 0 了,所以只有当_$DM = 1时,才会走这个if分支,即:

    
             else if (_$DM == 1)
             {
                _$Uy(0);
             }
         
        
  4. 依葫芦画瓢,所有的if分支都可以改成这种形式:

    
             if (_$DM == xxx)
             {
                somecode...
             }
         
        
  5. 根据上面的思路,这段代码还原后,应该是这样的:

    
             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;
                 }
               }
             }
         
        

三.思路

也许你会有疑问:这么简单的代码,直接手动处理不就完事了吗,还费劲的去写什么还原代码。我想说的是,对于这么几行,确实手动更省事,而成千上万行的混淆代码,手动去还原是非常不现实的,特别考验细心和耐心。

还原思路:

  1. 处理if语句,直接遍历最外层的if语句,在解析网站上可以看到,其父节点的父节点的类型为 WhileStatement 语句。

    
             const if2Switch =
             {
              IfStatement(path)
               {
                let {node,parentPath} = path;
                if (!parentPath.parentPath.isWhileStatement()) return;  //定位到最外层的if语句
                 ...
               },
             }
         
        
  2. 获取前一条语句节点,用其right节点构造siwtch的discriminant节点。

  3. 定义一个数组,用来保存每个if语句下面会真正执行的语句。

  4. 遍历这个path里面的 if语句,将符合条件的代码放在数组里。

  5. 遍历完成后,生成 switch节点,并进行替换即可。

完整代码我会放在星球里,仅供大家参考学习,需要的可自取。

三.结语

整个还原还是非常的容易,基本没啥需要注意的地方。整了个AST的交流群,有需要进群的可以加我微信,感谢阅读!

7097d47546939eab49ce829b75b863ef.png   

文章来源: blog.csdn.net,作者:悦来客栈的老板,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/qq523176585/article/details/122552030

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。