逆向-PE导出表

PE-导出表

​ 动态连接库要想给别人用实现加载时或运行时连接就必须提供函数和数据的地址。exe通常不会有这个,大部分是DLL文件的。导出分为名字导出和序号导出。windows

  1. 名字导出先找名字,再经过名字表的索引找到AddressOfNameOrdinals里面的值,此值即为name和函数地址关联处,是AddressOfFunctions的索引
  2. 序号导出,序号-base就是AddressOfFunctions索引,直接找就是函数地址。
typedef struct _IMAGE_EXPORT_DIRECTORY {
    DWORD   Characteristics;
    DWORD   TimeDateStamp;
    WORD    MajorVersion;
    WORD    MinorVersion;
    DWORD   Name;
    DWORD   Base;
    DWORD   NumberOfFunctions;
    DWORD   NumberOfNames;
    DWORD   AddressOfFunctions;     // RVA from base of image
    DWORD   AddressOfNames;         // RVA from base of image
    DWORD   AddressOfNameOrdinals;  // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
  1. Name指向一个ASCII字符串的RVA数组

  2. 对应此PE文件输出标的起始序数值(基数)。当经过序数来查询一个导入函数时,这个值从序数里被减去,结果做为导出地址表(EAT)的索引。函数

  3. NumberOfFunctions EAT表中条目数量code

  4. NumberOfNames 导出函数名称表(ENT)里条目数量。和导出序号表数量同样,有的为了避免让看到名字会将名字隐去,只经过序号输出的时候。blog

  5. AddressOfFunctions 导出表函数数组地址(EAT),经过AddressOfNameOrdinals保存的值+base映射过来索引

  6. AddressOfNameOrdinals 和NumberOfNames一一对应(数组索引)里面的值是EAT的索引值(不加base)。字符串

windows自己记载PE过程当中用到的就是LoadLibrary加载DLL并用 GetProcAddress 来获得函数地址从新刷新导入表的。io

也就是说一个不一样名字可能对应着同一个导出函数地址。有的导出函数没有名字只能经过序号来找,序号-base就是AddressOfFunctions 数组的索引,而AddressOfNameOrdinals 里存的值+base就是序号。
class

相关文章
相关标签/搜索