加密与解密(PE结构笔记⑤)

来源:互联网 发布:淘宝微淘达人佣金 编辑:程序博客网 时间:2024/06/14 20:41
    PE结构可以说是在Windows编程中、破解加密解密、外垮病毒等等领域很重要的基石。
    推荐教材:《加密与解密》
    推荐教程:鱼C工作室加密与解密PE结构系列    

    在PE文件中IMAGE_NT_HEADER结构中的IMAGE_OPTIONAL_HEADER32结构的最后一个字段DataDirectory结构数组,即数据目录表,其第二个成员就是指向输入表。输入表是以一个 IMAGE_IMPORT_DESCRIPTOR(简称IID) 的数组开始,每个被 PE文件链接进来的 DLL文件都分别对应一个 IID数组结构。在这个 IID数组中,并没有指出有多少个项(就是没有明确指明有多少个链接文件),但它最后是以一个全为NULL(0) 的 IID 作为结束的标志。
    
    OriginalFirsThunk字段:它指向first thunk,IMAGE_THUNK_DATA结构,该thunk拥有Hint和Function name的地址;
    Name字段:它表示DLL 名称的相对虚地址;
    FirstThunk字段:它包含由IMAGE_THUNK_DATA定义的 first thunk数组的虚地址,通过loader用函数虚地址初始化thunk。在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function names的thunks。
    看图:
    
    当程序还未被加载入内存时,OriginalFirstThunk和FirstThunk都指向了一个叫IMAGE_THUNK_DATA的结构,只不过一个是INT一个是IAT,但它们最终依旧指向一个IMAGE_IMPORT_BT_NAME的结构。
每一个IMAGE_THUNK_DATA结构定义一个导入函数信息,然后数组最后以一个内容为0的 IMAGE_THUNK_DATA 结构作为结束标志。
    
    由于是共用体,所以不同情况赋予不同的意义。
    
那我们怎么来区分何时是何意义呢?
    规定如下:
    当 IMAGE_THUNK_DATA 值的最高位为 1时,表示函数以序号方式输入,这时候低 31位被看作一个函数序号。
    当 IMAGE_THUNK_DATA 值的最高位为 0时,表示函数以字符串类型的函数名方式输入,这时双字的值是一个 RVA,指向一个IMAGE_IMPORT_BY_NAME 结构。

    
    
结构中的 Hint 字段也表示函数的序号,不过这个字段是可选的,有些编译器总是将它设置为 0。
    Name 字段定义了导入函数的名称字符串,这是一个以 0 为结尾的字符串。

     
为什么由两个并行的指针数组同时指向 IMAGE_IMPORT_BY_NAME 结构呢?第一个数组(由 OriginalFirstThunk 所指向)是单独的一项,而且不能被改写,我们前边称为 INT。
    第二个数组(由 FirstThunk 所指向)事实上是由 PE 装载器重写的。
    PE 装载器首先搜索 OriginalFirstThunk ,找到之后加载程序迭代搜索数组中的每个指针,找到每个 IMAGE_IMPORT_BY_NAME 结构所指向的输入函数的地址,然后加载器用函数真正入口地址来替代由 FirstThunk 数组中的一个入口,因此我们称为输入地址表(IAT)。
    
1 0
原创粉丝点击