首页 > 其他分享 >三层switch转一层switch的处理方法

三层switch转一层switch的处理方法

时间:2024-08-17 18:48:54浏览次数:6  
标签:一层 ast Ai 31 li switch fi 三层

阿里三层switch转一层switch的处理方法

如下所示的混淆代码,在淘系140、227等滑块的代码经过一些转化后得到。

这些转化包括:

//去自执行避免变量污染
traverse(ast, { UnaryExpression: renameScopIdn })
//去自执行
traverse(ast, { UnaryExpression: movezishixing })
//三目运算转if-else
traverse(ast, { ConditionalExpression: condition2ifelse })


//例如a&&console.log(b)  转if-no-else
traverse(ast, { LogicalExpression: Logic2if })

//将9==Ai,转成Ai==9,放在左边
traverse(ast, { BinaryExpression: putIdenLeft })

// Ai > 9  Ai < 10 转 Ai == x
traverse(ast, { BinaryExpression: ifLeGe2Eq })


//从switchCase入口是很有用的
//if嵌套转switch
//if嵌套能转switch的究极原因在于,它是通过一些混淆逻辑得到的代码,肉眼分析就会发现,每个代码块总是对应了条件变量等于某个值时,才会进入
traverse(ast, { SwitchCase: if2switch })

通过上面的转化得到了三层嵌套的switch,这篇我们重点看看这个转化:

 try {
    for (var li = 16996; void 0 !== li;) {
      var Ci = 31 & li,
        fi = li >> 5,
        mi = 31 & fi,
        bi = fi >> 5,
        Ai = 31 & bi;
      switch (Ci) {
        case 0:
          switch (mi) {
            case 0:
              switch (Ai) {
                case 12:
                  N = Se[vo], Q = N[Z](), li = Q ? 11460 : 1475;
                  break;
                case 5:
                  li = 8804;
                  break;
                case 2:
                  W = $ % 128, ie = [], M = W + 128, _ = $ - W, W = _ / 128, _ = 127 & W, ie.push(M, _), se = ie, li = 16390;
                  break;
                case 0:
                  Dn.push(0), li = 11522;
                  break;
                case 1:
                  L = mo, li = 24641;
                  break;
                case 3:
                  Oe = K, li = 20257;
                  break;
                case 4:
                  _ = 0 !== se.length, I = je, li = _ ? 22694 : 16963;
                  break;
                ……
                ……
                ……
                ……
                
                

通过上面可以看出,在满足

var Ci = 31 & li,
fi = li >> 5,
mi = 31 & fi,
bi = fi >> 5,
Ai = 31 & bi

并且 Ci===0 && mi ===0 && Ai ===0

的情况下进入第一个代码块,眼看好像很多变量,实际上都是由li运算得来,因此就是求满足这些约束的条件下的li的值。

然后最终转化为:

switch(li){
    case x:
    …………
    …………
}

那么怎么求解嘞?

嘿嘿,下面提供两种思路:

1.穷举

通过for循环,穷举0到999999(一个较大的数)的范围内,看看是否有满足上面条件的li的值

代码示例:

function iter() {

  here: for (let li = 0; li < 999999; li++) {
    var Ci = 31 & li,
      fi = li >> 5,
      mi = 31 & fi,
      bi = fi >> 5,
      Ai = 31 & bi;
    for (let con1 = 0; con1 < 26; con1++) {
      for (let con2 = 0; con2 < 26; con2++) {
        for (let con3 = 0; con3 < 26; con3++) {
          if (Ci === con1 && mi === con2 && Ai === con3) {
            //记录下来li和对应代码块的映射关系,后续重建switch即可
            console.log(con1, con2, con3, "<==>", li)
            // if (li === 16996) break here
          }


        }

      }

    }



  }
}
iter()

输出:

……
21 18 16 <==> 16981
22 18 16 <==> 16982
23 18 16 <==> 16983
24 18 16 <==> 16984
25 18 16 <==> 16985
0 19 16 <==> 16992
1 19 16 <==> 16993
2 19 16 <==> 16994
3 19 16 <==> 16995
4 19 16 <==> 16996
……

可以看到,还是挺快的就得出结果了。

值得注意的是,你会发现为什么我只遍历0到26的范围,这个的话取决于程序三层switch的case的范围有多大,当然你也可以写ast程序去搜集这三个的变化范围


2.约束求解

作者推荐使用这种方式,想到这个是因为作者的毕业设计使用的就是这个技术,如今没想到在js逆向上还能排上用场

我们直接使用z3-solver进行约束求解得到一个满足条件的解即可,穷举些许显得low

如下我们直接使用Z3对收集到的情况进行求解:

import json
from z3 import *
import sys


li = BitVec('li', 16)
s = Solver()  # 创建约束求解器
Ci = li & 31
fi = li >> 5
mi = 31 & fi
bi = fi >> 5
Ai = 31 & bi


def get_ans(n1, n2, n3):
    s.add(Ci == n1)  # 添加约束条件
    s.add(mi == n2)  # 添加约束条件
    s.add(Ai == n3)  # 添加约束条件
    if s.check() == sat:  # 检测是否有解
        # result = s.model()
        resst = s.model().eval(li).as_string()  # 若有解则得出解,注意这里的解是等式
        s.reset()
        return resst
    else:
        print('no result')  # 无解
for n1 in range(26):
    for n2 in range(26):
        for n3 in range(26):
            ans = get_ans(n1, n2, n3)
            print(n1,n2,n3,"<==>",ans)

总结

两种方式的话,速度我没有进行比较,甚至目前cpu情况下,穷举更快一些,为什么提出第二个方法呢?

实际上我在设想,我们没必要写前面所说那些复杂的ast还原插件,写了费劲巴拉调试了很久,才得到,三层switch嵌套,最后来转一层,如果我们能通过程序分析的策略往深度分支进行探索,一路上不断收集约束集合,直到最深的代码块(没有子分支),此时将收集到的约束进行求解,即可一步到位直接得到li和最终执行代码块的关系,直接就从混淆的代码得到了一层switch

上述方法的难点在于约束收集,纵观基于js写的符号执行引擎,ExpoSE算一个,但是文档稀少,安装编译都成问题,其次这些符号执行引擎都是动态符号执行,需要程序能够运行的情况下设计实现的,但是我们的被混淆的js代码一般都是不能直接运行的,虽然我们可以通过一些操作,比如将最主要的需要还原的代码抠出来,然后将不能执行的代码块暂时替换成能够运行的代码,但是映射关系需要留存好,后续还原用。但是这些为了能够使用动态符号执行思路的前期操作,比起直接写ast插件的方式,工作量也不一定小,所以解混淆嘛!本着简单直接的方式,所以还是目前建议使用ast插件的方式,进行,因为动态符号执行还涉及到代码插装等,写论文的水平了,已经是……

记得加入我们的学习群,更多知识尽在我的知识星球:

我的星球https://t.zsxq.com/125umU2l8

qq群 961566389获取更多资讯

标签:一层,ast,Ai,31,li,switch,fi,三层
From: https://www.cnblogs.com/steed4ever/p/18364817

相关文章

  • JDK 17 以上 switch 语句的 变化
    在JDK17中,switch语句得到了显著的增强,引入了模式匹配(PatternMatching)等特性,使得代码更加简洁、高效。以下是JDK17中switch语句的主要用法和特点:1.格式变化在JDK17中,switch语句的格式发生了改变,主要体现在以下几个方面:冒号变为箭头:传统的switch语句中的冒号(:)在JDK17中被......
  • Spring DI 简单演示三层架构——构造注入
    SpringIOC的常见注入方法有3种:Setter注入、构造注入和属性注入。想了解更多可点击链接:Spring注入、注解及相关概念补充        属性注入 不推荐。原因:使用私有的成员属性变量,依靠反射实现,破坏封装,只能依靠IOC容器实现注入,不严谨。所以我只演示Setter注入和构造......
  • Spring DI 简单演示三层架构——Setter 注入
    SpringIOC的常见注入方法有3种:Setter注入、构造注入和属性注入。想了解更多可点击链接:Spring注入、注解以及相关内容补充        属性注入 不推荐。原因:使用私有的成员属性变量,依靠反射实现,破坏封装,只能依靠IOC容器实现注入,不严谨。所以我只演示Setter注入和构......
  • Cisco Nexus 9000v Switch, NX-OS Release 10.5(1)F - 用于网络原型设计和学习研究的
    CiscoNexus9000vSwitch,NX-OSRelease10.5(1)F用于网络原型设计和学习研究的虚拟化数据中心交换机请访问原文链接:https://sysin.org/blog/cisco-nexus-9000v/,查看最新版。原创作品,转载请保留出处。ReleaseDateNX-OSSystemSoftwareReleaseDateCiscoNX-OSRe......
  • KingbaseES V8R6集群运维案例之---switchover切换repmgr版本错误
    案例说明:KingbaseESV8R6集群,执行switchover切换时,报错“unabletoparse'repmgr's'rportedversion..."。适用版本:KingbaseESV8R6**一、问题现象**如下所示,执行switchover切换时,报错“unabletoparse'repmgr's'rportedversion...":二、问题分析1、在集群节点执......
  • 思科三层交换机实现EIGIP路由协议6
    #路由协议实现##任务六三层交换机实现EIGIP路由协议6##1配置计算机的IP地址、子网掩码和网关#2配置Switch-A的名称及其接口IP地址Switch(config)#hostnameSwitch-ASwitch-A(config)#iproutingSwitch-A(config)#intg0/1Switch-A(config-if)#noswitchportSwitch-......
  • Switch增强
    Switch表达式增强JDK17新特性-全新的switch表达式在Java12的时候就引入了switch表达式,注意这里是表达式,而不是语句,原来的switch是语句。如果不清楚两者的区别的话,最好先去了解一下。主要的差别就是就是表达式有返回值,而语句则没有。再配合模式匹配,以及yield和“->”符号的加......
  • yum失效后Centos7 安装编译 fresswitch 1.10.8
    一、yum替换Centos7在2024.7月已停止yum服务,需替换为国内yum1、先备份mv/etc/yum.repos.d/CentOS-Base.repo/etc/yum.repos.d/CentOS-Base.repo.bak2、替换成yum阿里源curl-o/etc/yum.repos.d/CentOS-Base.repohttp://mirrors.aliyun.com/repo/Centos-7.repo3、......
  • 三层架构与解耦——IoC&DI机制【后端 7】
    三层架构与解耦——IoC&DI机制在软件开发领域,三层架构(Controller、Service、Dao)是一种广泛采用的架构模式,它通过将应用程序分为三个主要层次来组织代码,旨在提高代码的可维护性、复用性和可扩展性。而解耦(Decoupling)则是实现这些目标的关键技术之一。本文将深入探讨三层架......
  • 在Debian上安装freeswitch
    在Debian上安装freeswitch说明:首次发表日期:2024-08-12参考文档:https://medium.com/@jogikrunal9477/ultimate-guide-to-installing-freeswitch-on-ubuntu-22-04-lts-3745ef6a6bd6https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/Linux/Dep......