参考链接
https://xz.aliyun.com/t/7117
https://github.com/firmianay/CTF-All-In-One/blob/master/doc/5.3.1_angr.md
基础
#coding=utf-8
import angr
import networkx as nx
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
proj = angr.Project('/bin/true')
print proj.filename # 文件名
print proj.arch # 一个 archinfo.Arch 对象
print hex(proj.entry) # 入口点
loader = proj.loader
for obj in loader.all_objects: # 程序加载时会将二进制文件和共享库映射到虚拟地址中,所有对象文件
print obj
# 二进制文件本身是main_object
print loader.main_object
print hex(loader.main_object.min_addr)
print hex(loader.main_object.max_addr)
## 但是通常会选择关闭auto_load_libs,避免angr加载共享库
proj = angr.Project('/bin/true', auto_load_libs=False)
print proj.loader.all_objects
# project.factory 提供了很多类对二进制文件进行分析
# project.factory.block() 用于从给定地址解析一个 basic block,对象类型为 Block
block = proj.factory.block(proj.entry)
print block.pp() # 打印
print block.instructions # 指令数量
print block.instruction_addrs # 指令地址
# 将block类型转换为其他形式
print block.capstone.pp()
print block.vex.pp()
# 程序的执行需要初始化一个模拟程序状态的 SimState 对象
state = proj.factory.entry_state()
# 该对象包含了程序的内存、寄存器、文件系统数据等等模拟运行时动态变化的数据
print state.regs # 寄存器
print state.regs.rip # BV64对象
print state.regs.rsp
print state.regs.rsp.length
print state.mem[proj.entry].int.resolved # 将入口点的内存解释为c语言的int类型
# 这里的 BV,即 bitvectors,可以理解为一个比特串,用于在 angr 里表示 CPU 数据。看到在这里 rdi 有点特殊,它没有具体的数值,而是在符号执行中所使用的符号变量
# python int与bitvector之间的转换
bv = state.solver.BVV(0x1234, 32) # 创建一个32位的bitvector对象,值为0x1234
print hex(state.solver.eval(bv))
bv = state.solver.BVV(0x1234, 64) # 64位
# bitvector之间的数学运算
one = state.solver.BVV(1, 64)
one_hundred = state.solver.BVV(2, 64)
print one + one_hundred # 位数相同时可以直接运算
five = state.solver.BVV(5, 27)
print one + five.zero_extend(64 - 27) # 位数不同时需要进行扩展
print one + five.sign_extend(64 - 27) # 有符号扩展
# 使用 bitvectors 可以直接来设置寄存器和内存的值,当传入的是 Python int 时,angr 会自动将其转换成 bitvectors
# >>> state.regs.rsi = state.solver.BVV(3, 64)
# >>> state.regs.rsi
# <BV64 0x3>
# >>> state.mem[0x1000].long = 4 # 在地址 0x1000 存放一个 long 类型的值 4
# >>> state.mem[0x1000].long.resolved # .resolved 获取 bitvectors
# <BV64 0x4>
# >>> state.mem[0x1000].long.concrete # .concrete 获得 Python int
# 4L
# 初始化的 state 可以经过模拟执行得到一系列的 states,模拟管理器(Simulation Managers)的作用就是对这些 states 进行管理
simgr = proj.factory.simulation_manager(state)
print simgr.active # 当前状态
simgr.step() # 模拟执行一个basic block
print simgr.active # 当前状态被更新
print simgr.active[0].regs.rip # active[0] 是当前 state
# attention: 被改变的仅仅是simgr的状态,原始状态并不会被改变
print state.regs.rip
# angr 提供了大量函数用于程序分析,在这些函数在 Project.analyses.
p = angr.Project('/bin/true', load_options={'auto_load_libs': False})
cfg = p.analyses.CFGFast()
nx.draw(cfg.graph) # 画图
plt.savefig('temp.png')
网友评论