joern代码属性图简介

来源:互联网 发布:花生壳的域名ping不通 编辑:程序博客网 时间:2024/06/06 00:13

抽象语法树

抽象语法树是程序编译过程中形成的对于程序源码的中间表示,然而,直接从编译器获取抽象语法树势必要搭建程序的编译环境。对于一些程序来说这将是一个复杂的过程,并且对于一些旧程序,很可能找不到它们需要的编译工具和头文件。因此joern没有采取从编译器获取AST的方法,而是利用了一个基于island grammar的,直接从源码抽取AST的分析器。joern的分析器基于分析器生成工具ANTLR,对于图1所示的源码,它抽取出的AST如图2所示,将其表示为树形结构后如图3所示。相对于直接从编译器获取AST,joern不确保其生成的AST具有有效性,而只是希望从源码中抽取处尽可能多的语法信息。

代码属性图结点概述

对于装入的所有代码中的每一个函数,数据库中存储了一个代码属性图,包含一系列结点和代表结点间关系的边,结点有以下主要属性:
- type:结点类型
- code:此结点的代码
- location:结点所在位置,部分语句结点有次属性,不同结点可能由相同属性值

  • functionId:结点所属的函数编号
  • isCFGNode:属性值为True或False
  • name:函数结点的专有属性,属性值为函数名

代码属性图的结点主要分为以下几大类:
- 函数结点:type值为“Function”。
- 抽象语法树结点:joern抽象语法树结点种类由工具开发者Yamaguchi等人定义,表示代码的语法结构。
- 语句结点:语句结点也是由Yamaguchi等人定义,是抽象语法树结点的一个子集,语句结点由属性isCFGNode来标记,属性值为True,语句结点之间用边FLOWS_TO和REACHES连接。
- 符号结点:type值为“Symbol”,符号结点用于数据流分析,它与所有使用此符号的语句结点用边USE相连,与所有定义此符号的语句结点用边DEF相连。
- 文件和目录结点:type值为“File”或“Directory”,文件和目录结点之间以边IS_FILE_OF或IS_PARENT_DIR_OF相连。
- 结构体/类声明结点:type值为“Class”,结构体或类声明结点与所在文件以边IS_FILE_OF相连,与成员的声明以边IS_CLASS_OF相连。
- 变量声明结点:type值为“DeclStmt”,其中全局变量的声明在声明变量结点中,并且与所在文件以边IS_FILE_OF相连。


一些比较特殊结点的解释
1. CFGEntryNode:控制流图入口
- CFGExitNode:控制流图出口
- CompoundStatement:表示多个语句,无实际意义,从FunctionDef由边IS_AST_PARENT指向此结点,再从此结点由IS_AST_PARENT指向函数中的每个语句
- AssignmentExpr:赋值表达式,即“=”,由边IS_AST_PARENT指向等号的左右两边
- PrimaryExpression:多指常数
- Condition:条件语句的条件,从条件语句由边IS_AST_PARENT指向此结点
- ReturnStatement:返回语句
- ArrayIndexing:相当于数组标识符


代码属性图中的边

代码属性图的边有多种类别,枚举如下:
- IS_FILE_OF
- IS_PARENT_DIR_OF
- IS_FUNCTION_OF_AST
- IS_AST_PARENT
- CONTROLS
- FLOWS_TO
- REACHES
- POST_DOM
- USE
- DEF

除以下两种边外,其他类型的边没有属性:
- FLOWS_TO:有属性flowLabel,在相连结点为if语句(IfStatement)时,值为True或False或为空;在相连结点为switch语句(SwitchStatement)时,值为case值。
- REACHES:有属性var,值为它所连接结点中的变量名。

几种特殊边的解释:
- CONTROLS:由CFGEntryNode指向函数中所有语句,或由Condition结点流向条件分支语句的分支
- FLOWS_TO:从CFGEntryNode开始,沿着程序执行顺序,一直指向CFGExitNode
- REACHES:数据依赖边,一般由赋值语句指向需要计算的语句
- POST_DOM:


joern对于几种特殊情况的处理方法
- 条件分支:从语句结点由边IS_AST_PARENT指向Condition结点,再从Condition结点由边FLOWS_TO指向两个或多个分支的语句结点。
- 函数递归:与普通函数的处理方式并没有什么区别。

原创粉丝点击