WIN32汇编语言教程:第17章 PE文件 · 17.3 导出表(3)

程序一开始首先从数据目录表获取导出表的地址,然后显示一些文件的信息,如导出表中定义的原始文件名和导出表中的一些字段的值。

接下来程序显示每个导出函数的信息,包括序号、入口地址和函数名称(如果有的话),具体的处理方法如下:

按照NumberOfFunctions的数量循环处理导入函数地址表中的每个项目,在循环中每次用当前项目的索引值在AddressOfNameOrdinals指定的数组中查找,如果索引值没有包括在数组中,表示没有任何已定义的函数名称符合当前的函数入口地址,这时程序将显示“按照序号导出”的信息;如果在数组中找到当前索引值,表明有个函数名称对应当前的函数入口地址,程序记下在数组中找到当前索引的位置,并在AddressOfNames字段定义的函数名地址表的同样位置取出函数名称字符串的RVA,最后以这个RVA得到函数名称字符串并显示出来。

查找时使用的几句代码需要说明一下:

   mov    edi,@lpAddressOfNameOrdinals
   repnz  scasw
   .if    ZERO?  ;找到函数名称
          sub    edi,@lpAddressOfNameOrdinals
          sub    edi,2
         shl    edi,1
          add    edi,@lpAddressOfNames

首先,由于AddressOfNameOrdinals指定的数组是word类型的,所以查找指令用的是scasw而不是scasb或scasd,当查找结束后,如果标志位为0则表示查找成功,这时edi的值指向找到的项目后面一个word的位置,将edi减去数组的基址并减去2(一个word的长度),得到的就是找到的项目的位置偏移。由于这个数组是word类型的,而AddressOfNames指向的数组是dword类型的,所以还要将偏移乘以2来修正一下(使用shl edi,1指令),用修正后的偏移在AddressOfNames表中就可以得到指向函数名称字符串的RVA了。

上页:第17章 PE文件 · 17.3 导出表(2) 下页:第17章 PE文件 · 17.4 资源(1)

第17章 PE文件

版权所有 © 云南伯恩科技 证书:粤ICP备09170368号