【angr源码分析】3. Sim_State

Sim_State类

SimState代表了程序执行的状态,包括内存,寄存器等信息。

class SimState(PluginHub, ana.Storable):

Post not found: 8. Angr插件机制

所有的用于Sim_State的插件,都是SimStatePlugin Class的子类。(angr\state_plugins\plugin)

_init_()方法

设置了一些插件,包括memory,registers;以及其他属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def __init__(self, 
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,
plugin_preset='default'):
super(SimState, self).__init__() #先调用了PluginPreset的init方法
self.project = project
self.arch = arch if arch is not None else project.arch.copy() if project is not None else None

if type(self.arch) is str:
self.arch = arch_from_id(self.arch)

... ... 忽略了mode和Options

if plugin_preset is not None: #如果给出了默认preset,就使用该preset
self.use_plugin_preset(plugin_preset)
if plugins is not None: #如果给出了要注册的插件,就把他们注册进去
for n,p in plugins.iteritems():
self.register_plugin(n, p, inhibit_init=True)
for p in plugins.itervalues():
p.init_state()

if not set.has_plugin('memory'):
#注释原文是:我们没有设置内存的端序,因为和寄存器不同,很难判断用
#什么样的端序。如果不提供memory插件或者插件preset,我们别无选择,
#只能使用default preset。
if self.plugin_preset is None
#疑问:default插件是如何初始化的 ***
self.use_plugin_preset('default')

... ... options 中的 ABSTRACT_MEMORY,FAST_MEMROY选项
对应的插件名为:abs_memory, fast_memory
如果没有在options中设置,则会从preset中寻找插件名为:sym_memory
最后统一赋值给sim_memory

#注册内存插件
self.register_plugin('memory', sim_memory)

if not self.has_plugin('registers'):
... ... 从fast_memory或者sym_memory中获得registers插件

self.register_plugin('registers', sim_registers)

#疑问:为什么找不到.regs和.memory定义的位置?
#解决:register_plugin()使用了setattr方法,为类添加了这些属性

... ...

se()方法:

se实际上返回的是注册在Simstate里的一个插件——solver。

挖坑:solver.md**

1
2
3
4
@property
def se(self):
# TODO: Deprecate this
return self.get_plugin('solver')

add_constraints()方法:

为状态添加约束。您可以传入任意数量的符号布尔值作为可变参数。

挖坑**,这里必须了解claripy才能理解如何添加约束。claripy.md

同理,simplify方法也必须理解claripy。

step()方法:

进行符号执行,获得该状态执行之后的后继状态。

SimState中的step使用return self.project.factory.successors(self, **kwargs)

factory中使用return self.project.engines.successors(*args, **kwargs)

所以,最终使用的是engines中的successors。Post not found: 6. engines

1
2
def step(self, **kwargs):
return self.project.factory.successors(self, **kwargs)

block()方法:

获得当前IP指向的基本块。

SimState中的block使用return self.project.factory.block(*args, backup_state=self, **kwargs)

factory中获得block的方法:Post not found: 1. Factory

1
2
3
4
def block(self, *args, **kwargs):
if not args and 'addr' not in kwargs:
kwargs['addr'] = self.addr
return self.project.factory.block(*args, backup_state=self, **kwargs)


Sim_State类的插件介绍

挖坑待填:merge, stack_push, stack_pop, stack_read, memroy和regs插件的具体实现。

***history是什么插件

Unicorn插件

为一个state安装unicorn engine。这个插件负责管理SimState和Unicorn Engine的沟通。

angr\state_plugin\unicorn_engine.py文件中,有:

SimState.register_default('unicorn', Unicorn),即向’default’ preset中添加一个插件Unicorn。

class Unicorn(SimStatePlugin):

def setup():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def setup(self):
self._setup_unicorn()
self.set_regs()

#下面的暂时不管了
# tricky: using unicorn handle form unicorn.Uc object
self._uc_state = _UC_NATIVE.alloc(self.uc._uch, self.cache_key)
if UNICORN_HANDLE_TRANSMIT_SYSCALL in self.state.options and self.state.has_plugin('cgc'):
if self.transmit_addr is None:
l.error("You haven't set the address for concrete transmits!!!!!!!!!!!")
self.transmit_addr = 0
_UC_NATIVE.set_transmit_sysno(self._uc_state, 2, self.transmit_addr)

# just fyi there's a GDT in memory
_UC_NATIVE.activate(self._uc_state, 0x1000, 0x1000, None)

def _setup_unicorn():

似乎只是在检查架构问题。

1
2
3
def _setup_unicorn(self):
if self.state.arch.uc_mode is None:
raise SimUnicornUnsupport("unsupported architecture %r" % self.state.arch)

def set_regs():

设置unicorn registers。

1
2
3
4
5
6
7
8
9
def set_regs(self):
uc = self.uc

if self.state.arch.qemu_name == 'x86_64':
fs = self.state.se.eval(self.state.regs.fs)
gs = self.state.se.eval(self.state.regs.gs)
self.write_msr(fs, 0xC0000100)
self.write_msr(gs, 0xC0000101)
flags = self._process_value(self.state.regs.eflags, 'reg')