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

读取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日

悬赏问题

  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题