传上第二部分
三、数据目录表
1 数据目录表是干什么的?
用以快速定位PE结构中的其他的结构:输出表、输入表等。数据目录表的大小一般为16(IMAGE_NUMBEROF_DIRECTORY_ENTRIES)个,它的大小由文件头结构中的SizeOfOptionalHeader指定。其结构定义为:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; //偏移量
DWORD Size; //大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
2 数据结构表的成员
0x0) IMAGE_DIRECTORY_ENTRY_EXPORT // Export Directory
0x1) IMAGE_DIRECTORY_ENTRY_IMPORT // Import Directory
0x2) IMAGE_DIRECTORY_ENTRY_RESOURCE // Resource Directory
0x3) IMAGE_DIRECTORY_ENTRY_EXCEPTION // Exception Directory
0x4) IMAGE_DIRECTORY_ENTRY_SECURITY // Security Directory
0x5) IMAGE_DIRECTORY_ENTRY_BASERELOC // Base Relocation Table
0x6) IMAGE_DIRECTORY_ENTRY_DEBUG // Debug Directory
0x7) IMAGE_DIRECTORY_ENTRY_ARCHITECTURE // Architecture Specific Data
0x8) IMAGE_DIRECTORY_ENTRY_GLOBALPTR // RVA of GP
0x9) IMAGE_DIRECTORY_ENTRY_TLS // TLS Directory
0xA) IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG // Load Configuration Directory
0xB) IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT // Bound Import Directory in headers
0xC) IMAGE_DIRECTORY_ENTRY_IAT // Import Address Table
0xD) IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT // Delay Load Import Descriptors
0xE) IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR // COM Runtime descriptor
0xF) Reserved
四、输出表
输出表大多在DLL文件中定义,它存放一组导出的可被其他程序调用的函数。其结构定义为:
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name; //DLL文件名
DWORD Base; //
DWORD NumberOfFunctions; //输出地址表中的条目数
DWORD NumberOfNames; //输出函数名表中的条目数
DWORD AddressOfFunctions; //输出地址表的RVA
DWORD AddressOfNames; //输出函数名表的RVA
DWORD AddressOfNameOrdinals; //输出序数表的RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
得到输出函数地址的过程:
当一个可执行文件输入一个符号(函数名)时,系统先使用名字来查询想得到的符号的输出序数,再通过序数值来获取地址。
五、输入表
输入表存放的是该文件所导入的函数的相关信息。由数据目录表中的IMAGE_DIRECTORY_ENTRY_IMPORT成员指向,并以全0表示结束。其结构定义为:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
//指向输入名称表INT
};
DWORD TimeDateStamp; //
DWORD ForwarderChain; // 转向,为-1时没有转向。
DWORD Name; //输入的DLL名
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
//指向输入地址表IAT
} IMAGE_IMPORT_DESCRIPTOR;
OriginalFirstThunk, FirstThunk都是指向IMAGE_THUNK_DATA结构的数组。IAT中的IMAGE_THUNK_DATA结构扮演着双重角色,如果其值的高位被置位了,则作为一个序数值处理;如果其值高位未被置位,则它将指向IMAGE_IMPORT_BY_NAME的RVA。
IMAGE_THUNK_DATA结构:
typedef struct _IMAGE_THUNK_DATA32 {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA32;
记的比较粗略,如果要详细研究,翻阅前辈们的文章。
三、数据目录表
1 数据目录表是干什么的?
用以快速定位PE结构中的其他的结构:输出表、输入表等。数据目录表的大小一般为16(IMAGE_NUMBEROF_DIRECTORY_ENTRIES)个,它的大小由文件头结构中的SizeOfOptionalHeader指定。其结构定义为:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress; //偏移量
DWORD Size; //大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
2 数据结构表的成员
0x0) IMAGE_DIRECTORY_ENTRY_EXPORT // Export Directory
0x1) IMAGE_DIRECTORY_ENTRY_IMPORT // Import Directory
0x2) IMAGE_DIRECTORY_ENTRY_RESOURCE // Resource Directory
0x3) IMAGE_DIRECTORY_ENTRY_EXCEPTION // Exception Directory
0x4) IMAGE_DIRECTORY_ENTRY_SECURITY // Security Directory
0x5) IMAGE_DIRECTORY_ENTRY_BASERELOC // Base Relocation Table
0x6) IMAGE_DIRECTORY_ENTRY_DEBUG // Debug Directory
0x7) IMAGE_DIRECTORY_ENTRY_ARCHITECTURE // Architecture Specific Data
0x8) IMAGE_DIRECTORY_ENTRY_GLOBALPTR // RVA of GP
0x9) IMAGE_DIRECTORY_ENTRY_TLS // TLS Directory
0xA) IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG // Load Configuration Directory
0xB) IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT // Bound Import Directory in headers
0xC) IMAGE_DIRECTORY_ENTRY_IAT // Import Address Table
0xD) IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT // Delay Load Import Descriptors
0xE) IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR // COM Runtime descriptor
0xF) Reserved
四、输出表
输出表大多在DLL文件中定义,它存放一组导出的可被其他程序调用的函数。其结构定义为:
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name; //DLL文件名
DWORD Base; //
DWORD NumberOfFunctions; //输出地址表中的条目数
DWORD NumberOfNames; //输出函数名表中的条目数
DWORD AddressOfFunctions; //输出地址表的RVA
DWORD AddressOfNames; //输出函数名表的RVA
DWORD AddressOfNameOrdinals; //输出序数表的RVA
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
得到输出函数地址的过程:
当一个可执行文件输入一个符号(函数名)时,系统先使用名字来查询想得到的符号的输出序数,再通过序数值来获取地址。
五、输入表
输入表存放的是该文件所导入的函数的相关信息。由数据目录表中的IMAGE_DIRECTORY_ENTRY_IMPORT成员指向,并以全0表示结束。其结构定义为:
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
//指向输入名称表INT
};
DWORD TimeDateStamp; //
DWORD ForwarderChain; // 转向,为-1时没有转向。
DWORD Name; //输入的DLL名
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
//指向输入地址表IAT
} IMAGE_IMPORT_DESCRIPTOR;
OriginalFirstThunk, FirstThunk都是指向IMAGE_THUNK_DATA结构的数组。IAT中的IMAGE_THUNK_DATA结构扮演着双重角色,如果其值的高位被置位了,则作为一个序数值处理;如果其值高位未被置位,则它将指向IMAGE_IMPORT_BY_NAME的RVA。
IMAGE_THUNK_DATA结构:
typedef struct _IMAGE_THUNK_DATA32 {
union {
PBYTE ForwarderString;
PDWORD Function;
DWORD Ordinal;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA32;
记的比较粗略,如果要详细研究,翻阅前辈们的文章。
682

被折叠的 条评论
为什么被折叠?



