逆向-PE導出表

PE-導出表

​ 動態連接庫要想給別人用實現加載時或運行時連接就必須提供函數和數據的地址。exe通常不會有這個,大部分是DLL文件的。導出分爲名字導出和序號導出。windows

  1. 名字導出先找名字,再經過名字表的索引找到AddressOfNameOrdinals裏面的值,此值即爲name和函數地址關聯處,是AddressOfFunctions的索引
  2. 序號導出,序號-base就是AddressOfFunctions索引,直接找就是函數地址。
typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   AddressOfFunctions;     // RVA from base of image
    DWORD   AddressOfNames;         // RVA from base of image
    DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
  1. Name指向一個ASCII字符串的RVA數組

  2. 對應此PE文件輸出標的起始序數值(基數)。當經過序數來查詢一個導入函數時,這個值從序數裏被減去,結果做爲導出地址表(EAT)的索引。函數

  3. NumberOfFunctions EAT表中條目數量code

  4. NumberOfNames 導出函數名稱表(ENT)裏條目數量。和導出序號表數量同樣,有的爲了避免讓看到名字會將名字隱去,只經過序號輸出的時候。blog

  5. AddressOfFunctions 導出表函數數組地址(EAT),經過AddressOfNameOrdinals保存的值+base映射過來索引

  6. AddressOfNameOrdinals 和NumberOfNames一一對應(數組索引)裏面的值是EAT的索引值(不加base)。字符串

windows自己記載PE過程當中用到的就是LoadLibrary加載DLL並用 GetProcAddress 來獲得函數地址從新刷新導入表的。io

也就是說一個不一樣名字可能對應着同一個導出函數地址。有的導出函數沒有名字只能經過序號來找,序號-base就是AddressOfFunctions 數組的索引,而AddressOfNameOrdinals 裏存的值+base就是序號。
class

相關文章
相關標籤/搜索