首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定PE文件中目录RVA的物理文件地址

确定PE文件中目录RVA的物理文件地址
EN

Stack Overflow用户
提问于 2015-06-12 00:57:54
回答 1查看 1.5K关注 0票数 1

如何确定PE文件中特定数据目录的镜像地址(文件中的字节偏移量)?

例如,给定如下数据目录:

代码语言:javascript
复制
directory  1  RVA: 0x0  Size: 0
directory  2  RVA: 0xaf974  Size: 300
directory  3  RVA: 0xb8000  Size: 22328
directory  4  RVA: 0x0  Size: 0
directory  5  RVA: 0xc0800  Size: 6440
directory  6  RVA: 0xbe000  Size: 27776
directory  7  RVA: 0x91760  Size: 28
directory  8  RVA: 0x0  Size: 0
directory  9  RVA: 0x0  Size: 0
directory 10  RVA: 0x0  Size: 0
directory 11  RVA: 0xa46b8  Size: 64
directory 12  RVA: 0x0  Size: 0
directory 13  RVA: 0x91000  Size: 1736
directory 14  RVA: 0x0  Size: 0
directory 15  RVA: 0x0  Size: 0
directory 16  RVA: 0x0  Size: 0

导入目录(上面的#2)显示为RVA为0xAF974。但是,导入目录不在EXE文件的字节0xAF974处。如何计算写入磁盘的文件中导入目录的字节偏移量?

EN

回答 1

Stack Overflow用户

发布于 2015-06-12 01:07:01

这很有趣!您必须遍历各个部分,以便根据它的虚拟地址找到正确的位置。这是我写的一些代码,在写了很多

我可以试着解释这一点,但是我自己花了很多时间来理解它,而且我已经有几个星期没有看过它了,我已经忘记了很多技术方面的东西。我也在编写一个C++类来处理很多这样的事情

在我的代码缓冲区中有一个指向MapViewOfFile的指针,但它可以是任何字符指针。

代码语言:javascript
复制
/* Example usage...I know not perfect but should help a bit. */
    unsigned char * lpFile = (unsigned char *)(void *)MapViewOfFile(fileMap, FILE_MAP_ALL_ACCESS, 0,0, 0);

    if(lpFile==NULL) {
        printf("Failed to MapViewOfFile\r\n");
        exit(0);
    }

    header_dos = (PIMAGE_DOS_HEADER)lpFile;
    header_nt = (PIMAGE_NT_HEADERS32)&lpFile [header_dos->e_lfanew];

    IMAGE_DATA_DIRECTORY import = header_nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
    PIMAGE_IMPORT_DESCRIPTOR im = (PIMAGE_IMPORT_DESCRIPTOR)&lpFile[RVA2Offset(lpFile, import.VirtualAddress)];


        /* RVA is relative to the section it resides in. */
    int RVA2Offset(unsigned char * buffer, DWORD rva)
    {
        PIMAGE_NT_HEADERS header = (PIMAGE_NT_HEADERS) &buffer[ ((PIMAGE_DOS_HEADER)buffer)->e_lfanew ];
        PIMAGE_SECTION_HEADER section = (PIMAGE_SECTION_HEADER) &buffer[ ((PIMAGE_DOS_HEADER)buffer)->e_lfanew + sizeof(IMAGE_NT_HEADERS) ];

        for(int sectionIndex = 0; sectionIndex < header->FileHeader.NumberOfSections; sectionIndex++) {
            /*
                Check if the RVA is within the virtual addressing space of the section
                Make sure the RVA is less than  the VirtualAddress plus its raw data size
                IMAGE_HEADER_SECTION.VirtualAddress = The address of the first byte of the section when loaded into memory, relative to the image base. For object files, this is the address of the first byte before relocation is applied.
                Our ImageBase is 0, since we aren't loaded into actual memory
            */
            section = (PIMAGE_SECTION_HEADER) &buffer[ ((PIMAGE_DOS_HEADER)buffer)->e_lfanew + sizeof(IMAGE_NT_HEADERS) + (sectionIndex*sizeof(IMAGE_SECTION_HEADER))];

            if (rva >= section->VirtualAddress && (rva <= section->VirtualAddress + section->SizeOfRawData)) {
                /**
                    PointerToRawData gives us the section's location within the file.
                    RVA - VirtualAddress = Offset WITHIN the address space
                **/
                return section->PointerToRawData + (rva - section->VirtualAddress);
            }
        }

        return 0;
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30786961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档