1.介绍
绑定导入表的作用是加快程序的启动速度,一个PE程序在启动时会去加载导入表中的dll文件,并将导入表的FirstThunk指向的数组填入函数的真实地址,这需要耗去时间,绑定导入表中保存了导入函数的真实地址,所以当PE在启动时系统检测到有绑定导入表,就会直接将地址填入FirstThunk里,这样就省去了寻找真实地址的时间。
但是绑定导入表的生效,有两个前提条件:
- 程序初始化时,导入的DLL都加载到了首选基址中
- 程序执行了绑定导入操作以后,导入DLL中引用的符号位置一直没有变化
如果有任何一个条件没有满足,系统就会忽略绑定导入操作。
2.分析
在数据目录表中找到绑定导入表,本例是Win7下的mspaint.exe,它的RVA是280h,大小为360,下图是它的十六进制数据:
我们对照它的结构体IMAGE_BOUND_IMPORT_DESCRIPTOR来分析:
typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD NumberOfModuleForwarderRefs;
} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;
TimeDateStamp:时间戳,不多作解释,对应上图的0x4a5bd97e
OffsetModuleName:偏移,基址是IMAGE_BOUND_IMPORT_DESCRIPTOR的开端,对应上图的0x00a0,0x280+0xa0就是dll名称的位置
NumberOfModuleForwarderRefs:后面IMAGE_BOUND_FORWARDER_REF结构的数量,对应上图的0x01
我们再来看看IMAGE_BOUND_FORWARDER_REF的结构体:
typedef struct _IMAGE_BOUND_FORWARDER_REF {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
这个结构体的内容跟上面的其实是差不多的,绑定导入表中有一个函数转发链机制,比如说KERNEL32.DLL里面的HeapAlloc函数会转发到NTDLL.DLL中的RtlAllocateHeap函数,一般情况下NumberOfModuleForwarderRefs为0,这个结构体对应上图中的0x288-0x28f处的内容