angr初探
前言
在搞fuzz
的时候发现了一个比较难以解决的问题。例如if(*buf == "xdexadxbexef")
,我们如果想通过纯fuzz
去进入这个if
的分支,那么概率极其微小。这就使我不得不去尝试通过一些其他的方法去解决这个问题。于是我想到了一个比较出名符号执行的工具————angr
。这篇文章记录笔者入门angr
的过程。
环境安装
angr 的安装
angr
的安装非常简便,通过pip
即可,不过貌似angr
因为会依赖很多其他的库,所以它的创作者推荐把他装在虚拟环境当中,不过笔者就直接装在虚拟机里了。
pip3 install angr
学习环境安装
我这里用的是github
上的一个项目对angr
进行入门学习。
git clone https://github.com/jakespringer/angr_ctf.git
angr 基本使用方法
angr.Project
这是我们分析一个二进制文件的第一步,就是创建一个angr.Project
类,我们的后续操作都将基于这个类展开。并且我们可以通过所创建的project
获取二进制文件的一些基本信息。如:project.arch
可以获得这个二进制文件的架构,project.entry
可以获得这个二进制文件的起始地址,proj.filename
获得这个二进制文件的名字。
例如:
import sys
import angr
bin_path = "./00_angr_find"
project = angr.Project(bin_path)
print(project.arch)
print(hex(project.entry))
print(project.filename)
结果:
<Arch X86 (LE)>
0x80490b0
./00_angr_find
project.factory
project.factory
为我们提供了一些实用的类的构造器
project.factory.block(address)
angr
是以基本块为单位进行的分析,project.factory.block(address)
可以获得给定地址所在的基本块
。.pp()
可以获得该基本块的汇编代码。
例如:
block = project.factory.block(project.entry)
block.pp()
结果:
_start:
80490b0 endbr32
80490b4 xor ebp, ebp
80490b6 pop esi
80490b7 mov ecx, esp
80490b9 and esp, 0xfffffff0
80490bc push eax
80490bd push esp
80490be push edx
80490bf call 0x80490e7
project.factory.entry_state()
project.factory.entry_state()
用来获取一个程序的初始执行状态。
project.factory.blank_state(addr)
project.factory.blank_state(addr=...)
用来获取一个程序从指定地址开始执行的空白状态。
state - 模拟执行状态
无论是project.factory.entry_state()
,还是project.factory.blank_state(addr=...)
,都会返回一个模拟执行状态,我们可以把它存放到某个变量里,如存到state
里。
state.regs
state.regs
可以获取一些寄存器的值,如state.regs.esp
即可获得esp
的值。我们可以对其直接进行加减操作。
例如:
init_state = project.factory.entry_state()
print(init_state.regs.esp)
init_state.regs.esp-=12
print(init_state.regs.esp)
结果:
<BV32 0x7ffeffac>
<BV32 0x7ffeffa0>
state.memory
state.memory
是访问内存接口的一种形式。state.memory.load(addr, size_in_bytes)
:获取该地址上指定大小的位向量。state.memory.store(addr, bitvector)
:将一个位向量存储到指定地址、
state.posix
state.posix
是POSIX
相关的环境接口,例如state.posix.dumps(fileno)
获取对应文件描述符上的流。
simulation_manager - 模拟执行器
angr
将一个状态的执行方法独立成一个SimulationManager
类,有以下两种写法:
1、simgr = proj.factory.simgr(state)
2、simgr = proj.factory.simulation_manager(state)
simgr.step()
simgr.step()
:以基本块为单位的单步执行。
simgr.explore(find)
simgr.explore(find)
:路径探索,即执行到指定地址并进行约束求解,将执行完成的状态放在simgr.found
列表中,若无法求解则该列表为空。
相关文章
- Python中的函数与方法 以及Bound Method和Unbound Method
- 一文贯通python文件读取
- Python 中的异步编程:Asyncio
- 7个你现在就该学习Python的理由
- 提高Python运行效率的六个窍门
- Python数据科学:神经网络
- 一篇文章看懂大数据分析就业前景及职能定位
- R和Python中的文本挖掘:8个入门小贴士
- 告诉你为什么Python有点慢,但我却无所谓?
- 专注学习DevOps编程语言Top 5推荐
- Python发送邮件脚本
- Python多进程并行编程实践: mpi4py 的使用
- Python语言在未来的发展前景
- Python vs Ruby: 谁是最好的 web 开发语言?
- Python对Ruby:谁在Web开发领域更胜一筹?
- Python一行代码完成并行任务
- Python开发者2017应该关注的七个类库
- python爬虫入门基本知识
- 在终端中优雅地编写Python
- Python机器学习实战:信用卡欺诈检测