本文介绍了解决PE文件中的RVA的导入和导出表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在写一个解析器PE /加载器。
我已成功加载PE文件到内存使用标准的C文件IO,获取有效的DOS和PE头(可选头),以及获得访问PE的部分。
我的下一个目标是获得导出表检索导出的符号。
要做到这一点,我已经使用存储在可选的头的RVA数据字典数组中的索引0(我相信指向导出表),并加入这个地址装入程序存储器PE文件的地址,然后浇铸到这一个有效的出口表头。当我这样做,我转向了空地址和数据。这里是一个小code段;

I am currently writing a PE parser/loader.I have successfully loaded the PE file into memory using standard c file io, retrieved valid DOS and PE headers (the optional header) as well as gaining access to the PE's sections.My next target is to gain access to the Export table to retrieve exported symbols.To do this i have used the RVA stored in the optional headers data-dictionary array at index 0 (which i believe points to the export table) and added this address to the address of the PE file loaded into program memory, then casted this into a valid export table header. I am turning up NULL addresses and data when i do this. here is a small code snippet;

// RVA from optional headers data dictionaries array cast to Export directory type 
  IMAGE_EXPORT_DIRECTORY* ied(
  (IMAGE_EXPORT_DIRECTORY*)((void*)
  ((unsigned char*)buffer + ioh->DataDirectory[0].VirtualAddress)));

我必须使用内存映射的IO正确做到这一点?我在计算地址错了吗?在PE RVA的信息似乎稀疏。
先谢谢了。

Do i have to use memory mapped IO to do this properly? Am i calculating the address wrong? Information on PE RVA's seems sparse.thanks in advance.

推荐答案

我打开我的一个来自我喜欢你检查进口和出口目录(结构时旧项目 IMAGE_DIRECTORY_ENTRY_EXPORT IMAGE_DIRECTORY_ENTRY_IMPORT IMAGE_DIRECTORY_ENTRY_IAT IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT )。我可以在短期解释,你有问题的部分。我指的是一部分,如何找出指针,例如 IMAGE_EXPORT_DIRECTORY PE内部。

I opened one my old project from the time as I like you examined the structure of import and export directories (IMAGE_DIRECTORY_ENTRY_EXPORT, IMAGE_DIRECTORY_ENTRY_IMPORT, IMAGE_DIRECTORY_ENTRY_IAT and IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT). I can in short explain the part where you have a problem. I mean the part how to find out the pointer to for example IMAGE_EXPORT_DIRECTORY inside of PE.

所有的原因,可以使用读/写文件操作来分析PE文件,但它更容易使用像下列文件映射的第一

First of all of cause it is possible to use Read/Write file operations to analyse a PE file, but it is much easier to use file mapping like following:

hSrcFile = CreateFile (pszSrcFilename, GENERIC_READ, FILE_SHARE_READ,
                       NULL, OPEN_EXISTING, 0, NULL);
hMapSrcFile = CreateFileMapping (hSrcFile, NULL, PAGE_READONLY, 0, 0, NULL);
pSrcFile = (PBYTE) MapViewOfFile (hMapSrcFile, FILE_MAP_READ, 0, 0, 0);

之后,我们有指针 pSrcFile 这点PE文件包含我们可以找到另一个重要场所内PE的:

after we have the pointer pSrcFile which point to the PE file contain we can find another important places inside of PE:

pDosHeader = (IMAGE_DOS_HEADER *)pSrcFile;
IMAGE_NT_HEADERS32 *pNtHdr = (IMAGE_NT_HEADERS32 *)
    ((PBYTE)pDosHeader + pDosHeader->e_lfanew);
IMAGE_SECTION_HEADER *pFirstSectionHeader = (IMAGE_SECTION_HEADER *)
    ((PBYTE)&pNtHdr->OptionalHeader +
     pNtHdr->FileHeader.SizeOfOptionalHeader);

现在我们都需要的任何目录的虚拟地址。例如,

Now we have all needed virtual address of any directory. For example,

pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress

是导出目录的虚拟地址。之后,虚拟地址转换成内存指针,我们应该找出里面有这个虚拟地址的PE栏目。要做到这一点,我们可以列举PE的部分,并找到 I 磨碎或等于 0 和小于 pNtHdr-> FileHeader.NumberOfSection s其中

is a virtual address of export directory. After that to convert the virtual address to the memory pointer, we should find out the section of PE which has this virtual address inside. To do this we can enumerate sections of PE and find an i grater or equal to 0 and less then pNtHdr->FileHeader.NumberOfSections where

pFirstSectionHeader[i].VirtualAddress <= 
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress

和在同一时间

pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
< pFirstSectionHeader[i].VirtualAddress + pFirstSectionHeader[i].Misc.VirtualSize

,那么你应该在部分搜索数据导出 pFirstSectionHeader [I]

IMAGE_SECTION_HEADER *pSectionHeader = &pFirstSectionHeader[i];
IMAGE_EXPORT_DIRECTORY *pExportDirectory =
   (IMAGE_EXPORT_DIRECTORY *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
    pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress -
    pSectionHeader->VirtualAddress);

您应该重复发现同样的程序(IMAGE_IMPORT_DESCRIPTOR *)相当于 IMAGE_DIRECTORY_ENTRY_IMPORT (IMAGE_BOUND_IMPORT_DESCRIPTOR *)相当于 IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 来转储信息导入包含绑定信息(如果存在的话)。

The same procedure you should repeat to find (IMAGE_IMPORT_DESCRIPTOR *) which corresponds to IMAGE_DIRECTORY_ENTRY_IMPORT and (IMAGE_BOUND_IMPORT_DESCRIPTOR *) which corresponds to IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT to dump import information inclusive a binding information (if exist).

要转储从 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 信息(对应于(ImgDelayDescr *)在delayimp.h定义),你应该使用也是从信息 IMAGE_DIRECTORY_ENTRY_IAT (对应于(IMAGE_THUNK_DATA32 *))。

To dump information from IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT (corresponds to (ImgDelayDescr *) defined in delayimp.h) you should use also information from the IMAGE_DIRECTORY_ENTRY_IAT (corresponds to (IMAGE_THUNK_DATA32 *)).

有关PE的更多信息,我建议你http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

For more information about PE I recommend you http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

这篇关于解决PE文件中的RVA的导入和导出表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 12:04