自学PE详解(2)导出表 以及疑惑
2020-02-12 00:49:45 Author: bbs.pediy.com(查看原文) 阅读量:160 收藏

[原创]自学PE详解(2)导出表 以及疑惑

4天前 481

下面我们来讲导出表。

 首先还是查找导出表的数据目录所在地,还有导出表的节区起始

首先基本信息贴一张

之前我也发过相关的结构信息了,下面我就直接贴出数据目录导出表的各项信息

这里可以看到RVA是 00099740

然后我们在查看节区信息

然后这个时候我们发现了一个问题 节区.edata是导出表节区。但是我们在PE文件中没有发现.edata节区 该怎么转换成FOA(文件偏移)呢?

很简单,首先我们要根据得到的RVA来判断在那个节区范围以内

我们可以看见 节区.text
内存中大小为    0009F9C7
RVA为               00001000
而我们之前拿到的导出表RVA是 00099740 那么我们就可以判断00099740 >= 00001000 && 00099740 <= 9F9C7 导出表就在节区.text里面

如果遇到这种情况我们就可以根据如下公式将其转换成FOA(文件偏移)

(导出表RVA) -  (节区起始RVA)+ (文件偏移) = FOA
00099740 - 00001000 + 00000400 = 00098B40‬

这是导出表的详细结构 ,不用太在意里面的数值,因为这个查看软件 可能有问题 我们主要看PE文件中的数值这个PE查看器是我用来看结构的。。。。。。

这里重点说几个成员
Number of Functions    函数的实际个数
Names of Names          有名函数的实际个数。(这里解释一下什么叫有名函数个数,就是可以通过函数名查找到的函数个数)
Address Table RVA       这个成员是 函数地址表 是一个数组
Name Pointer Table RVA 这个成员是 函数名表 也是一个数组
Ordinal Table RVA      这个成员是 前面两个数组 的索引  什么意思呢。 打个比方你可以通过Ordinal Table RVA 这个数组里面的值 来 访问对于的函数地址还有函数名 在后面就可以看到。

红线标注的就是比较重要的成员了 当然上面我只介绍了 最重要的成员 同时我们也可以发现上面那个PE文件查看器里面的有一些值还是是对的。

那么下面我们开始 实战

第一个查找到是    这个导出模块的名字 

如上面的图所示 模块名的RVA 是 0009C1AA 转换成 FOA = 9B5AA‬

可以发现 导出模块的名字 是USER32.dll

这里需要说一下 查找的流程 

第一 我们不能通过函数地址 的 索引查找对应索引的 函数名 和 索引表,什么意思呢 比如数组 a[0] 可以访问到正确的成员 ,但是我们能通过这个[0]来访问到其他数组对应的正确成员。

第二 我们要通过函数名 来获得实际的正确的数组下标,然后通过数组下标 访问到正确的索引号。

篇幅有限就不详细的 介绍转换 过程了 直接 上数据

这里查看的成员是 Address Table RVA  导出函数的RVA

下面是成员 Name Pointer Table RVA 

下面是成员Ordinal Table RVA

在这里我们可以发现 明明RVA的地址对不上 为什么 Value 确实相同的呢 ,这是因为 PEview 的原因如果通过硬编码查看的话 会发现 并没有什么关联

这里我们来看一下PE文件就知道了
0009AA64 这是函数名表 转换成FOA 99E64

可以发现 99E64里面保存的 是第一个成员
 09C1E1 转换一下 FOA = 9B5E1‬

查看一下Ordinal 成员 
同样的 0009B9E8 转换成 9ADE8

在这里说一下 Ordinal成员 指向的表 是一个2字节的数组   0003保存 就是函数地址的索引,下面我们就可以通过这个索引来查看相应的函数地址了。

00099768 函数地址RVA 同时转换成 FOA 98b68

选中的就是函数地址数组的 第一个成员 那么我们通过 从Ordinal成员 获得的值 来访问 函数地址数组的成员 数组第一个成员 也就是0 依次往后推,在我用红箭头的地方就是我们要找的函数地址了,RVA = 44970

下面我们通过OD来查看函数地址

这里先查看 模块被加载进内存之后的 新基址

RVA 772d0000 +  44970 = 77314970‬

我们可以发现 这个位置 是一个JMP 继续跟

可以看到这里的JMP  然后我们想继续跟结果发现跟不下去了

我们查一下下一个 地址看看是什么情况

772d0000 + 448a0 = 773148A0‬

可以发现这里就是函数入口地址

导出表到这里就结束了 ,讲得不好,大佬们见笑了。

但是我有一个疑惑,为什么导出表 有一些是定位到一个JMP 位置处 还有一些是直接定位到函数入口点呢

2020安全开发者峰会(2020 SDC)议题征集 中国.北京 7月!

最后于 3天前 被kanxue编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-257548.htm
如有侵权请联系:admin#unsafe.sh