angr里提供两种CFG的生成,一种是CFGFast,一种是CFGEmulated。这两种究竟有什么不同呢?
本文主要是用图来说明下这个问题。可能回答的不是很完整。
CFGFast这种CFG生成的比较快,但是没有考虑上下文关系。比如函数A调用了printf函数,函数B也调用了printf函数。就会变成下图的形式。
而CFGEmulated这种CFG则是考虑了上下文关系,上面的例子在CFGEmulated里就会变成下图的样子。
现在来实际看看angr生成的控制流图是什么样子的。针对以下C程序,我们来画CFGEmulated和CFGFast。
#include<stdio.h>
int A(){
printf("hello world\n");
}
int B(){
printf("hello");
}
int C(){
printf("world");
}
int main()
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if (a == 1)
{
A();
}
else if (b == 1)
{
B();
}else
{
C();
}
return 0;
}
angr生成CFG以及可视化CFG的代码如下:
import angr
from angrutils import *
project = angr.Project("example/cfg",load_options={'auto_load_libs': False})
cfg_emulated = project.analyses.CFGEmulated()
plot_cfg(cfg_emulated, "cfg_emulated", asminst=True, remove_imports=True, remove_path_terminator=True)
cfg_fast = project.analyses.CFGFast()
plot_cfg(cfg_fast, "cfg_fast", asminst=True, remove_imports=True, remove_path_terminator=True)
CFGEmulated如下图所示:
CFGFast如下图所示:
可以看到CFGEmulated的三个分支的printf都单独提出来了。
而CFGFast中,可以看到printf节点的前继节点是B,C两个函数。