日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

静态程序分析chapter2 - IR(Jimple) 和 CFG

發布時間:2025/6/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 静态程序分析chapter2 - IR(Jimple) 和 CFG 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、
  • IR(Intermediate Representation)
    • 編譯器(Compiler)
    • 3AC(3-Address Code)
    • Soot和它的IR:Jimple
    • JVM中的方法調用與方法簽名簡介
      • invokespecial
      • invokevirtual
      • invokeinterface
      • invokestatic
      • invokedynamic
      • method signature
  • CFG(Control Flow Graph)的建立
      • 建立節點Node
      • 建立邊Edge
  • 總結


一、

IR(Intermediate Representation)

編譯器(Compiler)

??????編譯器編譯一般要經過5個階段:詞法分析;語法分析;語義分析;優化;目標代碼生成。下面通過自然語言處理來說明這些步驟(處理代碼也是類似的)。

??????詞法分析(Lexical Analysis)通過正則表達式來判斷每一個單詞本身是否存在錯誤。如果每一個單詞都是正確的,就會給它們做上標記(Token),交給下一個步驟。

??????語法分析(Syntax Analysis)通過上下文無關語法來判斷每一個語句是否符合英文語法(主謂賓…)。如果語句的語法沒有問題,就會將其轉化為抽象語法樹(AST)。

??????語義分析(Semantic Analysis)通過屬性語法來判斷每一個語句的語義上是否存在問題,比如語句 Apples eat you 從語義上來說是行不通的。當然編譯器在這個步驟的工作是比較簡單的,它只對語句做類型檢查,比如不能將一個 float 類型變量賦值給 char 類型變量。如果語句的語義沒有問題,就會生成修飾過后的抽象語法樹。

??????優化(optimization)步驟是通過轉換器轉換為一種中間表示形式(IR),優化的結果就是生成了IR。通常所說的IR就是三地址碼(3AC)。

??????最終的目標代碼(.obj)通過IR來生成。

??????而靜態分析通常是在IR上進行的,雖然最早也可以在AST上進行,但是現在已經被淘汰了。IR的優點在于:它是語言無關的并且包含有控制流信息,通常認為IR是靜態分析的基石。見下面圖示:


3AC(3-Address Code)

??????三地址碼的格式:在一個語句的右側只有一個操作符。比如語句 a = b + c + 2;它轉換為三地址碼的格式;t1 = b + c;a = t1 + 2;其中的 t1 是臨時變量。

??????其實三地址碼就是包含有三個地址的語句。這里的地址指的是:常量(2)、變量名(b or c)以及臨時變量(t1)。

??????常見的三地址碼格式:(x,y 和 z 都是地址)

????????????x = y bop z
????????????x = uop z
????????????x=y
????????????goto L
????????????if x goto L
????????????if x rop y goto L

??????bop 指的是二元算術運算符(+ , - , * , / , …);uop 指的是一元算術運算符(- ,casting …);rop指的是二元關系判斷運算符(> , < , == …)。

Soot和它的IR:Jimple

??????Jimple是一種典型的三地址碼。下面給出一些簡單的Java代碼和對應的Jimple代碼作為示例:(關于Soot,后面會專門講解)

一、
??????Java Src(do-while 循環):

public class DoWhileLoop3AC{public static void main(String[] args){int[] arr = new int[10];int i = 0;do {i = i + 1;}while(arr[i] < 10)} }

??????其中main函數所對應的Jimple代碼為:

public static void main(java.lang.String[]) {java.lang.String[] r0;int[] r1;int $i0,i1;r0 := @parameter0: java.lang.String[];r1 = newarray (int)[10];i1 = 0;label1:i1 = i1 + 1;$i0 = r1[i1];if $i0 < 10 goto label1;return; }

二、
??????Java Src(方法調用):

public class MethodCall3AC{String foo(String para1,String para2){return para1 + " " + para2;}public static void main(String[] args){MehtodCall3AC mc = new MehtodCall3AC();String result = mc.foo("hello","world"); }}

??????其中 foo 函數和 main 函數對應的Jimple代碼為:

java.lang.String foo(java.lang.String,java.lang.String) {MethodCall3AC r0;java.lang.String r1, r2, $r7;java.lang.StringBuilder $r3,$r4,$r5,$r6;r0 := @this: MethodCall3AC;r1 := @parameterr0: java.lang.String;r2 := @parameterr1: java.lang.String;$r3 = new java.lang.StringBulider;specialinvoke $r3.<java.lang.StringBulider: void<init>()>();$r4 = virtualinvoke $r3.<java.lang.StringBulider: java.lang.StringBulider append(java.lang.String)>(r1);$r5 = virtualinvoke $r4.<java.lang.StringBulider: java.lang.StringBulider append(java.lang.String)>(" ");$r6 = virtualinvoke $r5.<java.lang.StringBulider: java.lang.StringBulider append(java.lang.String)>(r2);$r7 = virtualinvoke $r6.<java.lang.StringBulider: java.lang.String toString()>();return $r7; }public static void main(java.lang.String[]) {java.lang.String[] r0;MethodCall3AC $r1;r0:= @parameter0: java.lang.String[];$r1= new MethodCall3AC;specialinvoke $r1.<MethodCall3AC: void<init>()>();virtualinvoke $r1.<MethodCall3AC: java.lang.String foo(java.lang.Stirng,java.lang.String)>("hello","world");return; }

三、
??????Java Src(類):

package a.b.c; public class Class3AC{public static final double pi = 3.14;public static void main(String[] args){}}

??????這個類對應的Jimple代碼為:

public class a.b.c.Class3AC extends java.lang.Object {public static final double pi;public void <init>(){a.b.c.Class3AC r0;r0 := @this: a.b.c.Class3AC;specialinvoke r0.<java.lang.Object: void <init>()>();return;}public static void main(java.lang.String[]){java.lang.String[] r0;r0:= @parameter0: java.lang.String[];return;}public static void <clinit>(){<a.b.c.Class3AC: double pi> = 3.14;return;} }

JVM中的方法調用與方法簽名簡介

invokespecial

??????用來調用構造函數,父類方法和私有方法(constructor、superclass method、private method),構造函數的的方法名是 。

invokevirtual

??????用來調用實例方法、基于類進行分派(instance method、virtual dispatch)

invokeinterface

??????用來調用接口中的方法

invokestatic

??????用來調用靜態方法

invokedynamic

??????Java7 添加,調用方法讓其動態執行

method signature

??????方法簽名的格式為:<類名: 返回值 方法名(參數1的類型,參數2的類型…)>(傳入的實參1,傳入的實參2…)

CFG(Control Flow Graph)的建立

??????下面講述采用3AC-IR建立控制流程圖的過程。控制流程圖是靜態分析的最基本的結構,控制流程圖是由節點和邊組成的,節點通常是一個獨立的3AC語句,或者是一個基本塊BB(Basic Block);邊用來表示控制流的方向。

建立節點Node

??????BB是滿足下面特點的最大的連續語句系列。第一,BB只能擁有一個入口。第二,BB只能擁有一個出口。根據這兩個特點,對于連續的3AC語句,將它們轉換為一系列BB的方法為:

??????每一個入口語句只能為:在所有語句中的第一條語句;任何跳轉語句的目的地址所在語句;任何跳轉語句的下一條語句。

??????當我們找到所有入口語句之后,就可以輕易地構建BB了。

??????下圖中左側為輸入語句,右側是根據上面方法構建的BB:

??????每一個BB中的第一條語句稱為 leaders,先找到所有的 leaders:(1)是第一條語句;(3)(7)(12)是跳轉語句的目標語句;(5)(11)(12)是跳轉語句的下一條語句。

??????最后,得到的BB如下圖所示:

建立邊Edge

??????1,如果一個基本塊 A 的最后一條語句為跳轉語句,并且該跳轉語句指向另一個基本塊 B 的第一條語句,那么,存在一條邊從基本塊 A 指向基本塊 B 。

??????2,如果一個基本塊 A 的最后一條語句不是無條件跳轉語句,而 B 是緊接著 A 的下一個基本塊,那么,存在一條邊從基本塊 A 指向基本塊 B 。

??????稱 A 為 B 的前驅,B 為 A 的后繼。

??????通常,我們需要再添加兩個節點,入口節點和出口節點。類似于數據結構鏈表的鏈表頭,它們并不包含任何語句,僅用來標記CFG的入口和出口。入口節點指向的BB中包含有整個代碼執行中的第一條IR語句;指向出口節點的BB中包含可能是整個代碼執行的最后一條IR語句。

??????在上面的BB中按照既有規則加上邊之后,得到的 CFG 如下圖:

總結

??????靜態分析的原材料是 3AC-IR ,文中列出了常用的六種 3AC-IR 的格式,為了更好的理解,我們介紹了 Soot 是如何將 Java 源代碼轉換為 IR Jimple 的,并且補充了JVM中的方法調用。最后一部分介紹了在 IR 的基礎上建立 CFG ,包括邊和節點的建造,后面會繼續介紹如何在 CFG 上進行數據流分析和三個典型案例講解。未完待續~

總結

以上是生活随笔為你收集整理的静态程序分析chapter2 - IR(Jimple) 和 CFG的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。