-
-
[原创]《加密与解密》读书笔记(四) PE文件格式 绑定输入
-
发表于: 2020-10-12 14:37 2980
-
PE装载PE文件时需要重写IAT,这个过程是很浪费时间的。绑定输入就是为了解决这样的问题。
当一个可执行文件被绑定,IAT中的IMAGE_THUNK_DATA结构的实际地址就被改写了,这是其中存放的就已经是函数的真实地址了,这样可以使程序更快的进行初始化,并且使用较少的内存空间,但是绑定时绑定程序是基于这样的两个假设进行的:1、需要的DLL实际上加载到了它们的首选地址中 2、自从绑定以来,DLL中的输出表中引用的符号位置一直没有改变。如果这两个假设任意一个不成立,IAT中的所有地址可能都是无效的,这时装载器会从INT中获取数据来解决输入API的问题。虽然载入程序不需要INT,但是如果没有INT,程序是不能被绑定的。当一个控制性文件被绑定时,被参考的DLL信息会被放入文件中,加载器通过检查这些信息来进行快速的绑定有效性验证。
数据目录表的第12个成员指向绑定输入。绑定输入以一个IMAGE_BOUND_IMPORT_DESCRIPTOR结构的数组开始。一个绑定可执行文件包含一些列这样的结构。每一个这样的结构都指出了被绑定DLL的时间/日期戳。
TimeDateStamp 包含一个被输入DLL的时间/日期戳。它允许加载器快速判断绑定是否是新的
OffsetMoudleName 包含一个指向被输入DLL名称的偏移。这个字段是与第一IMAGE_BOUND_IMPORT_DESCRIPTOR结构之间的偏移,并不是RVA
NumberOfModuleForworderRefs 包含紧跟着该结构的IMAGE_BOUND_FORWARDER_REF结构的数目,即转发链机制,这里是表示转发的模块数量。IMAGE_BOUND_FORWARDER_REF的结构除了最后一个字被保留以外,其他的部分和IMAGE_BOUND_IMPORT_DESCRIPTOR结构相同。
函数转发:加载的DLL模块内部不提供函数实现,通过转发的形式,让其在其他DLL模块中查找函数实现并调用
当绑定API被转向另一个DLL时,转向的DLL的有效性也要被检查。这样,上面提到的两个结构就是交叉存取的了。
typedef struct IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
WORD OffsetMoudleName;
WORD NumberOfModuleForworderRefs;
} IMAGE_BOUND_IMPORT_DESCRIPTOR;
typedef struct IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!