在PE头中,有导入目录,它描述了加载器应该在哪里绑定导入的符号。更准确地说:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics;
DWORD OriginalFirstThunk;
} DUMMYUNIONNAME;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
DWORD FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
FirstThunk
字段是绑定点的RVA,位于IAT(即.idata
部分)。
通常,链接器会在
.idata
上生成一些初始值。我认为这些都是无用的,直到我意识到如果我擦除整个 .idata
,DLL 将无法加载。这是因为加载器没有绑定导入符号,导致程序尝试调用这些导入的 API 时出现访问冲突。
我的问题是,为什么IAT中有初始值?是否需要加载DLL?我认为导入目录的 prodving 应该足以让加载程序绑定导入。
FirstThunk
在加载之前存储(对)序数。这就是所谓的“提示”。
加载后,它会被符号的真实地址覆盖。
序号是导出地址表的索引。
要获取导入符号(例如MessageBoxW