最近在看《黑卡免杀攻防》,对讲解的PE文件导入表、导出表的作用与原理有了更深刻的理解,特此记录。
首先,要知道什么是导入表?
导入表机制是PE文件从其他第三方程序(一般是DLL动态链接库)中导入API,以提供本程序调用的机制。而在Windows平台下,PE文件中的导入表结构就承担了完成这一工作的引导者角色。
IMAGE_IMPORT_DESCRIPTOR结构
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
DWORD ForwarderChain; // -1 if no forwarders
DWORD Name;
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
一般来说,对于导入表,我们只需要关注它的两个字段,分别是OriginalFirstThunk与FirstThunk,这两个字段分别指向了包含导出名称和导出地址的IMAGE_THUNK_DATA结构数组,这个数组以空的IMAGE_THUNK_DATA结构结尾。
IMAGE_THUNK_DATA结构
typedef struct _IMAGE_THUNK_DATA32 {
union {
PBYTE ForwarderString; // 转发字符串的RAV
PDWORD Function; // 被导入函数的地址
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData; // 指向输入名称表
} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
ForwarderString是转发用的,暂时不用考虑&#x