首页
社区
课程
招聘
[原创] Hex-Rays: 十步杀一人,两步秒OLLVM-BCF
发表于: 2020-1-13 21:40 26048

[原创] Hex-Rays: 十步杀一人,两步秒OLLVM-BCF

2020-1-13 21:40
26048

Bogus Control Flow 即虚假控制流,顾名思义,就是假的控制流,一般(OLLVM)表现为 一条结果恒定的条件表达式 & 一个永不到达的分支

OLLVM 中的虚假控制流是利用全局变量来构造条件表达式以制造虚假控制流,因为这个全局变量不会有写入的地方,所以这个表达式即一条结果恒定的条件表达式,因此始终只会走向一个真实分支,而另外的虚假分支即一个永不到达的分支。 大家把这个表达式称为 "不透明谓词"

上面说了, 虚假控制流就是永不到达的分支, 只要你了解一点点的编译原理、编译器优化,就会想到,这种代码应该都是被死代码消除(DCE, Dead Code Elimination)的。
所以只要能实现运行一遍 DCE 即可消除掉 BCF 混淆。

HexRays Decomplier肯定是有DCE优化的,但是为什么不能自动优化掉BCF? 原因出在不透明谓词的识别上。

之前快出 IDA7.3 的时候,就有人说 7.3 支持自动优化不透明谓词,然而拿到手之后发现并没有什么区别, 实际上经过测试,这个优化我用 6.9 测试也是存在的。

然而,使 IDA 无法识别出不透明谓词的原因是:恒定的全局变量是变量而不是常量,也就是说,这个变量的地址是可写而非只读的,你想办法把它改为只读,IDA 就可以进行优化了。

随便找了一个 bcf 样本测试。优化之前是这个样子的:

图片描述

那么如何让这堆 dword_xxx 变成可读呢?

图片描述

因为我的.data 段里没有任何其他东西,所以:

图片描述

Edit Segment, 把 Write 勾掉即可。


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

最后于 2020-6-3 10:54 被葫芦娃编辑 ,原因:
收藏
免费 20
支持
分享
打赏 + 2.00雪花
打赏次数 1 雪花 + 2.00
 
赞赏  orz1ruo   +2.00 2020/01/14 感谢分享~
最新回复 (36)
雪    币: 357
活跃值: (3568)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
2
真神奇
2020-1-13 21:57
0
雪    币: 6209
活跃值: (5022)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
3
mark
2020-1-14 04:53
0
雪    币: 1237
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
大神可识得此阵??
2020-1-14 09:10
0
雪    币: 29177
活跃值: (63566)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
5
顶~ 感谢分享!
2020-1-14 09:32
0
雪    币: 6992
活跃值: (1821)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2020-1-14 09:57
0
雪    币: 3237
活跃值: (1886)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
一级棒内
2020-1-14 10:16
0
雪    币: 401
活跃值: (55)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
dumBball 大神可识得此阵??
聚安全?
有个老外的文章里面讲了怎么写脚本 patch 跳转
2020-1-14 10:37
0
雪    币: 2512
活跃值: (672)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
9
楼主用 6.9 也可以吗?这个我用 7.0 测试不行。。。
最后于 2020-1-14 11:45 被暗夜盗魔编辑 ,原因:
2020-1-14 11:37
0
雪    币: 1339
活跃值: (2228)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
10
不错啊,学习了
2020-1-14 11:49
0
雪    币: 1339
活跃值: (2228)
能力值: ( LV5,RANK:75 )
在线值:
发帖
回帖
粉丝
11
擦,为啥不一样,我这是bss区域啊

2020-1-14 12:01
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
12
暗夜盗魔 楼主用 6.9 也可以吗?这个我用 7.0 测试不行。。。
截图就是6.9.
2020-1-14 12:47
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
13
茅山小僧 擦,为啥不一样,我这是bss区域啊
原理是一样的
2020-1-14 12:47
0
雪    币: 6124
活跃值: (4716)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
14
mark,又学到一个技巧
2020-1-14 14:19
0
雪    币: 29336
活跃值: (7879)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
15
试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
最后于 2020-1-14 14:43 被风间仁编辑 ,原因:
2020-1-14 14:41
0
雪    币: 158
活跃值: (755)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
可以  思路无敌
2020-1-14 19:40
0
雪    币: 1334
活跃值: (1995)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
good job
2020-1-15 15:59
0
雪    币: 54
活跃值: (705)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
风间仁 试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
删除bss段,重建段名字为data(或者其他名字,开始和结束跟之前一样的地址) 然后不管是否修改段属性为只读 都没效果呢
2020-1-15 16:43
0
雪    币: 83
活跃值: (1092)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
19
那如果.data区域有其他数据呢 你咋办
2020-1-15 16:52
0
雪    币: 6
活跃值: (1201)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
大神可识得此针,腻害了
2020-1-15 17:12
0
雪    币: 573
活跃值: (1019)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
1024
2020-1-17 14:13
0
雪    币: 977
活跃值: (435)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
22
2020-1-17 14:18
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
23
风间仁 试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
其实不用重建segment, 直接勾掉Write然后补0即可。
2020-1-19 11:44
0
雪    币: 29336
活跃值: (7879)
能力值: ( LV15,RANK:3306 )
在线值:
发帖
回帖
粉丝
24
恩, 这种方式更好(还方便直接脚本修改)
直接修改数据(相当于patch), 再声明为const即可, 也不用勾掉write了(毕竟segment很可能还有其他有用数据)  
最后于 2020-1-19 12:01 被风间仁编辑 ,原因:
2020-1-19 12:01
0
雪    币: 916
活跃值: (3434)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
25
风间仁 恩, 这种方式更好(还方便直接脚本修改)直接修改数据(相当于patch), 再声明为const即可, 也不用勾掉write了(毕竟segment很 ...
嗯,只要达到目的就可以
2020-1-19 12:16
0
游客
登录 | 注册 方可回帖
返回
//