[PE结构分析] 9.导出表 IMAGE_EXPORT_DIRECTORY

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 就是函数的入口地址。

附上图片:

时间: 2024-11-08 03:19:44

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

[PE结构分析] 5.IMAGE_OPTIONAL_HEADER

结构体源代码如下: typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // +18h WORD Magic; // 标志字, ROM 映像(0107h),普通可执行文件(010Bh) +1Ah BYTE MajorLinkerVersion; // 链接程序的主版本号 +1Bh BYTE MinorLinkerVersion; // 链接程序的次版本号 +1Ch DWORD SizeOfCode; // 所有含代码的节的

[PE结构分析] 6.IMAGE_SECTION_HEADER

IMAGE_SECTION_HEADER 的源代码如下: typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; // 节表名称,如“.text” //IMAGE_SIZEOF_SHORT_NAME=8 union { DWORD PhysicalAddress; // 在文件中的物理地址 DWORD VirtualSize; // 真实长度,这两个值是一个联合结构,可以使用其中的任何一个,一般是取后一

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

源代码如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION; 重定位表是一个数组,这个数组的大小记载在 _IMAGE_OPTIONAL_HEADER 的 .D

PE知识复习之PE的导出表

PE知识复习之PE的导出表 一丶简介 在说明PE导出表之前.我们要理解.一个PE可执行程序.是由一个文件组成的吗. 答案: 不是.是由很多PE文件组成.DLL也是PE文件.如果我们PE文件运行.那么就需要依赖DLL.系统DLL就是Kerner32.dll user32.dll等等.这些都是PE文件. 什么是导出表: 导出表就是当前的PE文件提供了那些函数.给别人用. 举个例子: PE文件相当于一个饭店.那么菜单就是导出表. 导出表解盲: 有人认为exe可执行文件.没有导出表.而DLL有导出表.这

32位PE文件信息查看器(WIN32控制台)

最近重新撸了一遍PE文件的文件格式,这个程序算是复习的产物吧. 说明与警告: 1.只适用于32位PE文件,可以读取符合标准的32位PE文件的DOS头.NT头.节区头.导入表.导出表信息,想要其他功能请在PEFile类中找,没有请留言 2.因为是边复习功能边写的,所以不要纠结程序架构.编码风格.鲁棒性等各种问题,我会再改的 3.翻译可能是不准的,仅供参考 4.所有计数从0开始,程序不对是否越界进行检查 5.转载请注明出处,本人不对引用此源码后程序产生的任何问题负责 单独的PEFile类 class

PE文件结构详解(一)基本概念

PE(Portable Execute) 文件是Windows下可执行文件的总称,常见的有DLL,EXE,OCX,SYS等,事实上,一个文件是否是PE文件与其扩展名无关,PE文件可以是任 何扩展名.那Windows是怎么区分可执行文件和非可执行文件的呢?我们调用LoadLibrary传递了一个文件名,系统是如何判断这个文件是一个合 法的动态库呢?这就涉及到PE文件结构了. PE文件的结构一般来说如下图所示:从起始位置开始依次是DOS头,NT头,节表以及具体的节. DOS头是用来兼容MS-DOS操

【逆向篇】分析一段简单的ShellCode——从TEB到函数地址获取

其实分在逆向篇不太合适,因为并没有逆向什么程序. 在http://www.exploit-db.com/exploits/28996/上看到这么一段最简单的ShellCode,其中的技术也是比较常见的,0day那本书上也提到过,大神都用烂了.不过想来很久没有碰汇编了,就心血来潮,权当温习一下. /* User32-free Messagebox Shellcode for any Windows version ==========================================

栈溢出笔记1.6 地址问题(1)

前面的Shellcode中,我使用的都是自己XP机器上的硬编码地址.不论什么时候在Shellcode中使用硬编码地址都不是个好主意,这一点与动态库的重定位相似,一旦系统环境和程序编译设置发生变化.Shellcode差点儿肯定会失效.因此.我们要找到更好一点的方法. 前面的Shellcode中,我用到了例如以下几个硬编码地址.它们的含义例如以下: 当中.LoadLibraryA的作用比較特殊,我们用它来载入user32.dll库. 如今我们要换掉这些硬编码地址.那么,怎样得到这些API函数的地址呢

Linux之ELF文件初探

对比windowsPE文件与概述 在windows中可执行文件是pe文件格式,Linux中可执行文件是ELF文件,其文件格式是ELF文件格式,在Linux下的ELF文件除了可执行文件(Excutable File),可重定位目标文件(RellocatableObject File).共享目标文件(SharedObjectFile).核心转储文件(Core DumpFile)也都是ELF格式文件. 一个典型的ELF文件大致的结构如下 文件头(ELF Header) 程序头表(Program Hea