PE檔案結構(四) 輸出表

billvsme發表於2014-10-06

PE檔案結構(四)


參考

書:《加密與解密》

視訊:小甲魚 解密系列 視訊


輸出表


一般來說輸出表存在於dll中。輸出表提供了 檔案中函式的名字跟這些函式的地址, PE裝載器通過輸出表來修改IAT。

IMAGE_OPTIONAL_HEADER中的 DataDirectory[0] 提供了輸出表的RVA。輸出表是以一個IMAGE_EXPORT_DIRECTORY結構 開始的。


IMAGE_EXPORT_DIRECTORY結構:

typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;         //未使用
    DWORD   TimeDateStamp;           //檔案生成的時間
    WORD    MajorVersion;            //主版本號,一般為0
    WORD    MinorVersion;            //次版本號,一般為0
    DWORD   Name;                    //指向dll名的RVA
    DWORD   Base;                    // 基數,一般為 1 (就是從1數起)
    DWORD   NumberOfFunctions;       // AddressOfFunctions指向的陣列的元素的個數
    DWORD   NumberOfNames;           // AddressOfNames 指向的陣列的元素的個數
    DWORD   AddressOfFunctions;     // 函式地址陣列ENT的RVA
    DWORD   AddressOfNames;         // 函式名字陣列EAT的RVA 
    DWORD   AddressOfNameOrdinals;  // 輸出序列號陣列的RVA,這個陣列是以WORD為單位的,用來函式名字陣列連線函式地址陣列的
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;


輸出表主要就是來給PE載入器修改IAT的,即查詢函式的入口地址。PE載入器查詢函式的地址有兩種方法,從序號查詢,從函式名查詢。


1. 從序號查詢函式入口地址

    PE載入器通過INT知道了序號,直接用這個序號 去找 函式地址陣列EAT就可以了。


2. 從函式名查詢函式入口地址

    通過函式名,查詢函式名陣列ENT,找到這個函式名在陣列中的序號 n(從0數起),然後取輸出序列號陣列的第n個值(從0數起)。然後 以這個值為序號的的函式地址陣列EAT的值就是這個函式的入口地址。


即 ENT[  輸出序列號陣列[n]  ] 


例項分析:


例如找user32.dll 中AdjustWindowRect 這個函式。


先檢視user32.dll的二進位制檔案,它的IMAGE_OPTIONAL_HEADER結構為:


圖片1



從中可以知道:

Name: RVA 55C0h          檔案偏移值:49C0h  
Base: 1
NumberOfFunctions: 02DCh  
NumberOfNmae:02DCh
AddressOfFunctions:  RVA 3928h         檔案偏移值:2D28h
AddressOfNames:  RVA 4498h             檔案偏移值:3898h
AddressOfNameOrdinals: RVA 5008h        檔案偏移值:4408h


檢視ENT陣列所指向的字串,可以知道AdjustWindowRect是第2個元素。所以,檢視AddressOfNameOrdinals所指向的輸出序列號陣列的第2個元素,可以發現值為 1。


圖片2



再檢視EAT中序號為1的元素(即第2個元素)值為021140h,這個就是AdjustWindowRect函式的RVA。


圖片3






















相關文章