一、前言 二、PE整體結構 三、DOS頭 四、NT頭 五、區段頭
六、導出表
七、導入表 八、資源表 九、其他表
1.概念
導出 是指PE檔案導出的供其他PE檔案使用的函數、變量、或者類的行為。
符号 這些導出的函數、變量、類一般稱為符号。
導出表 是存儲導出的這些符号的表。通過導出表,能夠定位這些符号。
2.導出表定位
前面提到的 NT頭->擴充頭->資料目錄表->第一個元素->相對虛拟位址(RVA)
還用010Editor打開百度雲盤看一下
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90zdaVnRXVWdWdUYqljVl9mTywEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYvwFd4VGdvwlMvw1ayFWbyVGdhd3P1gjMyAjMzEDNyYDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
可以看到,資料目錄表中第一個元素的結構體内有兩個資料
-
相對虛拟位址
相對虛拟位址隻是一個偏移值,虛拟位址才是真正定位的值。
虛拟位址 = 程式加載基址(通常是0x400000) + 虛拟位址
因為有檔案對齊的問題,未加載0x200對齊,加載後0x1000對齊,改位址并不能直接在檔案中找到導出表的位置。
需要将虛拟位址,轉換成,檔案偏移。
檔案FOA = 導出表RVA - 區段RVA + 區段FOA
導出表應該在.edata段中,但通常這個段會合并到.rdata中。
-
大小
EXE檔案通常是沒有導出内容的
大小,Size,值為0
我們換一個DLL檔案看一下
3.導出表結構
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name; // 目前PE檔案名
DWORD Base; // 序号基數
DWORD NumberOfFunctions; // 函數數量
DWORD NumberOfNames; // 函數名稱數量
DWORD AddressOfFunctions; // RVA 位址表
DWORD AddressOfNames; // RVA 名稱表
DWORD AddressOfNameOrdinals; // RVA 序号表
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
函數序号 需要通過序号基數加上序号表裡的序号才是真正的函數序号。
4.函數位址表
上面結構體中,AddressOfFunctions,該字段為導出函數位址表的**相對虛拟位址**RVA。
檔案未加載時,需要轉換為**檔案偏移**VA後才能使用。
檔案加載後,需要轉為為**虛拟位址**FOA才能使用。
找到導出函數位址表後,每條4個位元組為一條資料,共有NumberOfFunctions個。
5.函數名稱表
上面結構體中,AddressOfNames,該字段為導出函數名稱表的**相對虛拟位址**RVA。
表記憶體儲的是函數名稱的相對虛拟位址。
檔案未加載時,需要轉換為檔案偏移後才能使用。
檔案加載後,需要轉為為虛拟位址才能使用。
找到導出函數位址表後,每條4個位元組為一條資料,共有NumberOfFunctions個。每條資料為一個位址,指向函數名稱字元串。
6.函數序号表
上面結構體中,AddressOfNameOrdinals,該字段為導出函數序号表的**相對虛拟位址**RVA。
檔案未加載時,需要轉換為**檔案偏移**VA後才能使用。
檔案加載後,需要轉為為**虛拟位址**FOA才能使用。
找到導出函數序号表後,每條2個位元組為一條資料,共有NumberOfFunctions個。
7.位址表、名稱表、序号表關系
序号表 與 名稱表,兩表内容按索引值一一對應。
序号表 與 位址表,序号表内容 與 位址表索引加一的資料相對應。
位址表内容可能會比名稱表多,沒對應上的部分可能是用序号導出的函數,也可能是無效函數,位址為0。
上一篇 :【PE結構】3.區段頭
下一篇 :【PE結構】5.導入表