zoukankan      html  css  js  c++  java
  • 第13章:PE文件格式(3)

    EAT

    是一种核心机制,使不同的应用程序可以调用库文件中提供的函数.PE中的结构体Image_Export_Directory保存着导出信息,且只有一个结构体.

    DataDirectory[0]结构体中的第一个元素是地址,第二个是大小.

     有下面几个重要的成员:

    1#.NumberOfFunctions

    实际Export函数的个数.

    2#.NumberOfNames

    Export函数中具名的函数个数.

    3#.AddressOfNames

    函数名称地址数组.

    4.AddressOfFunctions

    Export函数地址数组.

    5#.AddressOfNameOrdinals

    Ordinal地址数组.

    注意这个结构体在notepad.exe中显示是NULL.

    下面展示在kernel.dll中的Image_Export_Directory结构体:

    RVA 地址转换为 FileOffset,262C 转化为 1A2C.

     如图所示:实际Export函数的个数:3b9,函数地址数组的起始地址:2654,函数名称数组的起始地址:3538,Ordinal地址数组:441C.(全是RVA)

    从这里可以知道GetProcAddress()到底是如何工作的了:

    1.在库文件的DataDirectory[0]中找到ExportDirectory,然后找到结构体中的AddressOfNames成员.每一个地址都对应一个函数名(连续的).

    2.通过strcmp()函数对比查找指定的函数名称.

    3.从AddressOfNameOrdinals找到ordinal数组.2字节表示一个ordinal值.将在找名称中拿到的索引值(x)用来查找相应的ordinal值(ordinal[x]).

    4.利用AddressOfFunctions成员转到EAT.4字节为一个地址.用ordinal值用作数组索引查找指定函数的地址.

    注意:若函数没有名称,则ordinal 无法匹配函数名称中的索引值.此时:

    MSDN中写到: GetProcAddress 采用 DLL 模块句柄(由 LoadLibrary 、AfxLoadLibrary 或 GetModuleHandle 返回)作为参数,并采用要调用的函数的名称或函数的导出序号" 因此ordinal是可以直接作为参数传递进去的.就可以找到函数地址.

    书上的一点补充:

     

     

  • 相关阅读:
    ASP.NET编程中非常有用的例子
    打包样式资源
    9.使用类的2个注意点
    面向对象案例
    super必须放到子类this之前
    PHP:根据二维数组中的某个字段进行排序
    Vuex的五个核心属性
    利用按钮控制listview的当前选择项,滚动条跟随动
    c#通过进程名字获取进程路径
    判断客户端是否安装realplayer
  • 原文地址:https://www.cnblogs.com/Rev-omi/p/13194195.html
Copyright © 2011-2022 走看看