ubuntu16
首先是需要python3.6以上的版本 用以下方法更新 (摘抄于https://zhuanlan.zhihu.com/p/51340766)
1.安装编译环境
1 | sudo apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev tk-dev libgdbm-dev libdb-dev libpcap-dev xz-utils libexpat1-dev liblzma-dev libffi-dev libc6-dev |
2.下载Python-3.6.3.tar.xz 国内镜像
3.解压
1 | tar xvJf Python-3.7.1.tar.xz |
4.配置安装位置
1 | ./configure --prefix=/usr/bin/python3.7 |
5.编译及安装
1 | sudo make && sudo make install |
弄完之后直接
1 | pip3 install angr |
今天打比赛 空余时间捣鼓 弄了一整天都有成功把去平坦化弄好呜呜呜 再见angr
windows10
直接使用python2.7即可
依次执行以下命令(首先需要安装pip
1 | pip install --upgrade pip |
import angr之后会有warning 说明安装成功
学习
这里使用了Null战队编写的《从0到1》内容
自己总结到一般来说angr跑题到步骤
1.创建一个project对象
1 | p = Project('r100',auto_load_libs = False) |
这里后面追加的 auto_load_libs 是否自动载入依赖库 一般设置为False 以减少angr的工作量
2.设置一个启动状态state
1 | p.factory.blank_state(addr=xxx) |
3.创建虚拟执行
1 | sm = p.factory.simulation_manager(state) |
4.执行! 去往想去的地方 规避不想去的地方
1 | sm.explore(find = 0x400844,avoid = 0x400855) |
5.输出结果
1 | if sm.found[0]: |
这是最简单的一个操作 接下来补充一些花里胡哨的操作
- 一些函数对结果没有影响,比如printf 我们可以直接让它返回,代码如下
1 | p.hook_symbol('printf',SIM_PROCEDURES['stubs']['ReturnUnconstrained'](),replace = True) |
- 既然可以hook我们认为对结果无影响对函数,那么也可以自己写一个函数去hook原本对函数,从而达到给angr减少工作量对目的
1 | class my_fgets(SimProcedure): # 固有格式 |
如果是写scanf的%d如下
1 | class my_sacnf(SimProcedure): # 固有格式 |
- 一个优化开关,无法避免无解的情况产生,但是能大大提高脚本的运行效率
1 | sm.one_active.options.add(options.LAZY_SOLVES) |
- 自己构造输入
因为使用标准输入经常无法推测输入字符串的长度,会浪费大量时间去尝试不同长度,所以我们可以自定义输入 然后作为参数传入一个函数,这个时候state要设置为call的地址
1 | flag_chars = [BVS('flag_%d'%i,32) for i in range(13)] |
因为是手动设置的输入,不能通过dump(0) dump标准输入来得到输入,这里使用angr求解器提供的eval函数
1 | flag = ''.join(chr(sm.one_found.solver.eval(c)) for c in flag_chars) |
- 对于开启了PIE的可执行文件,angr会默认其基地址为0x400000,此时所有操作只需要在原本地址上加上offset即可
- 对内存对储存鱼读取
1 | state.memory.store(addr,data) |