符号执行 angr

符号执行 angr
0x0符号执行是什么
首先,最传统的符号执行,就是静态符号执行。将输入的变量符号化后获取变量在流程中的改变,然后来直接得出原始的输入值。
举个例子:

a=raw_input() 
b=10*a 
if b == 0x10:
 	prin0t('win') 
else:
 	print('error')

那在这段代码中,在执行符号执行的过程,先将a设为x,b=10*x,那么b==0x10跟b!=0x10就是两个不同的路径,分别走向win跟error。在符号执行结束(也就是程序退出时候),约束求解器就会对每个不同路径所满足的约束式求解,来解出满足这个路径的值。
之后,还有将静态执行鱼实际执行结合的动态符号执行。动态符号执行就是不停的对x取随机数,之后将约束取反后对另外一条路径执行,还是以上面的为例,随机取a=2,走的error的路线,那取反,得到走win路线的值。以此类推,直到遍历走完所有路径。
一般而言,使用符号执行以来angr这个py库
//angr好像是py2的库,反正我物理机上py3的环境没装成功。
0x1 angr的使用
//其实我也不怎么会用2333
//不过据说angr跑起来很吃配置,因为angr会尽可能的去遍历所有路径,所以当存在循环时候,很容易就直接指数倍增长寻找次数,然后内存就gg了。

import angr
import claripy

这个俩个库先引用进来,angr自然不说,claripy这个库用来定义抽象的数据。
首先,先创建一个angr工程

r=angr.Project('filename',auto_load_libs=False)

之后

start=r.factory.entr_state()

entry_state()函数接受一个list作为程序的命令行参数并返回程序入口状态
标准输入:
程序从标准输入处读取数据时候,使用read_from()函数,如

k=state.posix.file[0].read_from(1)

就是重标准读入读取一个字节
之后,在获取到程序入口点状态后,我们可以使用angr的simgr模拟器来进行符号执行:

sm=r.factory.simgr(state)

从入口点创建一个模拟器进行符号执行
同时,对程序当前状态的表示有:

step()表示向下执行一个block(42bytes),step()函数产生active状态,表示该分支在执行中;
run()表示运行到结束,run()函数产生deadended状态,表示分支结束;
explore()可以对地址进行限制以减少符号执行遍历的路径。 explore()产生found状态,表示探索的结果等等

然后emmm,我看别人的wp好像一般是用的explore来进行约束后求得答案

answer=sm.explore(find=good,avoid=bad)

其中,good存储的是我们想要让程序跑到的地址,bad则是不需要的结果,例如:
一个re中,如果输入正确,输入win的地址,我们将这个地址保存为good,将输出error的地址保存为bad。
最后

print answer.found[0].posix.dumps(0)

来输出找到的输入。
不过感觉自己还是没怎么懂angr啊。。。太菜了。

你可能感兴趣的:(re)