Simulation Managers
Last updated on May 26, 2023 am
Stepping Stash-Management Simple-Exploration Exploration-Techniques
The most important control interface in angr is the SimulationManager, which allows you to control symbolic execution over groups of states simultaneously, applying search strategies to explore a program’s state space. Here, you’ll learn how to use it.
概括:angr里面最重要的控制接口就是SimulationManager
,可以以此同时控制不同的states
符号执行,我们也可以以此来执行我们的搜索策略
Simulation managers let you wrangle multiple states in a slick way. States are organized into “stashes”, which you can step forward, filter, merge, and move around as you wish. This allows you to, for example, step two different stashes of states at different rates, then merge them together. The default stash for most operations is the
active
stash, which is where your states get put when you initialize a new simulation manager.
概括:我们可以用用Simulation Managers
来管理多个states
,States
又是由stashes
组成,这些stashes
我们可以步入、过滤、融合甚至移到另一个stashes
,对于绝大多数的stashes
都是active
note: 这里一直说的stashes
其实就是一种状态标志,意味这个block是否还能继续走下去,比如说一个block是active
的,那么它就还有后继而且还能继续往下执行。所以当我们初始丢给Simulation Manager
的state应该是active
的,这样它Simulation Manager
才会为我们模拟执行
Stepping
一个简单的demo
我们使用.step()
来让当前的state执行一步,去到下一个block。demo中给出了两个block的地址
1 |
|
你一定想问,那如果一个state的后继不止有一个呢?答案是.step()
都会执行
1 |
|
如果我们不关心中间过程,只希望它能一直跑下去,直到再也没有后继块可以执行,那么我们可以用.run()
现在我们使用了.run()
得到最终的state,它有三个stash
,并且都是deadended
状态,也就是跑不动了
Stash Management
我们可以用.move()
来转移状态,它有三个参数from_stash
,to_statsh
,以及一个可选参数filter_func
1 |
|
这个demo让我们把输出含有Welcome
的state转移到authenticated
,也就是说authenticated
里的state都含有Welcome
每一个stash
都是一个列表,我们可以用常规的去索引,也可以用其他方法。如果我们加一个前缀one_
那么我们就会访问这个stash
的第一个元素,如果用mp_
就可以同时访问全部,关于mp_
这有一个说明
1 |
|
Of course,
step
,run
, and any other method that operates on a single stash of paths can take astash
argument, specifying which stash to operate on.
也就是所有的step
,run
方法都可以接受一个stash
参数,来决定执行哪一个
Stash types
You can use stashes for whatever you like, but there are a few stashes that will be used to categorize some special kinds of states. These are:
Stash | Description |
---|---|
active | 可执行的 |
deadended | 再也无法执行的,可能是因为无法到达,没有后继等 |
pruned | (不太确定)当使用LAZY_SOLVES 时,states不会再检查可满足性,当一个state发现是unsat 时,这个states路径上的所有states都会变成pruned |
unconstrained | 如果 save_unconstrained 传递给SimelationManager constructor, 那些无约束的就时unconstrained |
unsat | 如果 save_unsat 传递给SimelationManager constructor, 那些无解的就时unsat ,比如要求输入同时满足即是’AAAA’又是’BBBB’ |
Simple Exploration
符号执行很普遍的用法是找到一个可以到达某个地址的states,而忽略其他所有的states,angr提供.explore()
来方便执行。
当我们使用.explore()
方法时,它可以接受两个参数find
以及avoid
。其中find
可以是一个地址,一个列表,一个以state
为参数返回某些值的函数,当任何一个active
符合find
的要求,那么它就会被放入found
stash里面,同时停止执行,avoid
一样,不过是放入avoided
stash里面,然后继续符号执行。num_find
可以决定找多少个found
,简单demo
1 |
|
Exploration Techniques
angr内置了很多种的搜索算法,但是我们也可以自己写一个搜索算法,并通过simgr.use_technique(tech)
调用,这里的tech
是ExplorationTechnique
子类。后面会再详谈,这里先列出angr内置的一些搜索算法
- DFS: 深度优先,只会让一个state为active,把其他的放进
deferred
stash - Explorer: 实现
.explore()
,可以使用find
,avoid
方法 - LengthLimiter:最长路径截断
- LoopSeer: 如果可能在一个循环里面,放入
spining
stash,直到其他可达路径都走完 - ManualMergepoint: 标记一个地址作为merge点,当一个stata到达此处时将其挂起,当其他state在某个时间内到达这个点时会被merge
- Memory:在
.step()
之间监视内存释放/使用情况,如果内存释放/使用得少的话,停止探索 - Oppologist: 当angr遇到一个不支持的指令的时候,会具体化所有的输入,并使用unicorn引擎来单独模拟这条指令,使得可以继续符号执行
- Spiller: 当有太多states处于active状态时,这可以把一些states放进磁盘中,使得内存开销比较小
- Threading: 使用多线程并行处理,但由于python全局变量线程锁的原因,这并不会有多大提升。但是如果在angr的native-code依赖(z3,unicorn,libvex)上花太多时间可以考虑这项技术
- Tracer:可以动态追踪资源
- Veritesting:自动识别有用的可合并点,使用
veritesting=True
来启用,这会提高搜索效率,但与其他算法配合得并不是很好
Look at the API documentation for the SimulationManager
and ExplorationTechnique
classes for more information.