导出表

记录一下对导出表的理解

在DataDirectory的结构数组中,第一个元素记录了导出表的VirtualSize和Size,其中VirtualSize是在内存中的偏移地址。

通过VirtualSize可以找到导出表的位置,导出表记录了文件导出的函数的名称,数量,地址之类的属性。

 

导出表的成员如上图所示。

下面来讲解一下部分成员

1.Base存的是导出函数的起始序号

2.NumberOfFunctions存了导出的函数的个数,但要注意的是个数计算的方式:末端序号减去起始序号

假如导出序号为 1  2  3  4  5,那么NumberOfFunctions存的是5-1=4

又假如导出的序号为 1  2  4  5,那么NumberOfFunction存的也是5-1=4,尽管计算的结果和实际不同

NumberOfFunctions的值不一定会比NumberOfName的值大,因为一个函数可能会有多个名称

3.NumberOfNames存的是以名称导出的函数的个数,函数的导出可以分为两种形式,以名称导出和以序号导出,因为大部分函数的主要功能都可以在名称中体现,所以以序号导出可以实现隐藏的目的

4.AddressOfFunctions存的导出函数地址表的地址,该值是RVA,有时会根据需求转换成FOA,在该地址上的还是地址表,每个单元大小为4个字节,单元的个数为NumberOfFunctions,导出函数地址表的索引是从零开始的,索引的值是导出序号减去Base,每个单元又存了序号所对应的函数的地址,但当出现第二点中的情况是,序号3,索引为3-1=2的内存单元中存的是0。

5.AddressOfNames存的是导出函数名称的地址,也是RVA,根据地址找到的是以名称导出的函数的地址表,其顺序是按照名称ascii码进行的排序,每个内存单元的大小为4个字节,个数为NumberOfNames.

6.AddressOfNameOrdinals存的是以序号表的地址,也是RVA,根据地址找到的是序号表,每个内存单元的大小为2个字节,个数为NumberOfNames,序号表并不是存了所有的导出序号,而是以名称导出的函数的序号再减去Base,它的索引和名称表中的索引是一一对应的关系,要注意三张表的对应关系

7.通过函数名称来查找地址:

  在名称表中通过地址来查找与目标名称相同的名称,并返回索引,根据索引在序号表中查找对应的序号,再把该序号当做函数地址表的索引,其中所存的地址就是所需要的函数地址

8.通过序号来查找地址:
  将该序号的值减去Base,然后直接在函数地址表中将它当作是索引,来得到函数地址

 

posted @ 2021-03-19 17:26  Yanmo  阅读(237)  评论(0)    收藏  举报