首页
论坛
专栏
课程

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

2020-1-13 21:40 2349

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

2020-1-13 21:40
2349

以下大部分内容来自知识星球, 因星球不再更新(效果不是很好,大家都不是很活跃,所以走免费路线了, 见文末),特重新编译并搬运

什么是 Bogus Control Flow

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

OLLVM 中的 BCF

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

反混淆的思路

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

利用 IDA 反混淆

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

 

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

 

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

实测

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

 

图片描述

 

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

 

图片描述

 

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

 

图片描述

 

Edit Segment, 把 Write 勾掉即可。

 

再按一下 F5,神奇的事情就发生了~

 

图片描述

 

最后,欢迎大家关注俺的公众号,会时不时的分享一些逆向的小技巧:

 



2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!

最后于 2020-1-13 21:44 被葫芦娃编辑 ,原因:
打赏 + 2.00
打赏次数 1 金额 + 2.00
 
赞赏  雪衫   +2.00 2020/01/14 感谢分享~
最新回复 (24)
KooJiSung 2020-1-13 21:57
2
0
真神奇
淡然他徒弟 2020-1-14 04:53
3
0
mark
dumBball 2020-1-14 09:10
4
0
大神可识得此阵??
Editor 2020-1-14 09:32
5
0
顶~ 感谢分享!
TopC 2020-1-14 09:57
6
0
感谢分享
MsScotch 2020-1-14 10:16
7
0
一级棒内
没图你说个图 1 2020-1-14 10:37
8
0
dumBball 大神可识得此阵??
聚安全?
有个老外的文章里面讲了怎么写脚本 patch 跳转
暗夜盗魔 1 2020-1-14 11:37
9
0
楼主用 6.9 也可以吗?这个我用 7.0 测试不行。。。
最后于 2020-1-14 11:45 被暗夜盗魔编辑 ,原因:
茅山小僧 2020-1-14 11:49
10
0
不错啊,学习了
茅山小僧 2020-1-14 12:01
11
0
擦,为啥不一样,我这是bss区域啊

葫芦娃 1 2020-1-14 12:47
12
0
暗夜盗魔 楼主用 6.9 也可以吗?这个我用 7.0 测试不行。。。
截图就是6.9.
葫芦娃 1 2020-1-14 12:47
13
0
茅山小僧 擦,为啥不一样,我这是bss区域啊
原理是一样的
黑洛 1 2020-1-14 14:19
14
0
mark,又学到一个技巧
风间仁 19 2020-1-14 14:41
15
0
试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
最后于 2020-1-14 14:43 被风间仁编辑 ,原因:
Mars. 2020-1-14 19:40
16
0
可以  思路无敌
库尔 6天前
17
0
good job
chmlqw 6天前
18
0
风间仁 试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
删除bss段,重建段名字为data(或者其他名字,开始和结束跟之前一样的地址) 然后不管是否修改段属性为只读 都没效果呢
killpy 2 6天前
19
0
那如果.data区域有其他数据呢 你咋办
lookzo 6天前
20
0
大神可识得此针,腻害了
ChengQing 4天前
21
0
1024
22
0
葫芦娃 1 2天前
23
0
风间仁 试了下楼上提到的bss,用先删segment再补segment填充值(挺挫但可行)的方式成功F5, 记录下
其实不用重建segment, 直接勾掉Write然后补0即可。
风间仁 19 2天前
24
0
恩, 这种方式更好(还方便直接脚本修改)
直接修改数据(相当于patch), 再声明为const即可, 也不用勾掉write了(毕竟segment很可能还有其他有用数据)  
最后于 2天前 被风间仁编辑 ,原因:
葫芦娃 1 2天前
25
0
风间仁 恩, 这种方式更好(还方便直接脚本修改)直接修改数据(相当于patch), 再声明为const即可, 也不用勾掉write了(毕竟segment很 ...
嗯,只要达到目的就可以
游客
登录 | 注册 方可回帖
返回