PE知识复习之PE的绑定导入表

一丶简介

  根据前几讲,我们已经熟悉了导入表结构.但是如果大家尝试过打印导入表的结构. INT IAT的时候. 会出现问题.

PE在加载前 INT IAT表都指向一个名称表. 这样说是没错的. 但是如果你打印过导入表.会发现一个问题. 有的EXE程序.在打印IAT表的时候.发现里面是地址.

原因:

  我们的PE程序在加载的时候.我们知道. PE中导入表的子表. IAT表.会填写函数地址. 但是这就造成了一个问题.PE程序启动慢.每次启动都要给IAT表填写函数地址.

  我们可不可以在文件中就给填写好. 这样是可以的.

优点:

  PE程序启动变快.

缺点:

  如果DLL的ImageBase变了.那么就需要进行重定位.因为在文件中你填写的地址是固定的地址.

导入表结构:

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // INT 表
} DUMMYUNIONNAME;
DWORD TimeDateStamp; // 时间戳.
// -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;                //指向DLL名字的 RVA
DWORD FirstThunk; // IAT 表
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

但是我们怎么知道.在文件中IAT表是否填写地址.还是不填写地址. 重要的地方 就是 TimeDateStamp (时间戳)成员, 如果为0 则是这个DLL没有绑定. 如果为 -1 则是这个DLL进行了绑定.

那么什么是绑定.

  绑定的意思就是IAT的函数地址 是否是文件一开始就写入. 如果是绑定就是一开始就填写的.否则反之.

二丶绑定导入表

  怎么判断导入表中的 IAT表函数地址是否绑定. 根据 TimeDataStamp进行判断. 0未绑定, -1 绑定. 而真正的绑定时间存放在绑定导入表中.

数据目录的第12项

  绑定导入表结构

typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
DWORD TimeDateStamp;                //真正的时间戳,
WORD OffsetModuleName;              //DLL的名字. PE的文件名
WORD NumberOfModuleForwarderRefs;        //依赖的另外的DLL有几个
// Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;

我们的一个DLL可能依赖其他的DLL. 所以导入表的最后一个成员是依赖的DLL有几个.如果有两个.那么紧跟着下面就是依赖的DLL的绑定导入表结构.

依赖DLL的结构

typedef struct _IMAGE_BOUND_FORWARDER_REF {
DWORD TimeDateStamp;
WORD OffsetModuleName;
WORD Reserved;
} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;

跟绑定导入表是一样的. REF 引用的意思.就是说.我的绑定导入表中依赖的DLL有两个.那么绑定导入表下面.还有两个就是 xxx_REF结构(跟绑定导入表一样)

注意REF结构中第三个成员.,他是用来占位置的.保留的.

OffsetModuleName 成员.这个成员不是RVA 也不是FOA 而是第一个绑定导入表地址 +
OffsetModuleName 这个成员的值.才是一个指针. 这个指针才是真正的文件名所在的位置.
PS: 不管你打印到第几个 永远都是 第一个绑定导入表的值 + OffsetModuleName的值

如何判断这个DLL是否基址改变是否更新. 就是绑定导入表的时间戳 跟 文件头中的时间戳进行对比.如果不一样.就要用重新计算地址.进行填写.

PE知识复习之PE的绑定导入表的更多相关文章

  1. PE知识复习之PE的导入表

    PE知识复习之PE的导入表 一丶简介 上一讲讲解了导出表. 也就是一个PE文件给别人使用的时候.导出的函数  函数的地址 函数名称 序号 等等. 一个进程是一组PE文件构成的.  PE文件需要依赖那些 ...

  2. PE知识复习之PE的导出表

    PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就 ...

  3. PE知识复习之PE的各种头属性解析

    PE知识复习之PE的各种头属性解析 一丶DOS头结构体 typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // M ...

  4. PE知识复习之PE的重定位表

    PE知识复习之PE的重定位表 一丶何为重定位 重定位的意思就是修正偏移的意思.  如一个地址位 0x401234 ,Imagebase = 0x400000 . 那么RVA就是 1234.  如果Im ...

  5. PE知识复习之PE合并节

    PE知识复习之PE合并节 一丶简介 根据上一讲.我们为PE新增了一个节. 并且属性了各个成员中的相互配合. 例如文件头记录节个数.我们新增节就要修改这个个数. 那么现在我们要合并一个节.以上一讲我们例 ...

  6. PE知识复习之PE新增节

    PE知识复习之PE新增节 一丶为什么新增节.以及新增节的步骤 例如前几讲.我们的PE文件在空白区可以添加代码.但是这样是由一个弊端的.因为你的空白区节属性可能是只读的不能执行.如果你修改了属性.那么程 ...

  7. PE知识复习之PE扩大节

    PE知识复习之PE扩大节 一丶为什么扩大节 上面我们讲了,空白区添加我们的代码.但是有的时候.我们的空白区不够了怎么办.所以需要进行扩大节. 扩大节其实很简单.修改节数据对齐后的大小即可. 并且在PE ...

  8. PE知识复习之PE文件空白区添加代码

    PE知识复习之PE文件空白区添加代码 一丶简介 根据上面所讲PE知识.我们已经可以实现我们的一点手段了.比如PE的入口点位置.改为我们的入口位置.并且填写我们的代码.这个就是空白区添加代码. 我们也可 ...

  9. PE知识复习之PE的RVA与FOA的转换

    PE知识复习之PE的RVA与FOA的转换 一丶简介PE的两种状态 首先我们知道PE有两种状态.一种是内存展开.一种是在文件中的状态.那么此时我们有一个需求. 我们想改变一个全局变量的初始值.此时应该怎 ...

随机推荐

  1. 完整版本的推箱子小游戏,最简单的纯C语言打造

    /* 推箱子小游戏 1.定义绘制样式 用二维数组的方式 2.绘制图像 3.找出当前位置 4.逻辑判断,制造动作 根据数学xy轴的规律,这里使用ij 上移,行轴上升,行数减少 下移,行数下降,函数增加 ...

  2. NOIP2008 立体图

    题目描述 小渊是个聪明的孩子,他经常会给周围的小朋友们将写自己认为有趣的内容.最近,他准备给小朋友们讲解立体图,请你帮他画出立体图. 小渊有一块面积为m*n的矩形区域,上面有m*n个边长为1的格子,每 ...

  3. sortable的基本属性

    所有的事件回调函数都有两个参数:event和ui,浏览器自有event对象,和经过封装的ui对象   ui.helper - 表示sortable元素的JQuery对象,通常是当前元素的克隆对象    ...

  4. angular.lowercase()

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. JavaScript 深拷贝(deep copy)和浅拷贝(shallow copy)

    参考: [进阶4-1期]详细解析赋值.浅拷贝和深拷贝的区别 How to differentiate between deep and shallow copies in JavaScript 在编程 ...

  6. c++实验二

    1.函数重载编程练习编写重载函数add(),实现对int型,double型,Complex型数据的加法 #include<iostream> using namespace std; st ...

  7. python面向对象的知识梳理

    面向对象(Object Oriented Programming) 三个基本特征: 1.封装:包含两个概念,对象将变量(状态)和方法(用来改变状态或执行涉及状态的计算)集中在一个地方—即对象本身. 通 ...

  8. 十八、泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器基础加强

    l 泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器 泛型 1 回顾泛型类 泛型类:具有一个或多个泛型变量的类被称之为泛型类. public class A<T> { ...

  9. 约瑟夫环问题 --链表 C语言

    总共有m个人在圆桌上,依次报名,数到第n个数的人退出圆桌,下一个由退出人下一个开始继续报名,循环直到最后一个停止将编号输出 #include <stdio.h>#include <s ...

  10. java字符串应用之字符串编码转换

    [转载]原文地址:https://blog.csdn.net/zhouyong80/article/details/1900100 无论是对程序的本地化还是国际化,都会涉及到字符编码的转换的问题.尤其 ...