好友
阅读权限10
听众
最后登录1970-1-1
|
PE文件结构的optionalheader的结尾出现了一个大数组,这个数组中的每一项都是一个特定的结构,DataDirectory中的每一项都可以用
Directory:数据目录项的索引。
1. #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory
2. #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory
3. #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory
4. #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory
5. #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory
6. #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table
14. #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table
第一项是导出表的地址 ,是一个内存中的rva地址。在文件中要将rva转换为相对应的foa,才能找到导出表在文件上的位置。
导出表是一个记录了dll的名称 ,dll中的函数的名字,序号,地址的清单的一个dll的结构。导出表只的一个。包括3张表。
导出表是用来描述模块中的导出函数的结构,如果一个模块导出了函数,那么这个函数会被记录在导出表中,这样通过GetProcAddress函数就能动态获取到函数的地址。
函数导出的方式有两种,一种是按名字导出,一种是按序号导出。这两种导出方式在导出表中的描述方式也不相同。
1. typedef struct _IMAGE_EXPORT_DIRECTORY {
2. DWORD Characteristics;
3. DWORD TimeDateStamp;
4. WORD MajorVersion;
5. WORD MinorVersion;
6. DWORD Name;
7. DWORD Base;
8. DWORD NumberOfFunctions;
9. DWORD NumberOfNames;
10. DWORD AddressOfFunctions; // RVA from base of image
11. DWORD AddressOfNames; // RVA from base of image
12. DWORD AddressOfNameOrdinals; // RVA from base of image
13. } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
Name:模块的名字。
Base:序号的基数,按序号导出函数的序号值从Base开始递增。
NumberOfFunctions:所有导出函数的数量。
NumberOfNames:按名字导出函数的数量。
AddressOfFunctions:一个RVA,指向一个DWORD数组,数组中的每一项是一个导出函数的RVA,顺序与导出序号相同。
AddressOfNames:一个RVA,依然指向一个DWORD数组,数组中的每一项仍然是一个RVA,指向一个表示函数名字。
AddressOfNameOrdinals:一个RVA,还是指向一个WORD数组,数组中的每一项与AddressOfNames中的每一项对应,表示该名字的函数在AddressOfFunctions中的序号。
序号表只是按名字找时用的,与按序号找没有关系
按名字找:
先循环在名字表找Test这个名字。找到后看是下标索引是3,在序号表找下标索引是3的那个项的值,拿到值是4,再到函数地址表找下标索引是4的地址就是test这个函数的地址了 4+base = 导出序号
按序号找:序号-base 的值为下标索引,直接在函数地址表找下标索引 ,是序号-base 的值 的地址就是test这个函数的地址了 。
|
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|