在最初分析angr的符号执行流程时,我们首先介绍了angr中claripy的应用代码,如下:
import angr, claripy
b = angr.Project('/bin/true')
path = b.factory.path()
rax_start = claripy.BVS('rax_start', 64)
path.state.regs.rax = rax_start
path_new = path.step()[0] //step()返回的是SimSuccessors对象
rax_new = path_new.state.regs.rax
path_new.state.se.add(rax_new == 1337)
print path_new.state.se.eval(rax_start, 1)[0]
通过分析claripy.ast.bv.py文件,我们知道了如何创建一个符号变量,BVS或BVV。然后我们知道在执行符号执行前,需要提供程序分析的初始状态,与获取程序状态有关的类是factory,并且对factory里面包含的函数进行了介绍。结果我们发现factory类中函数返回值总是涉及到SimState和SimulationManager这两个类。(希望以后能画个图,把这一段话说明白。。。)所以今天我们首先对SimState进行介绍。
classangr.sim_state.
SimState
(project=None, arch=None, plugins=None, memory_backer=None, permissions_backer=None, mode=None, options=None, add_options=None, remove_options=None, special_memory_filler=None, os_name=None)
SimState表示一个程序的状态,包括内存和寄存器等。
1. 变量解释:
:ivar regs: 状态的寄存器的方便表示, 其中每一个寄存器都是一个property(属性)
:ivar mem: 状态的内存的方便表示, 一个类:`angr.state_plugins.view.SimMemView`
:ivar registers: 状态的寄存器文件作为平坦的存储区域。
:ivar memory: 状态的内存,一个平坦的存储区域。
:ivar solver: 该状态的符号求解器和变量管理器
:ivar inspect: 断点管理器, 一个类:`angr.state_plugins.inspect.SimInspector`
:ivar log: 关于该状态的历史信息
:ivar scratch: 关于当前执行步骤的信息
:ivar posix: MISNOMER: 关于操作系统或环境模型的信息
:ivar libc: 关于我们正在模拟的标准库的信息
:ivar cgc: 关于cgc环境的信息
:ivar uc_manager: 控制无约束的符号执行
:ivar unicorn: 控制Unicorn Engine(参考链接:https://skymz.cc/?post=466)
使用SimState时,其实我们更关心它的属性以及方法。
2. 属性:
部分简单属性:
ip
(self.regs.ip)
指令指针表达式,触发SimInspect断点,并生成SimAction
_ip
(self.regs._ip)
指令指针表达式,不触发SimInspect断点。
addr
(self.se.eval_one(self.regs._ip))
指令指针的具体地址,而不触发SimInspect断点或生成SimActions。一个整数,如果指令指针是符号,则会抛出异常。
通过插件访问的属性:
@property
def memory(self):
return self.get_plugin('memory')
@property
def registers(self):
return self.get_plugin('registers')
@property
def se(self):
return self.get_plugin('solver_engine')
@property
def solver(self):
return self.get_plugin('solver_engine')
@property
def inspect(self):
return self.get_plugin('inspector')
@property
def log(self):
return self.get_plugin('log')
@property
def scratch(self):
return self.get_plugin('scratch')
@property
def history(self):
return self.get_plugin('history')
@property
def posix(self):
return self.get_plugin('posix')
@property
def libc(self):
return self.get_plugin('libc')
@property
def cgc(self):
return self.get_plugin('cgc')
@property
def regs(self):
return self.get_plugin('regs')
@property
def mem(self):
return self.get_plugin('mem')
@property
def gdb(self):
return self.get_plugin('gdb')
@property
def globals(self):
return self.get_plugin('globals')
@property
def uc_manager(self):
return self.get_plugin('uc_manager')
@property
def unicorn(self):
return self.get_plugin('unicorn')
@property
def preconstrainer(self):
return self.get_plugin('preconstrainer')
@property
def callstack(self):
return self.get_plugin('callstack')
这时候,我们可能会对plugin是什么感兴趣。plugin的基类是class angr.state_plugins.plugin.SimStatePlugin。当状态发生分支时,SimState插件将于状态一起复制。它们旨在用于诸如跟踪打开文件,跟踪heap详细信息,并为SimProcedures提供存储和持久性功能。这样说起来非常笼统,等到后面遇到关于plugin使用时,再进行详细描述。
了解了SimState的属性后,我们也要关心状态的方法,也就是状态能做些什么,或对状态能做什么。
3. 方法:
simplify
(*args)
简化这个状态的约束条件。