首页
社区
课程
招聘
20
[原创]OLLVM控制流平坦化的改进
发表于: 2022-10-19 10:09 19133

[原创]OLLVM控制流平坦化的改进

2022-10-19 10:09
19133

0x1.传统平坦化

控制流平坦化这个混淆方式第一次出现于Ollvm项目中,作为其中的三种混淆方式之一fla。该混淆方式主要思想就是以基本块为单位,通过一个主分发器来控制程序的执行流程。在这种结构下,原有的程序控制逻辑被打碎,通过其中的控制变量配合Switch结构来实现控制流的转移。

OLLVM是一款是由瑞士西北科技大学开发的一套开源的针对LLVM的代码混淆工具,旨在加强逆向的难度,整个项目包含数个包含独立功能的LLVM Pass,每个Pass会对应实现一种特定的混淆方式,这些Pass将在后面进行细说,通过这些Pass可以改变源程序的CFG和源程序的结构。

 

图片.png
具体的混淆流程如下:

  • 1.收集原函数中所有的基本块,并初始化随机数种子。
  • 2.对入口基本块进行处理,切分基本块保证入口基本块只有一个后继。
  • 3.给每一个基本块分配一个随机数字,并新建一个变量var,在入口基本块中赋值为入口基本块后继基本块对应的数字。
  • 4.构造出基本的switch结构和循环框架,使得switch链接所有原有基本块。
  • 5.修正每个原有基本块的后继,使其跳转至switch结构,并在跳转之前根据后继和跳转条件构造对var的赋值语句。

而在原版的框架中,该混淆的普适性并不好。在针对于存在异常处理的C++代码中,是无法进行混淆的,同时由于该方案提出时间较早,早已有多种方法能够很好的去除该混淆,因此在该篇文章中,对原有的混淆进行改进,使其能够支持异常处理和防止被轻易去除。本文是基于控制流平坦化Pass的改进,主要提出的为改进原理,不会基于源码一行行分析,最后会将源码放出,可自行阅读。

0x2 支持异常处理

在传统的平坦化中,假定了每个函数的Terminator都是跳转指令BranchInst,然而在实际处理过程中并不一定是BranchInst,还有可能是SwitchInst,由于平坦化只处理后继小于等于2的情况,对于这种有多个后继的Terminator是无法处理的。针对于这种情况比较好处理,直接在上述第5步不修正其Terminator,让其保持原有的代码,直接continue即可,这样就可以保证其正常运行。
图片.png
但是除此之外,有一个指令为InvokeInst指令,这个指令有两个后继,但是一个是正常的基本块处,另一个是跳转到unwind相关的逻辑中,这个unwind基本块的开头必须为LandingPadInst,且只能通过InvokeInst指令来到达。所以当LandingPadInst被插入到SwitchInst中去的时候,由于不是通过InvokeInst到达的,所以会报错。
图片.png
图片.png

 

修正这种情况的思路也是非常的简单,首先需要确定每个基本块的Terminator是否是InvokeInst,是的话则从需要平坦化的基本块中剔除掉InvokeInst对应的UnwindBasicBlock。同时在进行第五步时判断当且仅当Terminator为BranchInst时才进行修正后继,否则不做任何处理。最后处理后结果如下所示。
图片.png

  • 代码修改如下(新增了判断Terminator是否为BranchInst)
    图片.png
  • 同时去除了LandingPad所在的基本块。
    图片.png

0x3 增强反反混淆效果

1
在现存的对抗思路中,无外乎就是模拟执行和静态分析两种思路。模拟执行首先需要定位到混淆后的控制流图中的真实块,即原控制流图中的基本块,然后从每个基本块开始模拟执行,给所有真实块(原函数中的基本块)下断点,当从基本块A出发,位于B中的断点触发,便能很容易的确定基本块后继(B是A的后继),如果遇到存在两个后继的情况则将对应的条件判断取反,从而使其获得两条路径,这样的思路往往采用angr或者unicorn实现,已经存在很多脚本了。而静态分析往往更加的困难,需要定位到对应的控制变量,并根据程序逻辑,找出每个基本块对应的值,并通过判断计算出每个基本块对应的后继。
  • 对于静态分析,更加偏向于经验化,通过少量的修改即可使得其适用性降低,因此静态方法去除控制流平坦化的思路往往被使用的较少,且普适性较差。
  • 而对于模拟执行,为了实现恢复的完整性,往往都是单独的从一个基本块出发,设下断点,确定该基本块的后继是什么。(当然也存在动态trace整个程序的执行流程,只要确定真实块即可简单的trace恢复执行流程,但是往往程序逻辑的触发条件是复杂的,有可能并不能覆盖所有的分支,因此这里不做讨论)
    图片.png

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

最后于 2022-10-19 10:33 被R1mao编辑 ,原因:
收藏
免费 20
支持
分享
赞赏记录
参与人
雪币
留言
时间
mb_kqntebgh
感谢你的贡献,论坛因你而更加精彩!
2024-11-10 18:43
mb_kqumvkku
感谢你分享这么好的资源!
2024-10-29 09:39
Ally Switch
+1
谢谢你的细致分析,受益匪浅!
2024-10-8 09:11
飞飞非反
为你点赞~
2024-7-16 09:46
明烛对酒
为你点赞~
2024-5-2 13:58
mb_yfioexda
为你点赞~
2023-8-22 10:54
FLYFISH123
为你点赞~
2023-5-25 14:26
CanineTooth
为你点赞~
2023-4-1 12:53
伟叔叔
为你点赞~
2023-3-18 00:59
PLEBFE
为你点赞~
2023-1-11 14:24
mb_tzesyfal
为你点赞~
2022-12-13 11:24
wx_Scr1pt
为你点赞~
2022-11-3 13:05
zhimian
为你点赞~
2022-10-23 22:49
34r7hm4n
为你点赞~
2022-10-22 17:19
trackL
为你点赞~
2022-10-22 17:17
fallw1nd
为你点赞~
2022-10-21 13:50
hzfjl
为你点赞~
2022-10-20 17:55
P.Z
为你点赞~
2022-10-20 09:13
R1mao
为你点赞~
2022-10-19 12:17
MaYil
为你点赞~
2022-10-19 10:32
最新回复 (7)
雪    币: 79
活跃值: (1844)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
不管动态分析还是静态分析,都是需要做控制流和数据流分析的,通过支配节点添加依赖关系同样可以反向优化,看看混淆后SSA形式的IR应该很容易看出这个变量的使用和定义吧
2022-10-19 14:41
0
雪    币: 3125
活跃值: (3343)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
3
淡淡的荧光 不管动态分析还是静态分析,都是需要做控制流和数据流分析的,通过支配节点添加依赖关系同样可以反向优化,看看混淆后SSA形式的IR应该很容易看出这个变量的使用和定义吧

但是根据支配树直接还原控制流图还是需要研究一下的。相比于之前的直接跳转还是有优势的。准确来说 只要静态分析够高超,没有什么混淆去不掉的

最后于 2022-10-19 17:59 被R1mao编辑 ,原因:
2022-10-19 17:57
2
雪    币: 24
活跃值: (1363)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
好贴
2022-10-19 21:31
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
5
学习了
2022-10-19 22:11
0
雪    币: 292
活跃值: (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
想问问这个改进后的平坦化,是不是对静态或动态符号执行的抵御还是不太行?
2022-11-4 11:46
0
雪    币: 3125
活跃值: (3343)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
7
小小通通 想问问这个改进后的平坦化,是不是对静态或动态符号执行的抵御还是不太行?

具体是什么不太行呢?angr的deflat是能够抵御的,还有D810

最后于 2022-11-4 17:26 被R1mao编辑 ,原因:
2022-11-4 17:26
0
雪    币: 1351
活跃值: (2094)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8

问题解决,删除。

最后于 2024-1-9 16:48 被ElainaDaemon编辑 ,原因: 问题解决
2023-2-28 18:32
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册