• 沒有找到結果。

The Classify of Driver Function

4.1 The Skeleton of Program Function

要分析及轉換一個程式前,我們必須先了解一個程式的結構,以下面一個C語言所 寫的範例為例:

void main() {

printf(“ 5 + 5 = ", add(5,5));

}

int add(x,y) {

return sum(5,5);

}

程式由小到大的分別由三個步驟完成,如Table 13紅色箭頭所示:

Step 1:單一識別子( Single Identifier)組成一行函數原型(Function Prototype)。

Step 2:每個單行的函數原型再組成一個函數區塊(Function Block)。

Step 3:所有函數區塊的集合就形成了最後的程式區段(Program Section)。

Element Example

Single Identifier void、main、int、printf、sum 、return

Function Prototype

printf(“ 5 + 5 = ", add(5,5)); 、 sum(5,5);

Function Block

int add(x,y) {

return sum(5,5);

}

Program Section

void main() {

printf(“ 5 + 5 = ", add(5,5));

}

int add(x,y) {

return sum(5,5);

}

Table 13: Construct a Program Function

把要比對的識別子(Identifier)分成五種型態,存在資料庫並給予一個代號(flag)來區 別,如Table 14所示,藍色字體為Windows Identifier、紅色字體為Linux Identifier,分別 介紹如下:

No Flag Type Example

1 F Function ExFreePoolÆkfree

KeSetPriorityThreadÆset_user_nice 2 S Status STATUS_UNSUCCESSFULÆ-EFAULT

STATUS_DEVICE_BUSYÆ-EBUSY 3 P Function Parameter PagedPoolÆGFP_KERNEL

NonPagedPoolÆGFP_ATOMIC 4 T Data Type PUINTÆunsigned int *

KSPIN_LOCK Æspinlock_t LIST_ENTRYÆlist_head 5 D Driver Only DriverEntryÆfile_operations

DEVICE_EXTENSIONÆprivate_data

Table 14: The Category of Single Identifier

z 第一種F為函數,釋放記憶體的函數原型在Windows和Linux分別為:

VOID ExFreePool(IN PVOID P);

void kfree (void *ptr);

以及調整執行緒優先權的函數原型在Windows和Linux分別為:

KPRIORITY KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority);

void set_user_nice ( task_t *p , long nice);

以及插入項目到串列尾部的函數原型在Windows和Linux分別為:

VOID InsertTailList(IN PLIST_ENTRY ListHead,IN PLIST_ENTRY Entry);

void list_add_tail(struct list_head *new, struct list_head *head);

z 第二種S為回傳的狀態值,失敗的回傳值在Windows和Linux分別為:

STATUS_UNSUCCESSFUL -EFAULT

以及裝置忙碌的回傳值在Windows和Linux分別為:

STATUS_DEVICE_BUSY -EBUSY

z 第三種P為函數的參數值,可移出分頁的參數在Windows和Linux分別為:

PagedPool GFP_KERNEL

以及不可移出分頁的參數在Windows和Linux分別為:

NonPagedPool GFP_ATOMIC

z 第四種T為資料型態,指向無正負符號的整數型態變數,在Windows和Linux 分別為:

PUINT unsigned int *

以及自旋鎖的資料型別在Windows和Linux分別為:

KSPIN_LOCK spinlock_t

以及雙向鏈結串列型態在Windows和Linux分別為:

LIST_ENTRY list_head

z 第五種D為驅動程式特有的識別子,驅動程式指定Entry Function在Windows和 Linux分別為:

DriverEntry file_operations

以及驅動程式內部資料在Windows和Linux分別為:

DEVICE_EXTENSION private_data

4.2 Classify the Map with Driver Function

收集常用的Function比對後,可以完全對應(Full Map)的Identifier有77個,部分對應 (Partial Map)的有33個,只有Windows才有的Function有73個,只有Linux才有的Function 有28個,如Table 15。

Symbol Map Count

0 Full Map 77

1 Partial Map 33

2 Only for Windows, will mark it 73 3 Only for Linux, no influence or added 28

Total 211 Table 15: The Statistic of Function Map

兩邊的程式都是使用C語言來撰寫,所以平時用到的函數,如sizeof()、sum()函數

Windows Linux

Function Prototype

VOID RtlCopyMemory(

IN VOID UNALIGNED *Destination, IN CONST VOID UNALIGNED *Source, IN SIZE_T Length

);

Unsigned long copy_from_user(

void *to,

Table 16: Full Map with Data Copy Function

z Partial Map:函數功能完全相同但參數部分相同,以I/O位址對映到記憶體的函 數為例,如Table 17,在Windows的函數名為MmMapIoSpace,在Linux函數名 為ioremap,均有指定記憶體位置及大小的參數,但Windows平台多了一個指 定CacheType的參數。

Windows Linux

Function Prototype PVOID MmMapIoSpace(IN

PHYSICAL_ADDRESS PhysicalAddress, IN ULONG NumberOfBytes,

IN MEMORY_CACHING_TYPE CacheType );

void *ioremap(

unsigned long phys_addr, unsigned long size );

Token with parameter

MmMapIoSpace ioremap

Table 17: Partial Map with I/O Map Function

另一個類似的例子是將某塊記憶體清空為零的函數,如Table 18,在Windows的函 數名為RtlZeroMemory對應到Linux的函數名為memset,均有指定記憶體位置及長度的參 數,但Linux平台的函數較有彈性,在第二個參數可設定將記憶體清成偏好的值。此部

分要轉換必須將各個Identifier轉成Lex/Yacc可辨識的Token,再重新排放。

Windows Linux

Function Prototype VOID RtlZeroMemory(

IN VOID UNALIGNED *Destination, IN SIZE_T Length

);

void *memset(

void *s,

int c, // can set to prefer value size_t n

);

Table 18: Partial Map with Memory Set Function

z 特殊情況一:Windows沒有但Linux才有的函數,像module_init及module_exit 這兩個函數是Linux Driver特有的函數,如Table 19。此部分轉換後由Driver Generator另行加入程式碼即可。

Map Type Include Windows Linux

2 F linux/init.h Windows not Exist but Linux Exist module_init(XXX_init);

2 F linux/init.h Windows not Exist but Linux Exist module_exit(XXX_exit);

Table 19: Linux Only Function

z 特殊情況二:Windows有但Linux沒有的函數,像IoCreateSymbolicLink及 IoDeleteSymbolicLink這兩個函數是Windows Driver特有的函數,如Table 20。

此部分轉換到Linux後必須將Windows程式註解掉。

Map Type Include Windows Linux

3 F IoCreateSymbolicLink Windows Exist but Linux not Exist 3 F IoDeleteSymbolicLink Windows Exist but Linux not Exist

Table 20: Windows Only Function

有了上面的分類基礎及處理方式才能著手建立轉換模式,在後面的章節我們會使用 Lex/Yacc[19][20]來做轉換,並將這些函數的對應建立在資料庫裏以便做前置處理。

相關文件