angr的控制流图恢复可以分为两种,一种是CFGAccurate,一种是CFGFast。关于它们的介绍,在我以前的一篇《自动化二进制分析技术》中有所提及,为了方便代码的理解,我把这部分内容再次放在本文的后面了。所以,如果你对控制流恢复一窍不通的话,可以跳到最后 控制流图恢复 部分先了解理论。
angr通过执行每一个基本块并观察基本块的执行流向来构造CFG。然而,在不同的上下文中基本块的流向将不同。如果一个块以函数返回作为结束,那么不同的调用者对应的函数返回也将不一样。
首先看一个angr中cfg使用的例子:
import angr
from angrutils import *
proj=angr.Project('mybinary')
start_addr=0x1F003BD9
start_state= proj.factory.blank_state(addr=start_addr)
cfg = proj.analyses.CFGAccurate(keep_state=True,starts=[start_state.addr], initial_state=start_state)
plot_cfg(cfg, "mycfg",asminst=True, remove_imports=True, remove_path_terminator=True) #convert the cfg to a png
这段代码首先加载了一个二进制文件,创建了一个空状态 start_state作为控制流恢复的起始状态。
最后一条语句是调用了angrutils模块,将恢复的控制流图打印为png,真的超好用的哎!不过似乎只支持打印CFGAccurate算法恢复出的控制流图,CFGFast不能,因为阅读后面文献可知它是没有控制关系的。当然它还可以画控制依赖图和数据流图,等一切NetworkX DiGraph的实例。
CFGAccurate算法比较常用,所以先介绍一下它的API。
classangr.analyses.cfg.cfg_accurate.
CFGAccurate
(context_sensitivity_level=1, start=None, avoid_runs=None, enable_function_hints=False, call_depth=None, call_tracing_filter=None, initial_state=None, starts=None