typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk; //指向输入名称表(INT)的RVA
};
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name; //指向导入PE文件的名字的RVA
DWORD FirstThunk; //指向输入地址表(IAT)的RVA
} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPROT_DESCRIPTOR;
说明:
1.OriginalFirstThunk 与 FirstThunk指向的是相同类型的结构体
2.磁盘文件中OriginalFirstThunk 与 FirstThunk的数据是相同的。加载到内存中之后,输入地址表会由加载器把相应Pe文件的函数地址覆盖到这里来。这是输入地址表才是真正的输入地址表。
3.有些文件中输入名称表是空的。说明输入地址表没有备份。所以解析输入表时最好用输入地址表解析。也可以两个都解析。
4.指向的结构体数组全以0为结尾,可以作为解析时的结束条件。
5.INT与IAT所指向的数据类型:
typedef struct _IMAGE_THUNK_DATA32 {
union {
DWORD ForwarderString; // PBYTE
DWORD Function; // 导入函数的地址,加载到内存后这里才生效
DWORD Ordinal; //假如是序号导入的,用到这里
DWORD AddressOfData; // 若是函数名导入的,用到这里,指向一个PIMAGE_IMPORT_BY_NAME结构体
} u1;
} IMAGE_THUNK_DATA32;
说明:
1.在磁盘文件中,起作用的只有后两个成员。
2.这个结构占据4个字节,假如最高位为1,那么序号导入起作用,只需输出一个序号,假如最高位为0,那么是函数名导入起作用,指向一个PIMAGE_IMPORT_BY_NAME。可以用IMAGE_SNAP_BY_ORDINAL32()判断最高位是否为1,参数就是这个结构体。
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint; //ordinal 序号
BYTE Name[1]; //function name string 函数名
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
- INT与IAT是长整型(4个字节数据类型)数组,以NULL结束
- INT中各元素的值为IMAGE_IMPORT_BY_NAME结构体指针(有时IAT也拥有相同的值)
- INT与IAT的大小应相同