WEB开发网
开发学院软件开发VC PE文件格式详解(下) 阅读

PE文件格式详解(下)

 2006-07-20 11:43:35 来源:WEB开发网   
核心提示: 导出数据段,.edata.edata段包含了应用程序或DLL的导出数据,PE文件格式详解(下)(6),在这个段出现的时候,它会包含一个到达导出信息的导出目录,因此在使用之前必须进行转换——函数之中体现了这一点,虽然你可以编写一个类似的函数来决定顺序值或函数入口点,

导出数据段,.edata

.edata段包含了应用程序或DLL的导出数据。在这个段出现的时候,它会包含一个到达导出信息的导出目录。 // WINNT.H
typedef struct _IMAGE_EXPORT_DIRECTORY {
 ULONG Characteristics;
 ULONG TimeDateStamp;
 USHORT MajorVersion;
 USHORT MinorVersion;
 ULONG Name;
 ULONG Base;
 ULONG NumberOfFunctions;
 ULONG NumberOfNames;
 PULONG *AddressOfFunctions;
 PULONG *AddressOfNames;
 PUSHORT *AddressOfNameOrdinals;
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
  
导出目录中的Name域标识了可执行模块的名称。NumberOfFunctions域和NumberOfNames域表示模块中有多少导出的函数以及这些函数的名称。

AddressOfFunctions域是一个到导出函数入口列表的偏移量。AddressOfNames域是到一个导出函数名称列表起始处偏移量的地址,这个列表是由null分隔的。AddressOfNameOrdinals是一个到相同导出函数顺序值(每个值2字节长)列表的偏移量。

三个AddressOf...域是当模块装载时进程地址空间中的相对虚拟地址。一旦模块被装载,那么要获得进程地质空间中的确切地址的话,就应该在相对虚拟地址上加上模块的基地址。可是,在文件被装载前,仍然可以决定这一地址:只要从给定的域地址中减去段头部的虚拟地址(VirtualAddress),再加上段实体的偏移量(PointerToRawData),这个结果就是映像文件中的偏移量了。以下的例子解说了这一技术:

// PEFILE.C
int WINAPI GetExportFunctionNames(LPVOID lpFile, HANDLE hHeap, char **pszFunctions)
{
 IMAGE_SECTION_HEADER sh;
 PIMAGE_EXPORT_DIRECTORY ped;
 char *pNames, *pCnt;
 int i, nCnt;
 /* 获得.edata域中的段头部和指向数据目录的指针 */
 if ((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
   (lpFile, IMAGE_DIRECTORY_ENTRY_EXPORT)) == NULL)
  return 0;
 GetSectionHdrByName (lpFile, &sh, ".edata");
 /* 决定导出函数名称的偏移量 */
 pNames = (char *)(*(int *)((int)ped->AddressOfNames -
  (int)sh.VirtualAddress + (int)sh.PointerToRawData +
  (int)lpFile) - (int)sh.VirtualAddress +
  (int)sh.PointerToRawData + (int)lpFile);
 /* 计算出要为所有的字符串分配多少内存 */
 pCnt = pNames;
 for (i = 0; i < (int)ped->NumberOfNames; i++)
  while (*pCnt++);
 nCnt = (int)(pCnt.pNames);
 /* 在堆上为函数名称分配内存 */
 *pszFunctions = HeapAlloc (hHeap, HEAP_ZERO_MEMORY, nCnt);
 /* 将所有字符串复制到缓冲区 */
 CopyMemory((LPVOID)*pszFunctions, (LPVOID)pNames, nCnt);
 return nCnt;
}
请注意,在这个函数之中,变量pNames是由决定偏移量地址和当前偏移量位置的方法来赋值的。偏移量的地址和偏移量本身都是相对虚拟地址,因此在使用之前必须进行转换——函数之中体现了这一点。虽然你可以编写一个类似的函数来决定顺序值或函数入口点,但是我为什么不为你做好呢?——GetNumberOfExportedFunctions、GetExportFunctionEntryPoints和GetExportFunctionOrdinals已经存在于PEFILE.DLL之中了。

上一页  1 2 3 4 5 6 7 8 9 10  下一页

Tags:PE 文件 格式

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接