0X0 EAT表

在windows系统中,“库”是为了方便其他程序调用而集中包含相关的函数的文件(dll,sys).win32 API是最具有代表性的库。

EAT是一种核心机制,它使不同的应用程序可以调用库文件中提供的函数。也就是说,只有通过EAT表才能准确的求得从相应的库中导出函数的起始地址。

PE文件内的结构体(IMAGE_EXPORT_DIRECTORY)保存着导出信息,且PE文件中仅有一个用来说明库EAT的IMAGE_EXPORT_DIRECTORY结构体

0X01 IMAGE_EXPORT_DIRECTORY结构体

我们可以在PE文件头 IMAGE_EXPORT_DIRECTORY的位置,IMAGE_OPTIONAL_HEADER32.DataDirectory[0].VirtualAddress就是该结构体数组的起始地址。

IMAGE_EXPORT_DIRECTORY 结构体代码如下

typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics; //保留 总是定义为0
DWORD TimeDateStamp; //文件生成时间
WORD MajorVersion; //主版本号 一般不赋值
WORD MinorVersion; //次版本号 一般不赋值
DWORD Name; //模块的真实名称
DWORD Base; //索引基数 加上序数就是函数地址数组的索引值
DWORD NumberOfFunctions; //地址表中个数
DWORD NumberOfNames; //名称表的个数
DWORD AddressOfFunctions; //输出函数地址的RVA
DWORD AddressOfNames; //输出函数名字的RVA
DWORD AddressOfNameOrdinals; //输出函数序号的RVA
} IMAGE_EXPORT_DIRECTORYM, *pIMAGE_EXPORT_DIRECTORY;

IMAGE_EXPORT_DIRECTORY 结构体的重要成员

项目 含义
NumberOfFunctions 实际Export函数的个数
NumberOfNames Export函数中具名函数的个数
AddressOfFunctions Export函数地址数组(数组元素个数=NumberOfFunctions)
AddressOfNames 函数名称地址数组(数组元素个数=NumberOfNames)
AddressOfNameOrdinals Ordinal地址数组(数组元素个数=NumberOfNames)

下图是描述kernel32.dll文件的IMAGE_EXPORT_DIRECTORY 结构体与整个EAT结构

0x02 获取库函数的操作原理

从库中获取函数的API为GetProAddress()函数。该API引用EAT来获取指定API的地址,下面说明GetProAddress()函数的流程。

GetProAddress()操作原理

(1) 首先我们有一个要查找的函数名字fun_name

(2) 通过IMAGE_EXPORT_DIRECTORYM 获得AddressOfNames成员获取函数名称数组。通过比较(strcmp)字符串,查找出指定的函数名称,获取数组的索引值

(3) 通过IMAGE_EXPORT_DIRECTORYM 获得AddressOfNameOrdinals成员获取函数名称数组,将获取的数组索引值作为AddressOfNameOrdinals数组的下标获取相应的值ordinal

(4) 通过IMAGE_EXPORT_DIRECTORYM 获得AddressOfFunctions成员获取函数名称数组。并把ordinal作为AddressOfFunctions数组的下标,获取指定函数的地址

提示

对于没有函数名称的导出函数,可以通过Ordinal查找它们地址。从Ordinal值减去IMAGE_EXPORT_DIRECTORY.Base成员最后一个值,使用该值作为"函数地址数组"(AddressOfFunctions)的索引,即可查找到相应的函数地址。

0x03 使用user32.dll练习

1 查找EAT表的地址

通过PEview查看user32.dll RVA 3900 => RAW 2D00

2 查出来EAT表的RAW为 2D00

EAT结构体中的含义

名称 数据(RVA) RAW
Characteristics 0 0
TimeDateStamp 48025D7A 0
MajorVersion 0000 0
MinorVersion 0000 0
Name 000055C0 49C0
Base 00000001 0
NumberOfFunctions 000002DC 0
NumberOfNames 000002DC 0
AddressOfFunctions 00003928 2D28
AddressOfNames 00004498 3898
AddressOfNameOrdinals 00005008 4408

3 查看函数名称组

AddressOfNames是一个 4个字节RVA组成的数组,AddressOfNameOrdinals是一个2个字节组成的数组,AddressOfFunctions 是由4个字节 函数地址组成的数组

我们查找第一个函数名的地址来演示整个流程 首先找到AddressOfNames 在文件中的首地址RAW 3898

RVA 55CB => RAW 49CB 转换成文件偏移

这个为一个函数,序号为0,下一步需要查找AddressOfNameOrdinals中索引为0中的数据

从数组中取出数据为零,则在AddressOfFunctions 数组查找下标为0的数组

RVA 00018673

用OllDbg查看user32.dll 看到 ImageBase=77D10000

所以该ActivateKeyboardLayout函数的实际地址为 77D10000+18673=77D28673

0x04 寻找函数地址示意图

EAT表的更多相关文章

  1. hook技术分类

    1.HOOK SERVICE TABLE:HOOK SSDT 这种方法对于拦截 NATIVE API 来说用的比较多. SSDT hook,一句话——Windows把需要调用的内核API地址全都存在了 ...

  2. hook 9大类

    HOOK技术主要分为两大类,一是内核层HOOK,一是用户层HOOK. 用户层HOOK也就是在ring3环境下hook kenerl32.dll.User3.dll.Gui32.dll.Advapi.d ...

  3. Hook基本知识

    一.什么是HOOK(钩子) Windows系统,建立在事件驱动机制上,就是整个系统都是通过消息传递实现的.hook(钩子)是一种特殊的消息处理机制,它可以监视系统或者进程中的各种事件消息,截获发往目标 ...

  4. 逆向-PE导出表

    PE-导出表 ​ 动态链接库要想给别人用实现加载时或运行时链接就必须提供函数和数据的地址.exe一般不会有这个,大部分是DLL文件的.导出分为名字导出和序号导出. 名字导出先找名字,再通过名字表的索引 ...

  5. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  6. 临时表VS表变量--因地制宜,合理使用

    一直以来大家对临时表与表变量的孰优孰劣争论颇多,一些技术群里的朋友甚至认为表变量几乎一无是处,比如无统计信息,不支持事务等等.但事实并非如此.这里我就临时表与表变量做个对比,对于大多数人不理解或是有歧 ...

  7. AngularJS系列:表单全解(表单验证,radio必选,三级联动,check绑定,form提交验证)

    一.查看$scope -->寻找Form控制变量的位置 Form控制变量 格式:form的name属性.input的name属性.$... formName.inputField.$pristi ...

  8. jQuery表单验证以及将表单序列化为json对象小练习

    jquery表单验证(非实时验证),同时,将表单序列化为json对象提交表单. <!DOCTYPE html> <html lang="en"> <h ...

  9. EAT/IAT Hook

    标 题: EAT/IAT Hook 作 者: Y4ng 时 间: 2013-08-21 链 接: http://www.cnblogs.com/Y4ng/p/EAT_IAT_HOOK.html #in ...

随机推荐

  1. Spring 框架的 AOP 简介

    Spring 框架的 AOP Spring 框架的一个关键组件是面向方面的编程(AOP)(也称为面向切面编程)框架. 面向方面的编程需要把程序逻辑分解成不同的部分称为所谓的关注点. 跨一个应用程序的多 ...

  2. Verilog代码和FPGA硬件的映射关系(四)

    其实在FPGA的开发中理想情况下FPGA之间的数据要通过寄存器输入.输出,这样才能使得延时最小,从而更容易满足建立时间要求.我们在FPGA内部硬件结构中得知,IOB内是有寄存器的,且IOB内的寄存器比 ...

  3. SpringBoot外部化配置使用Plus版

    本文如有任何纰漏.错误,请不吝指正! PS: 之前写过一篇关于SpringBoo中使用配置文件的一些姿势,不过嘛,有句话(我)说的好:曾见小桥流水,未睹观音坐莲!所以再写一篇增强版,以便记录. 序言 ...

  4. [工具推荐]003.Tortoisegit使用教程(补充)

    前文介绍:       在前文<[工具推荐]003.Tortoisegit使用教程>中详细介绍了如何使用Tortoisegit的使用,但是大家使用后反映一点,就是每次操作都需要输入账号名和 ...

  5. Mysql索引的基本知识和用处

    2020-05-29 15:38:27 一.索引的优点 1.能大大减少服务器需要扫描的数据量. 2.帮助服务器避免排序和临时表. 3.将随机io变成顺序io. 二.索引的用处 能够快速匹配where条 ...

  6. python九九乘法表程序代码

    按照c语言的思路来考虑python的,方法很简单,直接运用双重循环即可,本代码为了代码量少采用的是while嵌套双循环. 取两个随机变量 (1)i和j都从1开始(因为表中最小数值为1) (2)i控制第 ...

  7. 03 . Redis集群

    Redis集群方案 Redis Cluster 集群模式通常具有 高可用.可扩展性.分布式.容错等特性.Redis分布式方案一般有两种 客户端分区方案 客户端 就已经决定数据会被 存储到哪个 redi ...

  8. Ratel源码-C/S事件梳理

    一.Ratel介绍 Ratel 是一个可以在命令行中玩斗地主的项目,可以使用小巧的jar包在拥有JVM环境的终端中进行游戏,同时支持人人对战和人机对战两种模式,丰富你的空闲时间! 二.玩法Demo 三 ...

  9. Bom和Dom对象

    BOM-JavaScript是运行在浏览器中的,所以提供了一系列对象用于和浏览器窗口进行交互,这些对象主要包括window.document.location.navigator和screen等.通常 ...

  10. 关于MySQL无法启动的一点问题

    今天早上做作业启动MySQL遇到服务无法启动的问题,在网上找方法解决找了一个钟. 修改host文件,重装mysql服务,就差卸载重装了.到后面终于找到问题,原来是我之前改了root密码,所以每次启动m ...