angr的深入学习

 

以前就会用angr   最近在看的时候 发现很多框架都利用了 angr 做了很多事情 

于是根据 两个项目来深入学习一下angr

一个是 反混淆ollvm的代码 

项目地址

https://github.com/pcy190/deflat

一个是 auto pwn 的框架

https://github.com/ChrisTheCoolHut/Zeratool

这两个都用到了angr 。。   所以重点学习一下

首先先说一下符号执行  其实根据这个名字 符号执行  大概都能懂是干啥的

就是根据符号 约束来求解   具体体现点就是 利用了ir

ir 是一个中间语言 如果了解过编译原理 应该能懂 ir 

ir 里面有一个 ITE    If-Then-Else    如果给定的IR表达式值为0,返回一个IR表达式,否则返回另一个

用伪代码可以这样理解

if(x+5=10){

then:

y=10

else:

y=20

}

就可以表示为 y=ITE(x+5==10,10,20)

其中 x 就可以约束 然后路径规划 求解,,,  详情可以看看angr源码  这几天看他们的官方文档 看的有点头疼 = = =

然后我们可以自己写代码来看 加深一下印象 

这里用到的程序 是上面ollvm给的例子

# -*- coding: utf-8 -*
from  angr import*

from pyvex import*
import archinfo
'''
.text:00000000004008CC B8 39 B0 59 AF                                mov     eax, 0AF59B039h
.text:00000000004008D1 B9 FD 15 87 19                                mov     ecx, 198715FDh
.text:00000000004008D6 48 8B 55 F0                                   mov     rdx, [rbp+var_10]
.text:00000000004008DA 0F BE 32                                      movsx   esi, byte ptr [rdx]
.text:00000000004008DD 81 FE 62 00 00 00                             cmp     esi, 62h
.text:00000000004008E3 0F 44 C1                                      cmovz   eax, ecx
.text:00000000004008E6 89 45 E4                                      mov     [rbp+var_1C], eax
.text:00000000004008E9 E9 AD 00 00 00                                jmp     loc_40099B
                             ; -----------------------------
[0x0F,0x84,0xB6,0x02,0x00,0x00]
'''

p=Project('check_passwd_flat')
irsb=p.factory.block(0x4008CC).vex
irsb.pp()
'''
   00 | ------ IMark(0x4008cc, 5, 0) ------
   01 | ------ IMark(0x4008d1, 5, 0) ------
   02 | PUT(rcx) = 0x00000000198715fd
   03 | PUT(rip) = 0x00000000004008d6
   04 | ------ IMark(0x4008d6, 4, 0) ------
   05 | t11 = GET:I64(rbp)
   06 | t10 = Add64(t11,0xfffffffffffffff0)
   07 | t12 = LDle:I64(t10)
   08 | PUT(rdx) = t12
   09 | PUT(rip) = 0x00000000004008da
   10 | ------ IMark(0x4008da, 3, 0) ------
   11 | t15 = LDle:I8(t12)
   12 | t37 = 8Sto32(t15)
   13 | t14 = t37
   14 | t38 = 32Uto64(t14)
   15 | t13 = t38
   16 | PUT(rsi) = t13
   17 | ------ IMark(0x4008dd, 6, 0) ------
   18 | t39 = 64to32(t13)
   19 | t16 = t39
   20 | PUT(cc_op) = 0x0000000000000007
   21 | t40 = 32Uto64(t16)
   22 | t18 = t40
   23 | PUT(cc_dep1) = t18
   24 | PUT(cc_dep2) = 0x0000000000000062
   25 | ------ IMark(0x4008e3, 3, 0) ------
   26 | t43 = 64to32(0x0000000000000062)
   27 | t44 = 64to32(t18)
   28 | t42 = CmpEQ32(t44,t43)
   29 | t41 = 1Uto64(t42)
   30 | t31 = t41
   31 | t45 = 64to1(t31)
   32 | t26 = t45
   33 | t46 = ITE(t26,0x198715fd,0xaf59b039)
   34 | t25 = t46
   35 | t47 = 32Uto64(t25)
   36 | t24 = t47
   37 | PUT(rax) = t24
   38 | PUT(rip) = 0x00000000004008e6
   39 | ------ IMark(0x4008e6, 3, 0) ------
   40 | t32 = Add64(t11,0xffffffffffffffe4)
   41 | t48 = 64to32(t24)
   42 | t34 = t48
   43 | STle(t32) = t34
   44 | ------ IMark(0x4008e9, 5, 0) ------
'''

 

一种可以很明显看到 汇编在 ir 里面的解释  ITE 表现的情况 可以在汇编里面看的出来 

伪c里面的对照

angr的深入学习_第1张图片

 

大概了解好了ite 就可以讲ollvm的项目代码了

首先 理清一下ollvm混淆  借用一下 https://security.tencent.com/index.php/blog/msg/112 上面的一个图  

angr的深入学习_第2张图片

angr的深入学习_第3张图片

 

观察可以看得出  真实块的后继块就是 预处理器  只需要 找到预处理器 就ok

ret 块是没有后继的块   序言是没有前继   

找的方法是根据 cfg图

 

cfg图 可以根据 边 点 的关系来判断出来预处理 和序言

angr的深入学习_第4张图片

先找到了没有 前继块的序言块  和没有后继块的ret 块 

然后根据 主分发器的前继 来寻找 预处理器  找到预处理器之后 直接找真实块就ok

angr的深入学习_第5张图片

 接下来就是难点了,,  怎么确认真实块的逻辑关系。。

angr的深入学习_第6张图片

接着看那个函数

angr的深入学习_第7张图片

statement    一个IR statement正在被解释执行(translate)   的时候断下来

angr的深入学习_第8张图片

这里就为啥我开篇说了ite 的概念 要不然 这里就理解不了 0xbird大佬在他的文章上也解释了这一做法,

修改临时变量  再执行就可以得到分支的地址    这一做法可以得到两个分支的逻辑 如果遇到call 就直接返回, 

angr的深入学习_第9张图片

 看看执行的块 是否在真实块集合里面  如果在的话 就把真实块地址返回

然后到 flow 这个列表里面 然后根据这

angr的深入学习_第10张图片

 这样就找到了真实块之间的调用关系

最后就是根据调用块来直接patch 

如果是有分支的话 

针对产生分支的真实块把CMOV指令改成相应的条件跳转指令跳向符合条件的分支,例如CMOVZ 改成JZ ,再在这条之后添加JMP 指令跳向另一分支

angr的深入学习_第11张图片

然后这个脚本就分析完毕了

 这里说一下无名侠大佬针对arm的ollvm  

发现arm 这个好多工具 支持的都不是太好 angr 也是如此

所以无名侠大佬用的unicorn 模拟执行 

其中 有一点就是  他们的虚假块和真实块之间的判断就只能利用特征码来判断

所以就麻烦了许多,,

zeratool 

发现也是17、18年的项目。 

发现已经有人发布在先知社区 写的非常不错 这里就不加以描述了 

链接地址

https://xz.aliyun.com/t/7224

 

 

 

 

参考链接

https://security.tencent.com/index.php/blog/msg/112

 

你可能感兴趣的:(栈溢出,堆溢出)