欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

angr的深入学习

程序员文章站 2022-03-24 09:16:31
...

 

以前就会用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的深入学习

 

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

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

angr的深入学习

angr的深入学习

 

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

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

找的方法是根据 cfg图

angr的深入学习

 

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

angr的深入学习

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

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

angr的深入学习

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

angr的深入学习

接着看那个函数

angr的深入学习 

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

angr的深入学习

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

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

angr的深入学习

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

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

angr的深入学习

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

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

如果是有分支的话 

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

angr的深入学习

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

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

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

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

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

所以就麻烦了许多,,

zeratool 

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

 

 

 

 

 

参考链接

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

 

相关标签: 栈溢出 堆溢出