导入表
一、定位导入表
可选PE头的最后一个成员属性IMAGE_DATA_DIRECTORY DataDirectory,成员属性有16个,第二个存储就是导出表的位置
IMAGE_DIRECTORY_ENTRY_IMPORT
struct _IMAGE_DATA_DIRECTORY {
0x00 DWORD VirtualAddress; //导入表的地址
0x04 DWORD Size; //大小
};
二、导入表结构
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk; //RVA 指向IMAGE_THUNK_DATA结构数组
};
DWORD TimeDateStamp; //时间戳
DWORD ForwarderChain;
DWORD Name; //RVA,指向dll名字,该名字已0结尾
DWORD FirstThunk; //RVA,指向IMAGE_THUNK_DATA结构数组
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
导入表由一堆表组成,每个表占20个字节,当查到有20个字节都为0时,说明导入表到此结束
三、INT表(导入名称表)
typedef struct _IMAGE_THUNK_DATA32 {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal; //序号
PIMAGE_IMPORT_BY_NAME AddressOfData; //指向IMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA32;
1、导入表的第一个成员存的是INT表的地址,INT表每个成员是4字节,一直查到4个字节都为0时,说明INT结束
2、根据INT表找到导入函数
- 判断最高位是否为1,如果是,那么去除最高位的值,就是函数的导出序号,如果不是那么这个值是一个RVA 指向
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint; //可能为空,编译器决定 如果不为空 是函数在导出表中的索引
BYTE Name[1]; //函数名称,以0结尾
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;