1. 程式人生 > >joern程式碼屬性圖簡介

joern程式碼屬性圖簡介

抽象語法樹

抽象語法樹是程式編譯過程中形成的對於程式原始碼的中間表示,然而,直接從編譯器獲取抽象語法樹勢必要搭建程式的編譯環境。對於一些程式來說這將是一個複雜的過程,並且對於一些舊程式,很可能找不到它們需要的編譯工具和標頭檔案。因此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指向兩個或多個分支的語句結點。
- 函式遞迴:與普通函式的處理方式並沒有什麼區別。