动态连接库要想给别人用实现加载时或运行时连接就必须提供函数和数据的地址。exe通常不会有这个,大部分是DLL文件的。导出分为名字导出和序号导出。windows
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;
Name指向一个ASCII字符串的RVA数组
对应此PE文件输出标的起始序数值(基数)。当经过序数来查询一个导入函数时,这个值从序数里被减去,结果做为导出地址表(EAT)的索引。函数
NumberOfFunctions EAT表中条目数量code
NumberOfNames 导出函数名称表(ENT)里条目数量。和导出序号表数量同样,有的为了避免让看到名字会将名字隐去,只经过序号输出的时候。blog
AddressOfFunctions 导出表函数数组地址(EAT),经过AddressOfNameOrdinals保存的值+base映射过来索引
AddressOfNameOrdinals 和NumberOfNames一一对应(数组索引)里面的值是EAT的索引值(不加base)。字符串
windows自己记载PE过程当中用到的就是LoadLibrary加载DLL并用 GetProcAddress 来获得函数地址从新刷新导入表的。io
也就是说一个不一样名字可能对应着同一个导出函数地址。有的导出函数没有名字只能经过序号来找,序号-base就是AddressOfFunctions 数组的索引,而AddressOfNameOrdinals 里存的值+base就是序号。
class