- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我目前正在编写 PE 解析器/加载器。我已经使用标准 c 文件 io 成功地将 PE 文件加载到内存中,检索到有效的 DOS 和 PE header (可选 header )以及获得对 PE 部分的访问权限。我的下一个目标是访问导出表以检索导出的符号。为此,我使用了存储在索引 0 处的可选 header 数据字典数组中的 RVA(我相信它指向导出表)并将该地址添加到加载到程序内存中的 PE 文件的地址,然后将其转换为有效的导出表头。当我这样做时,我正在打开 NULL 地址和数据。这是一个小代码片段;
// 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 的信息似乎很少。提前致谢。
最佳答案
我打开了一个我以前的项目,因为我喜欢你检查导入和导出目录的结构(IMAGE_DIRECTORY_ENTRY_EXPORT
、IMAGE_DIRECTORY_ENTRY_IMPORT
、IMAGE_DIRECTORY_ENTRY_IAT
和 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
)。我可以简而言之解释您遇到问题的部分。我的意思是如何找到指向例如 PE 内部的 IMAGE_EXPORT_DIRECTORY
的指针的部分。
首先,可以使用读/写文件操作来分析 PE 文件,但使用如下文件映射要容易得多:
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);
在我们有了指向 PE 文件的指针 pSrcFile
之后,我们可以在 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);
现在我们拥有了任何目录所需的所有虚拟地址。例如,
pNtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
是导出目录的虚拟地址。之后要将虚拟地址转换为内存指针,我们应该找出PE里面有这个虚拟地址的段。为此,我们可以枚举 PE 的部分并找到大于或等于 0
且小于 pNtHdr->FileHeader.NumberOfSection
的 i
,其中
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_DIRECTORY_ENTRY_IMPORT
的 (IMAGE_IMPORT_DESCRIPTOR *)
和对应于 的
转储包含绑定(bind)信息(如果存在)的导入信息。(IMAGE_BOUND_IMPORT_DESCRIPTOR *)
>IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
要从 IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
(对应于 delayimp.h 中定义的 (ImgDelayDescr *)
)转储信息,您还应该使用来自 IMAGE_DIRECTORY_ENTRY_IAT
的信息(对应于 (IMAGE_THUNK_DATA32 *)
)。
更多PE推荐给你http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
关于c++ - 解析 PE 文件中导入和导出表的 RVA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2975639/
我在使用 Win32 NT header 时遇到问题,因为它给我的导入名称提供了奇怪的 RVA。这是给我问题的相关代码: //Get a pointer to the import table PIM
相对虚拟地址和相对于文件基址的偏移有什么区别? 最佳答案 RVA是相对虚拟地址,即与首选基地址的距离。首选基地址在 PE header 中说明,并且是当可执行文件加载到内存中时内存中图像开始的(首选)
我正在尝试读取 PE 文件。 问题是数据使用 RVA 指针,而我需要在文件中偏移 得到我需要的东西。 如何将 RVA 转换为文件中的偏移量? 最佳答案 要通过 RVA 确定文件偏移量,您需要: 确定在
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我目前正在编写 PE 解析器/加载器。我已经使用标准 c 文件 io 成功地将 PE 文件加载到内存中,检索到有效的 DOS 和 PE header (可选 header )以及获得对 PE 部分的访
Microsoft's documentation对于 PE 可选 header 标准字段(第 25.2.3.1 节)中的“入口点 RVA”字段,该字段应为: RVA of entry point,
A file that is given as input to the linker is called Object File. The linker produces an Image file
我已经成功构建了一个基本的 JAVA 反汇编器,仅仅是因为已经构建的开源反汇编器(pecoff4j 及其分支)尽管非常出色但没有帮助。我已经设法解析所有 PE header ,将其与 Lord PE
从磁盘位置读取 PE 文件时,我需要将 RVA(从 pdb 文件获取的相对虚拟地址)映射到 PE 文件 (EXE) 偏移量。为此,我需要将 RVA 转换为文件偏移量,以便我可以从该位置读出 GUIDS
我正在使用 sounddevice 录制音频,我想通过 pygame 通过虚拟音频线播放它,我一直收到此错误 Exception has occurred: error mpg123_seek: In
我一直在网上搜寻这个问题的答案,但似乎没有找到答案。在提出这个问题之前,我查阅了以下资料。 http://www.csn.ul.ie/~caolan/publink/winresdump/winres
我是一名优秀的程序员,十分优秀!