什麼是輸入表?
輸入表就相當於exe檔案與
dll檔案溝通的橋梁,形象的可以比喻成兩個城市之間交流的高速公路。在pe檔案對映到記憶體後,windows將相應的dll檔案裝入,exe檔案通過「輸入表」找到相應的dll中的匯入函式,從而完成程式的正常執行。
輸入表的組成與工作原理?
首先大概了解整體的結構:
三個表: ①
輸入表:
對應image_import_descriptor結構體。
②輸入名稱表(int):對應image_thunk_data結構體。
③輸入位址表(iat):也是對應image_thunk_data結構體。
由1圖,輸入名稱表(int)和
輸入位址表(iat)都
是image_thunk_data結構體的陣列。並且這兩個陣列都是以乙個空的結構體作為結束的。
而image_thunk_data實質上是四個指標(每個指標四位元組,共16位元組)組成的結構體。這裡理解錯了:image_thunk_data不是四個指標的結構體,而是共用體(關鍵字:union):共用體表
示幾個變數
共用乙個記憶體位置,在不同的時間儲存不同的資料型別
和不同長度的變數
。在union中,所有共用體
成員共用乙個空間,並且同一時間只能儲存其中乙個成員的
值。結構如下:
image_import_by_name結構體:
下面把流程走一下:
>
假設我們要列出某個pe檔案的所有引入函式,可以照著下面步驟走:
校驗檔案是否是有效的pe。
從dos header
定位到pe header。
獲取位於
optionalheader 資料目錄位址。
轉至資料目錄的第二個成員提取其virtualaddress值。
利用上值定位第乙個
image_import_descriptor 結構。
檢查originalfirstthunk值。若不為0,順著 originalfirstthunk 裡的rva值轉入那個rva陣列。若originalfirstthunk 為0,就改用firstthunk值。有些聯結器生成pe檔案時會置originalfirstthunk值為0,這應該算是個bug。不過為了安全起見,我們還是檢查
originalfirstthunk值先。
對於每個陣列元素,我們比對元素值是否等於image_ordinal_flag32。如果該元素值的最高二進位為1,那麼函式是由序數引入的,可以從該值的低位元組提取序數。
如果元素值的最高二進位為0,就可將該值作為rva轉入
image_import_by_name 陣列,跳過
hint 就是函式名字了。
再跳至下乙個陣列元素提取函式名一直到陣列底部(它以null結尾)。現在我們已遍歷完乙個dll的引入函式,接下去處理下乙個dll。
即跳轉到下乙個
image_import_descriptor
並處理之,如此這般迴圈直到陣列見底。(image_import_descriptor
陣列以乙個全0域元素結尾)。
PE檔案中的輸入表
pe檔案中的輸入表含有三個重要結構iid,int,iat。pe檔案為需要載入的dll檔案建立乙個iid結構,乙個dll與乙個iid對應。int是輸入名稱表,iat輸入位址表,在沒有繫結輸入的情況下磁碟中的檔案int與iat相同。如果有繫結輸入的話因為繫結輸入的函式其磁碟檔案中的iat項就已經是對應函...
PE檔案詳解五 PE詳解之輸入表(匯入表)詳解1
首先,我們知道pe 檔案中的資料被載入記憶體後根據不同頁面屬性被劃分成很多區塊 節 並有區塊表 節表 的資料來描述這些區塊。這裡我們需要注意的問題是 乙個區塊中的數 據僅僅只是由於屬性相同而放在一起,並不一定是同一種用途的內容。例如輸入表 輸出表等就有可能和唯讀常量一起被放在同乙個區塊中,因為他們的...
PE檔案詳解五 PE詳解之輸入表(匯入表)詳解1
首先,我們知道pe 檔案中的資料被載入記憶體後根據不同頁面屬性被劃分成很多區塊 節 並有區塊表 節表 的資料來描述這些區塊。這裡我們需要注意的問題是 乙個區塊中的數 據僅僅只是由於屬性相同而放在一起,並不一定是同一種用途的內容。例如輸入表 輸出表等就有可能和唯讀常量一起被放在同乙個區塊中,因為他們的...