【angr源码分析】1. Factory

AngrObjectFactory类

使用angr,首先是 proj = angr.Project('./binary')。Project类实例化对象时,会调用 self.factory = AngrObjectFactory(self)。即:project中的factory对象,是AngrObjectFactory类的一个实例。

描述如下:

1
2
3
4
5
class AngrObjectFactory(object):
"""
This factory provides access to important analysis elements.
factory提供一些重要分析工具的访问方式
"""

Factory中比较重要的部分包括:SimState,Block,Simulation_Manager,然而Factory并没有实际提供这些部分的定义,只是把它们的接口集合在Factory中。

获得Block

两个方法:block(), fresh_block()

def block():

参数的含义并未给出注释,很烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def block(self, addr, size=None, max_size=None, byte_string=None, vex=None, thumb=False, backup_state=None,
opt_level=None, num_inst=None, traceflags=0,
insn_bytes=None, insn_text=None, # backward compatibility
strict_block_end=None,
):

... ...

if insn_bytes is not None:
byte_string = insn_bytes
if insn_text is not None:
byte_string = self.project.arch.asm(insn_text, addr=addr, as_bytes=True, thumb=thumb)
#这里对insn_text进行编译,作为参数byte_string传入Block的生成器
... ...

return Block(addr, project=self.project, size=size, byte_string=byte_string, vex=vex, thumb=thumb,
backup_state=backup_state, opt_level=opt_level, num_inst=num_inst, traceflags=traceflags,
strict_block_end=strict_block_end
)

传送门 Post not found: 2. Block

获得SimState

包括以下4个状态。

1
2
def blank_state(self, **kwargs):
return self.project.simos.state_blank(**kwargs)
1
2
def entry_state(self, **kwargs):
return self.project.simos.state_entry(**kwargs)
1
2
def full_init_state(self, **kwargs):
return self.project.simos.state_full_init(**kwargs)
1
2
def call_state(self, addr, *args, **kwargs):
return self.project.simos.state_call(addr, *args, **kwargs)

都是调用了simos中的方法,本质上是实例化了一个SimState对象 state = SimState(self.project, **kwargs)

传送门:Post not found: 3. Sim_State Post not found: 4. SimOS

获得Simulation_Manager

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
def simulation_manager(self, thing=None, **kwargs):
"""
Constructs a new simulation manager.

:param thing: Optional - What to put in the new SimulationManager's active stash (either a SimState or a list of SimStates).
:param kwargs: Any additional keyword arguments will be passed to the SimulationManager constructor
:returns: The new SimulationManager
:rtype: angr.sim_manager.SimulationManager

Many different types can be passed to this method:

* If nothing is passed in, the SimulationManager is seeded with a state initialized for the program
entry point, i.e. :meth:`entry_state()`.
* If a :class:`SimState` is passed in, the SimulationManager is seeded with that state.
* If a list is passed in, the list must contain only SimStates and the whole list will be used to seed the SimulationManager.#***?什么意思
"""
if thing is None:
thing = [ self.entry_state() ]
elif isinstance(thing, (list, tuple)):
if any(not isinstance(val, SimState) for val in thing):
raise AngrError("Bad type to initialize SimulationManager")
elif isinstance(thing, SimState):
thing = [ thing ]
else:
raise AngrError("BadType to initialze SimulationManager: %s" % repr(thing))

return SimulationManager(self.project, active_states=thing, **kwargs)

最后,传入的state或者state列表,被作为active_states,生成了SimulationManager对象。

传送门:Post not found: 5. SimulationManager



其他信息

这里包含factory提供的其他功能。

Successors

def successors():

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def successors(self, *args, **kwargs):
"""
Perform execution using any applicable engine. Enumerate the current engines and use the
first one that works. Return a SimSuccessors object classifying the results of the run.

:param state: The state to analyze
:param addr: optional, an address to execute at instead of the state's ip
:param jumpkind: optional, the jumpkind of the previous exit
:param inline: This is an inline execution. Do not bother copying the state.

Additional keyword arguments will be passed directly into each engine's process method.
"""

return self.project.engines.successors(*args, **kwargs)

所以,factory里的successors只是调用了Project.engines里的方法。engines实际上是EnginHub类的对象,继承自PluginHub。传送门:Post not found: 6. engines