typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics; // 未使用,总为0
    DWORD   TimeDateStamp;      // 文件创建时间戳
WORD MajorVersion; // 未使用,总为0
    WORD    MinorVersion;       // 未使用,总为0
DWORD Name; // 指向一个代表此 DLL名字的 ASCII字符串的 RVA
DWORD Base; // 函数的起始序号
DWORD NumberOfFunctions; // 导出函数的总数
    DWORD   NumberOfNames;      // 以名称方式导出的函数的总数
    DWORD   AddressOfFunctions;     // 指向输出函数地址的RVA
DWORD AddressOfNames; // 指向输出函数名字的RVA
DWORD AddressOfNameOrdinals; // 指向输出函数序号的RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

AddressOfFunctions 所指向内容是以 4 字节为一个单位的数组元素,每个元素代表函数入口

AddressOfNames 所指向内容是以 4 字节为一个单位的数组元素,每个元素代表一个指向字符串的 RVA

AddressOfNamesOrdinals 所指向内容是以 2 字节为一个单位的数组元素,每个元素代表对应名字在 AddressOfFunctions 中的序号数。

AddressOfNames 和 AddressOfNamesOrdinals 的数目肯定是一样的,不是一样那么就出错了。

主要要掌握两种寻找函数入口地址的方法:

A. 从序号查找函数入口地址

1. 定位到PE 文件头
2. 从PE 文件头中的 IMAGE_OPTIONAL_HEADER32 结构中取出数据目录表,并从第一个数据目录中得到导出表的RVA
3. 从导出表的 Base 字段得到起始序号
4. 将需要查找的导出序号减去起始序号Base,得到函数在入口地址表中的索引,检测索引值是否大于导出表的 NumberOfFunctions 字段的值,如果大于后者的话,说明输入的序号是无效的
5. 用这个索引值在 AddressOfFunctions 字段指向的导出函数入口地址表中取出相应的项目,这就是函数入口地址的RVA 值,当函数被装入内存的时候,这个RVA 值加上模块实际装入的基地址,就得到了函数真正的入口地址

B. 从函数名称查找入口地址

我想通的地方,记录下来:用函数名来查找的话,Base 的值现在没有任何意义

1. 首先得到导出表的地址
2. 从导出表的 NumberOfNames 字段得到已命名函数的总数,并以这个数字作为循环的次数来构造一个循环,从 AddressOfNames 字段指向得到的函数名称地址表的第一项开始,在循环中将每一项定义的函数名与要查找的函数名相比较,如果没有任何一个函数名是符合的,表示文件中没有指定名称的函数。
3. 如果某一项定义的函数名与要查找的函数名符合,那么记下这个函数名在字符串地址表中的索引值,然后在AddressOfNamesOrdinals 指向的数组中以同样的索引值取出数组项的值,我们这里假设这个值是 x
4. 最后,以 x 的值作为索引值在 AddressOfFunctions  字段指向的函数入口地址表中获取 RVA 。此 RVA 就是函数的入口地址。

附上图片:

[PE结构分析] 9.导出表 IMAGE_EXPORT_DIRECTORY的更多相关文章

  1. PE文件 02 导出表

    0x01  导出表结构  导出表是由数据目录表中的第一个成员DataDirectory[0]指出的: typedef struct _IMAGE_DATA_DIRECTORY { DWORD Virt ...

  2. [PE]结构分析与代码实现

    PE结构浅析 知识导向: 程序最开始是存放在磁盘上的,运行程序首先需要申请4GB的内存,将程序从磁盘copy到内存,但不是直接复制,而是进行拉伸处理. 这也就是为什么会有一个文件中地址和一个Virtu ...

  3. [PE结构分析] 8.输入表结构和输入地址表(IAT)

    在 PE文件头的 IMAGE_OPTIONAL_HEADER 结构中的 DataDirectory(数据目录表) 的第二个成员就是指向输入表的.每个被链接进来的 DLL文件都分别对应一个 IMAGE_ ...

  4. [PE结构分析] 5.IMAGE_OPTIONAL_HEADER

    结构体源代码如下: typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // +18h WORD Magic; // 标志字, ...

  5. [PE结构分析] 10.基址重定位

    源代码如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD Type ...

  6. [PE结构分析] 7.相对虚拟地址(RVA)和文件偏移间的转换

    RVA是相对虚拟地址(Relative Virtual Address)的缩写.RVA是当PE 文件被装载到内存中后,某个数据位置相对于文件头的偏移量. 例如:导入表的位置和大小可以从PE文件头中IM ...

  7. [PE结构分析] 6.IMAGE_SECTION_HEADER

    IMAGE_SECTION_HEADER 的源代码如下: typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAM ...

  8. PE结构分析(二)

    在表中,我们知道了0x01 4c对应的平台结构是i386: 我们接着分析下一个字段,给出PE结构图 向后推移2个字节,现在来到(图片高亮部分): 高亮部分对应IMAGE_NT_HEADERS结构的Nu ...

  9. [PE结构分析] 11.资源表结构

    资源表是一个树形结构,可以设置成2的31次方的层数,Windows 使用了3级: 类型->名称->语言 其中涉及到四个结构: Data Description Resource Direc ...

随机推荐

  1. Hadoop 生态系统

    1.概述 最近收到一些同学和朋友的邮件,说能不能整理一下 Hadoop 生态圈的相关内容,然后分享一些,我觉得这是一个不错的提议,于是,花了一些业余时间整理了 Hadoop 的生态系统,并将其进行了归 ...

  2. MD5 加密的两种方法

    System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5Cryp ...

  3. 使用before、after伪类制作三角形

    使用before.after伪类实现三角形的制作,不需要再为三角形增加不必要的DOM元素,影响阅读. <!DOCTYPE html><html><head>    ...

  4. 数据人员Sql必会列转行

    列转行上一篇博客已经介绍过了. 下面介绍一下行转列的实现 假设我们有一个数据表: CREATE TABLE row_to_line ( ) NOT NULL, -- 学生名称 yingyu integ ...

  5. preg_match_all正则表达式的基本使用

    了解正则表达式之前,须要掌握一些常用的正则表达式的基础知识,这些如果能记得最好记得,记不住须要用的时候能查到就行,就多个特殊字符,所以说正则表达式玩的就是特殊,具体大家可以查看更加细致的说明. pre ...

  6. wireshark解密本地https流量笔记

    此方式支持firefox,chrome 建立path变量 SSLKEYLOGFILE=c:\ssl.key 重启firefox chrome,访问https网站会自动生成ssl session key ...

  7. managed_shared_memory.construct造成的性能损失

    boost中的IPC进程间通信非常好用,可以直接在共享内存上创建对象,相当于new分配器,实测发现它的分配算法还是有点耗时.第一个测试代码仅仅分配一次,然后频繁的复制,每秒钟可以复制4200次左右. ...

  8. Google Chrome 扩展程序开发

    根据公司的规定,每月八小时,弹性工作制.所以大家平时来的不太准时,如果有事,下班也就早些回去了.所以一个月下来工作时间可能不够,但是公司的考勤日历是这样的: 除了请假和法定节假日外,其他样式显示都是一 ...

  9. 【weka应用技术与实践】过滤器

    weka中的过滤器主要用于数据预处理阶段对数据集的各种操作. 今天简单地使用一下过滤器: 首先打开一个自带数据集weather.numeric.arff,这是一个关于通过天气条件,气温以及风力等因素来 ...

  10. 路由器换大Flash

    使用winhex自建编程器固件(我的是TP-WR941N V6) 1:使用winhex新建一个8M,16M的文件,编辑-全选,填充选块,填充十六进制数值 FF : 2:打开4M的原厂编程器固件(或者自 ...