名字长了总有XX跟着念 2022-04-27 14:24 采纳率: 77.8%
浏览 28
已结题

读取x64文件的pe结构导入表的问题

rewind(fp);
fread(&DOS_header, sizeof(struct _IMAGE_DOS_HEADER), 1, fp);

    fseek(fp, DOS_header.e_lfanew, 0);
    fread(&nt_header, sizeof(struct _IMAGE_NT_HEADERS), 1, fp);
 psection_header = new IMAGE_SECTION_HEADER[nt_header.FileHeader.NumberOfSections];
    fread(psection_header, nt_header.FileHeader.NumberOfSections * sizeof(struct _IMAGE_SECTION_HEADER), 1, fp);
PIMAGE_NT_HEADERS64 pNTHeader = (PIMAGE_NT_HEADERS64)&nt_header;
        int nSectionNum = pNTHeader->FileHeader.NumberOfSections;
        DWORD Addr = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
        DWORD Size = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size - sizeof(IMAGE_IMPORT_DESCRIPTOR);
        while (Size > 0)
        {
            int nImportOffset = rva_to_raw(psection_header, nSectionNum, Addr);
            if (!nImportOffset) {
                break;
            }
            printf("%p--%p--%p", nSectionNum,Addr, nImportOffset);
            fseek(fp, nImportOffset, SEEK_SET);
            IMAGE_IMPORT_DESCRIPTOR import_table = { 0 };
            fread(&import_table, sizeof(IMAGE_IMPORT_DESCRIPTOR), 1, fp);
            fseek(fp, rva_to_raw(psection_header, nSectionNum, import_table.Name), SEEK_SET);
            char dll_name[300] = { 0 };
            fread(dll_name, 300, 1, fp);
            printf("%s\r\n", dll_name);
            Addr += sizeof(IMAGE_IMPORT_DESCRIPTOR);
            Size -= sizeof(IMAGE_IMPORT_DESCRIPTOR);
        }
// 内存偏移转文件偏移
int rva_to_raw(PIMAGE_SECTION_HEADER pSection, int nSectionNum, int nRva)
{
    int nRet = 0;

    // 遍历节区
    for (int i = 0; i < nSectionNum; i++) {
        // 导出表地址在这个节区内
        if (pSection[i].VirtualAddress <= nRva && nRva < pSection[i + 1].VirtualAddress) {
            // 文件偏移 = 该段的 PointerToRawData + (内存偏移 - 该段起始的RVA(VirtualAddress))
            nRet = nRva - pSection[i].VirtualAddress + pSection[i].PointerToRawData;
            break;
        }
    }

    return nRet;
}

这段代码无法正常输出导入表的dll名称,但是我看Addr 的地址是对的,而且同样的逻辑读取x86文件可以成功获取

  • 写回答

1条回答 默认 最新

  • 关注

    偏移错了

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月27日
  • 已采纳回答 4月27日
  • 修改了问题 4月27日
  • 创建了问题 4月27日