當pe檔案執行時,pe檔案將被系統載入進入記憶體中,此時windows載入器會定位所有的匯入的函式或者將定位到的內容填寫到可執行檔案的某個位置供使用,這個定位是需要借助於可執行檔案的匯入表來實現的。匯入表中存放了所使用的dll模組名稱及匯入函式的名稱或者函式序列。
在pe檔案中定位到pe頭部的可選頭的位置,可選頭image_optional_header中最後乙個成員:
image_data_directory datadirectory[image_numberof_directory_entries];
image_data_directory的結構如下:
typedef struct _image_data_directory
image_data_directory, *pimage_data_directory;
最後乙個成員為陣列,陣列中不同的索引值對應不同的資料目錄
所以定位到資料目錄中的第二個目錄,該目錄包含匯入表的相對虛擬位址,根據相對於基位址的偏移量找到匯入表的首位址,匯入表是乙個
image_import_descriptor型別的陣列,被匯入的每乙個dll都對應陣列中的乙個image_import_descriptor結構體,匯入表以乙個全為0的image_import_descriptor結構結束。
typedef struct _image_import_descriptor image_import_descriptor, *pimage_import_descriptor;
每乙個image_thunk_data對應乙個dll匯入的函式,同樣image_thunk_data的結構體陣列以乙個全為0的image_thunk_data的結構體結束
typedef struct _image_thunk_data32 u1;
} image_thunk_data32;
這個結構體的成員只有乙個聯合體,就相當於結構體實際上只是乙個dword型別,只是不同時候代表的意義不同:
在磁碟上時,originalfirstthunk指向的image_thunk_data中儲存的是指向匯入名稱表的相對虛擬位址,此時 firstthunk也指向如此,它們在磁碟中是沒有差別的;
在檔案被載入在記憶體中時,originalfirstthunk指向的image_thunk_data中儲存的仍然是指向匯入名稱表的相對虛擬位址,而firstthunk指向的image_thunk_data則變成了由windows載入器填充的匯入位址表的相對虛擬位址。
function表示函式位址,如果是按序號匯入ordinal就有用了,若是按名字匯入addressofdata便指向名字資訊。可以看出這個結構體就是乙個大的union,union雖包含多個域但是在不同時刻代表不同的意義那到底應該是名字還是序號,該如何區分呢?可以通過結構體判斷,如果結構體的最高位是1,就是按序號匯入的,這時候,低31位就是匯入序號,如果最高位是0,則addressofdata是乙個rva,指向乙個image_import_by_name結構,用來儲存名字資訊,由於ordinal和addressofdata實際上是同乙個記憶體空間,所以addressofdata其實只有低31位可以表示rva。
了解一下image_import_by_name結構。
typedef struct _image_import_by_name_
image_import_by_name,*pimage_import_by_name;
hint: 儲存著需要匯入函式的序號,這個值不是必須的。
name: 儲存著需要匯入函式的名稱,函式名不可能由乙個位元組組成的,這裡通過越界訪問來達到訪問字串的功能。
PE檔案結構詳解(四)PE匯入表
pe檔案結構詳解 二 可執行檔案頭的最後展示了乙個陣列,pe檔案結構詳解 三 pe匯出表中解釋了其中第一項的格式,本篇文章來揭示這個陣列中的第二項 image directory entry import,即匯入表。也許大家注意到過,在image data directory中,有幾項的名字都和匯入...
PE檔案結構詳解(四)PE匯入表
pe檔案結構詳解 二 可執行檔案頭的最後展示了乙個陣列,pe檔案結構詳解 三 pe匯出表中解釋了其中第一項的格式,本篇文章來揭示這個陣列中的第二項 image directory entry import,即匯入表。也許大家注意到過,在image data directory中,有幾項的名字都和匯入...
PE檔案結構詳解(四)PE匯入表
pe檔案結構詳解 二 可執行檔案頭的最後展示了乙個陣列,pe檔案結構詳解 三 pe匯出表中解釋了其中第一項的格式,本篇文章來揭示這個陣列中的第二項 image directory entry import,即匯入表。也許大家注意到過,在image data directory中,有幾項的名字都和匯入...