• 沒有找到結果。

第五章 網路通訊協定堆疊剖析暨除錯工具之實作

5.2 選擇性指令嵌入技術之實作

本節將介紹我們根據第 4.3.3 節的選擇性指令嵌入技術之架構,實作本技術 內部的 Polymorphism Module、Direct use function Module 與 Indirect use function Module,並且運行於 Linux 核心系統。由於該系統主要是利用 C 語言實作,然 而 C 的語法規則非常複雜,無法利用簡單的字串比對程式,達成本技術尋找以 及嵌入指令於函式的目的,因此我們選擇利用兩套工具:Lex & Yacc[61]來實作 本技術。

因為 Lex & Yacc 主要用於實作編譯器(Compilers)及直譯器(Interpreters),而 且美國國家標準協會(ANSI)利用 Lex & Yacc 訂定 C 的語法規則標準[62][63],所 以 Lex & Yacc 非常適合於實作 C 的語法分析程式(Parser),因此可以輕易達成本 技術的目的。以下分別介紹 Polymorphism Module、Direct use function Module 與 Indirect use function Module 的實作方法。

5.2.1 Polymorphism Module 之實作

由於 Polymorphism 的三種變形,其語法規則皆不相同,因此將分別介紹:

 Alias

因為 Alias 是由 C Preprocessor 處理,因此 ANSI 並未利用 Lex & Yacc

訂定 Alias 的標準語法規則。然而我們從 C Preprocessor 的文件[64],得知 Alias 的語法規則為#define 接著一個 identifier 與 token list 直到換行,由於此 語法規則較為單純,因此我們只需利用 Lex 即可實作,如 Figure 5-1。當 Lex 取得#define 時,即進入 Alias 的狀態,接著取得一個 identifier,並且執行 define 函式讀取 token list,最後判斷 struct sk_buff 是否存在於此 token list。

1 ^[ \t]*"#"[ \t]*"define" { BEGIN DEFMODE; } 2 <DEFMODE>{L}({L}|{D})* { define(); BEGIN INITIAL;}

3 <DEFMODE>\n { BEGIN INITIAL; } 4 define()

5  read token list

6  check if struct sk_buff exits in token list

Figure 5-1 Alias 的語法規則

 Customized Data Types 與 Nested Structure

因為此兩種屬於 C 語言的語法,所以 ANSI 已經訂定此兩種語法規則的 標準,其中 Customized Data Types 的語法規則為 typedef 接著一個資料型態 與一個以上的 identifier,而該資料型態也可以為 Nested Structure,所以我們 得知此兩種變形的語法規則有重疊的部分,因此將一併實作,如 Figure 5-2。

1 declaration

2 : TYPEDEF type_specifier declarator_list ';'

3 { check if struct sk_buff exits in type_specifier }

4 ;

5 type_specifier

6 : TYPE_NAME

7 | struct_specifier

8 ;

9 struct_specifier

10 : STRUCT IDENTIFIER '{' struct_declaration_list '}'

11 { check if struct sk_buff exits in struct_declaration_list } 12 | STRUCT '{' struct_declaration_list '}'

13 { check if struct sk_buff exits in struct_declaration_list }

14 | STRUCT IDENTIFIER

15 ;

16 struct_declaration_list

17 : type_specifier declarator_list ';'

18 | struct_declaration_list type_specifier declarator_list ';'

19 ;

20 declarator_list 21 : declarator

22 | declarator_list ',' declarator

23 ;

24 declarator

25 : pointer IDENTIFIER

26 | IDENTIFIER

27 ;

我們可以於 struct_specifier 檢查 struct 宣告內部是否包含 struct sk_buff,

找出 Nested Structure,之後我們可以於 declaration 檢查 typedef 的資料結構 是否為 struct sk_buff,找出 Customized Data Types。

5.2.2 Direct use function/Indirect use function Module 之實作

首先介紹 Direct use function Module 的實作,因為我們要找出核心系統中,

傳遞或回傳結構型態為 struct sk_buff 之參數的所有函式,並且嵌入指令於這些函 式,所以必頇從核心系統的原始程式碼,找出所有函式的定義,進而找出 Direct use of function。而 C 語言的函式定義之語法規則,ANSI 也已經訂定其標準,因 此我們只需利用該標準即可實作,如 Figure 5-3。

1 declaration_specifiers

2 : storage_class_specifier

3 | storage_class_specifier declaration_specifiers 4 | type_specifier

5 | type_specifier declaration_specifiers 6 | type_qualifier

7 | type_qualifier declaration_specifiers 8 | function_specifier

9 | function_specifier declaration_specifiers

10 ;

11 declarator

12 : pointer direct_declarator 13 | direct_declarator

14 ;

15 direct_declarator

16 : IDENTIFIER

17 | '(' declarator ')'

18 | direct_declarator '(' parameter_type_list ')' 19 | direct_declarator '(' ')'

20 ;

21 parameter_type_list 22 : parameter_list

23 | parameter_list ',' ELLIPSIS

24 ;

25 parameter_list

26 : declaration_specifiers declarator

27 | parameter_list ',' declaration_specifiers declarator

28 ;

29 function_definition

30 : declaration_specifiers declarator '{' block_item_list '}' 31 check if struct sk_buff exit in declaration_specifiers

32 check if struct sk_buff exit in parameter_type_list of declarator

33 ;

Figure 5-3 Function Definition 的語法規則

我們於 function_definition 檢查 declaration_specifiers 是否包含 struct sk_buff,

判斷函式是否回傳資料型態為 struct sk_buff 的參數。接著於 declaratior 檢查其中 的 parameter_type_list 是否包含 struct sk_buff,判斷函式是否傳遞資料型態為

struct sk_buff 的參數,所以我們將可以判斷此函式是否為 Direct use function。

最後介紹 Indirect use function Module 的實作,因為我們要找出核心系統中,

呼叫 Direct use function 或者被 Direct use function 呼叫的所有函式,並且判斷是 否為 Indirect use function。所以必頇從函式定義之中的敘述主體,即 Figure 5-3 中的 block_item_list,判斷是否為 Indirect use function。而判斷的方法已經於第 4.5.1 節的 Indirect use function Module 說明,在此不再贅述。

為了剖析與除錯網路通訊協定堆疊,我們需要測量封包於函式內部的處理時 間,因此當 Direct use function Module 與 Indirect use function Module 找到封包處 理函式時,需要嵌入指令於該函式的起始點(Start Point)與結束點(End Point)。一 個函式只會有一個起始點,然而一個函式卻可能存在許多個結束點,因為一個函 式可以於任何地方結束,並將控制權交還給 Caller Function。

在 C 語言中,擁有一個保留字(return),當函式執行到 return 時,即交還控 制權。如果函式的回傳參數其型態為 void,則不一定需要 return,當函式執行完 成之後,會自動將控制權交還給 Caller Function。

因此 Direct use function Module 與 Indirect use function Module 將藉由函式回 傳參數的型態以及 return,尋找並且嵌入指令於函式的結束點,如 Figure 5-4。

End Point

Figure 5-4 嵌入指令於函式的結束點

然而如果我們於 Linux 核心系統的原始程式碼,嵌入直接記錄資訊的指令,

缺點是在於當我們想要變更輸出資訊時,必頇重新執行本技術,重新編譯核心系 統。

為了改善此缺點,因此本技術將建立於曹敏峰所實作的動態指令嵌入平台 [48],本論文已於 3.2 小節介紹該平台。本技術只嵌入 Probe 於封包處理函式之 中,此後如果我們想要改變觀察的函式或者記錄的資訊,藉由修改核心模組,即 可達成目的,不需要重新執行選擇性指令嵌入技術,以及重新編譯核心系統。

相關文件