IMAGE_IMPORT_DESCRIPTOR结构体中记录着PE文件要导入哪些库文件
<span style="font-size:12px;">typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk; //INT(Import Name Table) address (RVA)
};
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name; //library name string address (RVA)
DWORD FirstThunk; //IAT(Import Address Table) address (RVA)
} IMAGE_IMPORT_DESCRIPTOR;
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint; //ordinal
BYTE Name[1]; //function name string
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;</span>
OriginalFirstThunk INT的地址
Name 库名称字符串的地址
FirstThunk IAT的地址
- INT与IAT是长整型(4个字节数据类型)数组,以NULL结束
- INT中各元素的值为IMAGE_IMPORT_BY_NAME结构体指针(有时IAT也拥有相同的值)
- INT与IAT的大小应相同
INT输入顺序
1.读取IID的Name成员,获取库名称字符串("kernel32.dll")
2.装载相应库——————> LoadLibrary("kernel32.dll")
3.读取IID的OriginalFirstThunk成员,获取INT地址
4.逐一读取INT中数组的值,获取相应IMAGE_IMPORT_BY_NAME地址(RVA)
5.使用IMAGE_IMPORT_BY_NAME的Hint(ordinal) 或Name项,获取相应函数的起始地址。 GetProcAddress("GetCurrentThreadId")
6.读取IID的FirstThunk(IAT)成员,获得IAT地址
7.将上面获得的函数地址输入相应IAT数组值。
8.重复以上补助4~7,直到INT结束(遇到NULL时)