首页
社区
课程
招聘
[原创]ARM64 目前主流的反混淆技术的初窥
发表于: 2025-2-14 01:53 31455

[原创]ARM64 目前主流的反混淆技术的初窥

2025-2-14 01:53
31455

声明

本文仅限于技术讨论,不得用于非法途径,后果自负。

前言

随着混淆技术和虚拟化的发展,我们不可能很方便的去得到我们想要的东西,既然如此,那只能比谁头更铁了,本文列举一下在逆向某一个签名字段中开发者所布下的铜墙铁壁,以及我的头铁方案,本文更多的是分析思路,而不是解决方案,所以样本自己找

BR reg

在ARM64 中 寄存器跳转只剩下BR 指令了,由于ida 为了 br的准确性(cs:ip跳转),ida会识别成函数跳转,但是这却给开发者带来了天大的便利,于是乎,一个贼好用的anti 反编译器函数分析方案横空出世
alt text
让我们回到汇编

1
2
3
4
.text:000000000008D1E8                 BL              sub_8D1F8
.text:000000000008D1EC                 MOV             X1, X0
.text:000000000008D1F0                 ADD             X1, X1, #0x38 ; '8'
.text:000000000008D1F4                 BR              X1

可以看到 X1的值是由sub_8D1F8 返回值加上 0x38 ,而sub_8D1F8一看地址 不对啊,为什么这么近。我们再看看sub_8D1F8的汇编
alt text
如果经常看汇编的小伙伴已经懂了

1
2
.text:000000000008D1FC                 STP             X29, X30, [SP]
.text:000000000008D200                 LDR             X0, [SP,#8]

sub_8D1F8的返回值 被x30 也就是lr寄存器赋值 所以 X1 = sub_8D1F8返回地址 +0x38 = 0x8D1EC + 0x38 = 0x8d224
alt text
既然如此 直接改跳转吧,写个脚本模式匹配下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def antiBR1(start,end):
    addr = start
    while addr < end :
        insn = idc.print_insn_mnem(addr)
        op0 = idc.print_operand(addr,0)
        op1 = idc.print_operand(addr,1)
        # .text:000000000008B03C                 BL              loc_8B04C
        # .text:000000000008B040                 MOV             X1, X0
        # .text:000000000008B044                 ADD             X1, X1, #0x38 ; '8'
        # .text:000000000008B048                 BR              X1
        # match 4 instructions
        if insn == "BL" and (idc.print_insn_mnem(addr + 0xc).find("BR") != -1 or idc.print_insn_mnem(addr + 0x8).find("BR") != -1):
            # find add
            addr1 =addr
            while 1:
                str = get_instruction_at_address(addr1)
                if str != None:
                    if str.find("ADD") != -1:
                        break
                addr1 = addr1 + 4
            opeValue = idc.get_operand_value(addr1,2)
            print("find add: %x" % opeValue)
            # patch addr B (addr +4 + opeValue)
            code,count =ks.asm("B "+ hex(addr + 4 + opeValue),addr)
            print(hex(addr))
            ida_bytes.patch_bytes(addr, bytes(code))
        addr = addr + 4

修复后
alt text

花指令

可以看到一排奇怪的东西
alt text
正常程序怎么会有呢,看看汇编

1
2
3
4
5
6
7
8
9
10
11
.text:000000000008D53C loc_8D53C                               ; CODE XREF: sub_8D170:loc_8D530↑j
.text:000000000008D53C                 MRS             X1, NZCV
.text:000000000008D540                 MOV             X0, XZR
.text:000000000008D544                 CMP             X0, XZR
.text:000000000008D548                 MSR             NZCV, X0
.text:000000000008D54C                 B.NE            loc_8D558
.text:000000000008D550                 CLREX
.text:000000000008D554                 BRK             #3
.text:000000000008D558
.text:000000000008D558 loc_8D558                               ; CODE XREF: sub_8D170+3DC↑j
.text:000000000008D558                 MSR             NZCV, X1

MSR NZCV, X0 x0 = 0 所以zf位为0 所以B.NE 恒成立 所以啥事没干 所以可以直接nop
简单的看下逻辑
alt text
0x8d240 在这个函数内 所以不是代码自解码 就是校验
alt text
查看sub_13C704
alt text
那就是检验咯 不管 下一个函数 sub_13DC3C
修复后发现f5 没东西
alt text
这怎么可能 切换到汇编,研究后

1
2
3
4
5
6
7
.text:000000000013DCE4 000              MOV             X30, X17
.text:000000000013DCE8 000               SUB             SP, SP, #0x50 ; 'P'
.text:000000000013DCEC 050              STP             X29, X17, [SP,#0x50+var_10]
.text:000000000013DCF0 050              ADD             X29, SP, #0x50+var_10
.text:000000000013DCF4 050              STUR            X0, [X29,#-0x10]
.text:000000000013DCF8 050              STUR            X1, [X29,#-0x18]
.text:000000000013DCFC 050            STR             X0, [SP,#0x50+var_30]
1
2
3
.text:000000000013DD94 050              LDR             X9, [SP,#0x50+var_30]
.text:000000000013DD98 050              LDR             X10, [SP,#0x50+var_38]
.text:000000000013DD9C 050              STR             X9, [X10,#8]

var_38 = x29 x29指向存放 x29 x30的栈地址 所以STR X9, [X10,#8] 等价于 x30 = x9 x0 是参数 所以回上一个函数
alt text

去看看吧 sub_8d5c8

ollvm

alt text

标准控制流平坦化

这里简单介绍什么是控制流平坦化
源代码

1
2
3
4
5
6
7
8
if(temp){
    print("ok");
    return 1
}
else{
    print("no");
     return 2
}

经过平坦化后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var flowState = 0;
while(1)
{
    switch(flowState):
        case 0:
            if(temp){
                flowState = 1
            }
            else{
                flowState = 2
            }
            break
        case 1:
            print("ok");
            flowState = 3
        case 2:
            print("no");
            flowState = 4
        case 3:
            return 1
        case 4:
            return 0
}

可以看到一个 while switch 的结构 其中flowState 负责控制整个流程 这个就是平坦化的基本原理 可以看到8行普通的代码被膨胀到了23行 假如我再平坦化 一次呢 我们会发现随着平坦化的越来越多,肉眼阅读的能力也越来越困难
下面介绍一个我从国外看到的方案 345K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Z5k6i4S2Q4x3X3c8J5j5i4W2K6i4K6u0W2j5$3!0E0i4K6u0r3j5X3I4G2k6#2)9J5c8X3S2W2P5q4)9J5k6s2u0S2P5i4y4Q4x3X3c8E0K9h3y4J5L8$3y4G2k6r3g2Q4x3X3c8S2M7r3W2Q4x3X3c8$3M7#2)9J5k6r3!0T1k6Y4g2K6j5$3q4@1K9h3&6Y4i4K6u0V1j5$3!0E0M7r3W2D9k6i4t1`.

1.计算支配节点

下面画一个简单的cfg图

1
2
3
4
5
6
7
       0
       |
       1
     /   \
   2       3
 /  \     /  \
4      5      6

如果走到某一个节点2 必须经过另外一个节点1 那么 2 被 1 支配 1 是 2的支配节点
通过bitset 可以快速计算出来

0: 0
1: 1
2:0,1
3: 0,1
4:0,1,2
5:0,1,2,3
6:0,1,3
将其反转
可得0 是所有节点的支配节点
有什么用?
仔细看平坦化的代码 可以发现 while 会被所有节点支配 所以 控制流分发快 必定被所有节点支配 由此定位到了分发块

2.路径计算

我们来看 如果从0要走到 5 有几种 路径
0125
0135
将cfg填充内容

1
2
3
4
5
6
7
8
9
10
11
            0
        flowState = 0
            |
            1
          /   \
        2       3
flowState = 1  flowState=2
      /  \     /  \
     4      5      6
     |      |       |
     1      1       1

可以得到 0125 flowState = 1, 0124 flowState = 2 那么如果计算支配节点的所有路径 是不是可以得到所有 flowState 的状态

状态指向计算

通过switch 可以轻松得到 状态指向的地址

修改控制流

将每一个状态所对应的 地址 连接

死代码消除

检查每一个 没有前继节点的节点 删除 反编译器自动优化

活跃变量分析

假设 0节点 flowState = 0 1 节点flowState参与 2节点中 flowState = 1 那么 flowState 1节点 将被删除 反编译器自动优化

反混淆

接下来回到这个demo
将他转换成cfg
alt text


[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2025-2-15 10:23 被method编辑 ,原因:
收藏
免费 218
支持
分享
最新回复 (132)
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
感谢分享
2025-2-14 02:52
0
雪    币: 2105
活跃值: (1732)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
666
2025-2-14 11:07
0
雪    币: 1
活跃值: (86)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享,努力学习一下
2025-2-14 11:41
0
雪    币: 59
活跃值: (1522)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
6666
2025-2-14 11:50
0
雪    币: 439
活跃值: (1528)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2025-2-14 12:33
0
雪    币: 2269
活跃值: (1643)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
7
不错,楼主最近还真是铁
2025-2-14 13:36
0
雪    币: 48
活跃值: (2253)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
膜拜大佬
2025-2-14 14:15
0
雪    币: 14
活跃值: (369)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
2025-2-14 14:53
0
雪    币: 1814
活跃值: (2343)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
5
2025-2-14 16:17
0
雪    币: 1411
活跃值: (997)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
6666
2025-2-14 16:27
0
雪    币: 1643
活跃值: (3296)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
6666
2025-2-14 17:21
0
雪    币: 105
活跃值: (5096)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
66666666666666666
2025-2-14 17:47
0
雪    币: 75
活跃值: (1163)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
14
66666666666666666
2025-2-14 17:53
0
雪    币: 13
活跃值: (2067)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
666666666
2025-2-14 17:59
0
雪    币: 1607
活跃值: (1987)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
666
2025-2-14 18:56
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17
666
2025-2-14 23:10
0
雪    币: 1494
活跃值: (1370)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
真的有看沒有懂...
2025-2-15 01:23
0
雪    币: 168
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
666
2025-2-15 12:14
0
雪    币: 1993
活跃值: (1557)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
20
6666666
2025-2-15 14:07
0
雪    币: 118
活跃值: (1106)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
6666666
2025-2-15 19:17
0
雪    币: 3136
活跃值: (1189)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
666
2025-2-15 20:48
0
雪    币: 2141
活跃值: (1400)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
666
2025-2-15 21:14
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24
666
2025-2-16 00:00
0
雪    币: 7347
活跃值: (4667)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
感谢分享
2025-2-16 13:08
0
游客
登录 | 注册 方可回帖
返回