首页
社区
课程
招聘
[原创]OLLVM-BR间接混淆去除
发表于: 3天前 1337

[原创]OLLVM-BR间接混淆去除

3天前
1337

本文章主要介绍ollvm的间接混淆,以及如何去除ollvm的间接混淆,。因样本涉及一些私密的东西,就不方便公开了,接下来介绍的一些去除混淆思路是通用的,大可不用担心。

分析架构所属:arm64

接下来主要介绍间接混淆里的间接跳转(Indirect Branch)和间接函数调用(Indirect Call),这两种混淆方式也是最常见的。

传统的程序跳转通常是直接的,例如B 0x168730(跳转到一个固定的地址),而间接跳转则不同,它不直接指定目标地址,而是通过一个寄存器或内存中的值来确定跳转目标。比如下面的这张图:

image-20250615100312545

在伪代码窗口看到的类似__asm { BR X8 }这种代码,在汇编里的表现形式则是BR X8,当出现这种的代码表现形式,就证明此函数采用了间接跳转混淆。

静态分析失效:逆向工具在遇到间接跳转时,在不执行代码的情况下无法确定代码分支跳转的可能目标,也就意味着自动生成的控制流图会是断裂的或不完整的,严重阻碍对程序逻辑的理解。

image-20250615101915945

比如这种控制流图就是ida无法正常识别需要跳转的代码,就导致这些分支代码未被正确识别进函数体,从而出现这种没有头部链接的情况。

难以识别关键路径:由于真实路径被隐藏,分析人员难以区分正常代码和混淆代码,也无法快速定位程序的核心功能。

复杂性增加:间接跳转通常伴随着复杂的算术和逻辑运算来计算目标地址,这进一步增加了分析的负担。

image-20250615102616743

这种就是需要通过一些逻辑运算得到x8寄存器的值,这个值也就是最后跳转的目标地址。如果人工这样去计算这个地址,会耗费大量时间,效率低下,所以不建议去静态分析计算,而是动态执行的方式去获取到寄存器里的值,最后统一patch目标地址。

正常的函数跳转都是BL 0x888888(函数地址),而间接函数调用则不同,它不直接指定目标地址,而是通过一个寄存器或内存中的值来确定跳转目标。比如下面的这张图:

image-20250615103825169

image-20250615105109207

在伪代码里看到的是v278 = v277(v50 + 19);,没有一个明显的函数跳转符号,在汇编可以看到BLR X8,并且上面也是通过大量逻辑运算得到函数目标地址存储到x8寄存器。当出现这种的代码表现形式,就证明此函数采用了间接函数调用混淆。

当我们知道某一个函数确实是被调用了,hook也确实是走了,此时我们想知道这个函数是在哪里被调用的,此时我们就需要使用快捷键X交叉引用查看,但是这样操作后可能会遇到的问题是提示没有地方调用这个函数。

image-20250615110004931

所以间接函数调用混淆,会导致我们无法清晰知道函数调用逻辑,进而分析函数更困难。

接下来展开对间接混淆相关的去除思路

我会讲几种间接跳转混淆表现形式的去除思路。

image-20250615113353703

这种处理方式是最简单的,可以看出它这里面没有它没有任何条件判断相关的逻辑(CSELCSET),只需要计算出目标寄存器X9的值,最后使用keypatch将汇编指令BR X9 ptach成B 0x153AF0即可。

image-20250615173107617

CSEL指令的出现说明这里是有条件判断的,也就是if ...else...代码。

拆解下这里的汇编指令

首先,它检查 X0 是否大于 0。

如果 X0 > 0,则 X8 的值保持不变。

如果 X0 <= 0,则 X8 的值会被更新为 X9 的值。

用三元表达式可以表示为:

X8 = (X0 > 0) ? X8 : X9;

最后取X8寄存器里的内容作为跳转地址赋予X8.

通过上面的拆解分析继续计算X8和X9的值,通过计算得到X8=0x1eabc0,X9=0x1e9c00

image-20250615174606649

我们先跳转到X8寄存器的地址

image-20250615174835776

后面sub_16AAC0就是0x1eabc0地址里存储的跳转地址

继续跳转到X9寄存器的地址

image-20250615175659514

sub_1651EC就是0x1e9c00地址里存储的跳转地址

最后总结可得patch的汇编指令为

image-20250615180218117

这时可能会有疑问,为什么是选择在CSEL指令和BR指令的值patch,却不直接在CSEL指令和其下一条指令地址patch呢,因为会有一种特殊情况,在CSEL指令和BR指令之间存在真实指令,如果选择第二种方式去patch,那么B指令后面的指令都不会执行,从而导致真实指令缺失,影响程序的分析

这种其实原理是和上面一样的,只是有多个条件判断

image-20250615181348782

这里都是用EQ作为条件判断,当条件满足时选第二个寄存器作为赋值,否则就是第三个寄存器

继续拆解上面的指令

第一个条件判断

第二个条件判断

第三个条件判断

第四个条件判断

第五个条件

用代码表现为

计算方式和上面一样的,下面就是patch后的流图

image-20250615195113738

image-20250615195421611

image-20250615195515625

这里就是一个跳转表混淆,继续拆解

ADRL X13, dword_5CE30

dword_5CE30:这里储存的是跳转偏移量的数组

ADR X14, loc_1505F8

loc_1505F8:跳转目标地址的基地址

LDRSW X15, [X13,X12,LSL#2]

LDRSW: 加载一个32位有符号数

X13: 这是前面加载的跳转表基地址。

X12: 这是索引寄存器。通常,switch 语句的变量值会经过处理后放入 X12。

LSL#2: 这意味着 X12 的值被左移了两位(乘以4)。这非常关键,因为它表明跳转表中的每个条目是4字节长(一个32位值)。这与 LDRSW 加载一个32位有符号数是匹配的。

这条指令的含义是:从地址 (X13 + X12 * 4) 的位置加载一个32位有符号整数到 X15。这个有符号整数就是跳转的偏移量。

ADD X14, X14, X15

计算跳转表基地址+偏移量的结果得到跳转目标地址

拆解分析完,接下来就是去修复跳转表了

点击dword_5CE30查看

image-20250615201634762

这里很正常存储了4个偏移数据,字节格式也是正常转换了的,以4字节显示

如果是遇到了下面的这种,在数据段里都是一个字节显示的,我们需要用D键去转为4个字节为一组的数据

image-20250615201728078

结果就会变成这样的

image-20250615201823567

继续操作

选中这段数据

image-20250615202056603

点击下面的Offset(user-defined)

image-20250615202145755

image-20250615202357097

Base address填写上面分析的跳转目标基地址,点击ok会弹出下面的窗口

image-20250615202656895

点击OK,这里之前的偏移量就变成了跳转目标地址-跳转目标基地址

image-20250615202800396

返回到原来的位置,选中BR X14这一行的X14寄存器,在Edit栏里选中Specify switch idiom...

image-20250615202955321

image-20250615202941771

image-20250615203403054

这样填写后点击OK就可以正常显示了

image-20250615203543948

先看下这里的表现形式,off_1EDEA0是函数表的首地址,里面存储了大量的函数,后面是运算得到索引,根据这个索引去函数表里去除对应的函数地址

image-20250615204040598

我这里以光标所在函数为例,先计算出这里的索引结果


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 99
支持
分享
最新回复 (50)
雪    币: 2287
活跃值: (2739)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习一下
3天前
0
雪    币: 2458
活跃值: (1043)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
3
大晚上的就别卷了,各位师傅,刚发布就库库的来了
3天前
1
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
1
3天前
0
雪    币: 1484
活跃值: (2762)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
大佬好卷 大晚上还发布
3天前
0
雪    币: 13
活跃值: (245)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习一下
3天前
0
雪    币: 104
活跃值: (5751)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
666
3天前
0
雪    币: 30
活跃值: (1785)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
666
3天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
666
3天前
0
雪    币: 586
活跃值: (1339)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
123
3天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
6
3天前
0
雪    币: 27
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
1
3天前
0
雪    币: 552
活跃值: (4664)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
刘大屌牛逼 下次嗦你牛子
3天前
0
雪    币: 2868
活跃值: (7468)
能力值: ( LV7,RANK:102 )
在线值:
发帖
回帖
粉丝
14
这是什么模块
3天前
0
雪    币: 27
活跃值: (1685)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
123
3天前
0
雪    币: 25
活跃值: (1551)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
16
666
3天前
0
雪    币: 745
活跃值: (5883)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
17
1
3天前
0
雪    币: 5203
活跃值: (4800)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
666
3天前
0
雪    币: 148
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
666
3天前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
666
3天前
0
雪    币: 20
活跃值: (1078)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
666
3天前
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
学习一下
3天前
0
雪    币: 3073
活跃值: (4452)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
感谢分享
3天前
0
雪    币: 1520
活跃值: (2638)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
24
有实力的
3天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25
感谢分享
3天前
0
游客
登录 | 注册 方可回帖
返回