基本块和流图
基本块
概念
从第一条指令开始,直到出现跳转
后续使用信息
知道一个变量的值接下来在什么时候使用对于生成良好的代码非常重要,
比如一个寄存器中值一直未被使用,这个寄存器就可以被分配给其他值
使用的定义:语句j使用了语句i中x的值,则称x在语句i是活跃的。
对一个基本块中的语句求得活跃性和后续使用信息
从基本块B的最后一条指令开始,反向扫描到B的开始;对于每一条指令
i:x=y+z
- 设置x为不活跃
- 设置y,z为活跃,设置他们的下一次使用设置语句为i
流图
基本块B和基本块C之间存在一条边当且仅当基本块C的第一条指令紧跟
B的最后一条指令执行
流图的表示
用两个指针,一个指向基本块的头部,一个指向尾部。当我们需要更改
指令条数时,最好创建指令链表。
循环
循环是满足下面条件的基本块集合L
- L有一个循环入口
- L每个节点都有到达入口的非空路径,而且这条路径在L中:q
使用工具绘制流图
使用angr, angrutils绘制可执行程序控制流图
待分析程序
#include <stdlib.h>
#include <stdio.h>
int main( int argc,char** argv )
{
int account=0x4000;
int key=0;
if(argc<2){
fprintf(stderr,"need two args\n");
return -1;
}
scanf("%d",&key);
if(key+account==0x80){
printf("success\n");
return 0;
}
else{
printf("error, go away\n");
return 0;
}
}
python代码参考
import angr
from angrutils import *
def main():
p=angr.Project("./myapp",load_options={'auto_load_libs':False})
main_obj=p.loader.main_object.get_symbol("main")
start_state=p.factory.blank_state(addr=main_obj.addr)
cfg=p.analyses.CFGAccurate(fail_fast=True,starts=[main_obj.addr],initial_state=start_state)
plot_cfg(cfg,"myapp",asminst=True,remove_imports=True,remove_path_terminator=True)
if __name__=="__main__":
main()
myapp.png
网友评论