angr初探 - 狒猩橙
source link: https://www.cnblogs.com/pwnfeifei/p/17135984.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在搞fuzz
的时候发现了一个比较难以解决的问题。例如if(*buf == "\xde\xad\xbe\xef")
,我们如果想通过纯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
列表中,若无法求解则该列表为空。
__EOF__
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK