【问题标题】:import directory of a DLL does not work on 64bit dllDLL 的导入目录不适用于 64 位 dll
【发布时间】:2015-10-13 23:35:52
【问题描述】:

我正在尝试打印需要为给定 dll 加载的位数和 dll。

我的代码看起来像这样(简化版;没有错误检查):

fh = CreateFile("my_dll_file.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
fm = CreateFileMapping(fh, NULL, PAGE_READONLY, 0, 0, NULL);
base_pointer = (char *)MapViewOfFile(fm, FILE_MAP_READ, 0, 0, 0);
pe = ImageNtHeader(base_pointer);
oh = pe->OptionalHeader;
mi = oh.Magic;
    switch (mi) {
    case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
        puts("64-bit");
        break;
    case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
        puts("32-bit");
        break;
    default:
        puts("no match bitness\n");
        break;
    }
rva = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
sec = ImageRvaToSection(pe, base_pointer, rva);
sb = (char *)(base_pointer + sec->PointerToRawData);
sa = (char *)(sb - sec->VirtualAddress);
id = (IMAGE_IMPORT_DESCRIPTOR *)(sa + rva);
while (!IsBadReadPtr(id, sizeof(*id)) && id->Name) {
printf("\ndependency \"%s\":\n", (char *)(sa + id->Name));
id++;
}

但这仅适用于 32 位 dll。在 64 位 dll 上尝试时,我的“rva”结果为 0。上面几行中的位数检查工作正常。关于 64 位 dll 可能出了什么问题的任何指针?

编辑: 我想问题可能是我的目标是x86(并且我链接到32位的dbghelp.lib)。将目标更改为 x64 显然会给我链接器错误。但是我没有任何 dbghelp.lib 64 位版本可以链接。这甚至可用。没找到。

【问题讨论】:

  • 在完成对 oh 的分配后,您如何访问 oh.Magic?分配假定 oh 是一个指针 (->),但您使用点 (.) 表示法来访问它的元素 - 这些是不兼容的。另外,当您不再使用mi 时,为什么要将oh.Magic 分配给mi
  • pe->OptionalHeader 给我 'oh' 这是 'IMAGE_OPTIONAL_HEADER' 但不是指针。所以哦。魔法对我来说很好用。就像我说的,这是我的代码的简化版本。我确实将 mi 用于其他目的。

标签: c++ dll dependencies portable-executable


【解决方案1】:

你应该使用 pe->FileHeader.Machine:

switch (pe->FileHeader.Machine) {
case IMAGE_FILE_MACHINE_AMD64:
    puts("64-bit");
    break;
case IMAGE_FILE_MACHINE_I386:
    puts("32-bit");
    break;
default:
    puts("no match bitness\n");
    break;
}

您的无效,因为 IMAGE_OPTIONAL_HEADER 有 2 种不同的变体,具体取决于位数。
所以这应该适用于 rva:

if (pe->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
  rva = ((PIMAGE_OPTIONAL_HEADER32)&pe->OptionalHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
else
  rva = ((PIMAGE_OPTIONAL_HEADER64)&pe->OptionalHeader)->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;

【讨论】:

  • 这是有道理的。谢谢你的回答。
【解决方案2】:

对于将来偶然发现这篇文章的任何人。

正如我所怀疑的,您需要链接 64 位 dbghelp.lib 并将您的目标平台更改为 x64 以使用 64 位 dll。但是,这不适用于 32 位 dll。

看起来你需要有不同的位程序来处理相应的位 dll。

dbghelp.lib 也位于此处: C:\Program Files\Debugging Tools for Windows (x64)\sdk\lib

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-22
    • 2014-08-08
    • 1970-01-01
    • 2022-01-20
    • 2011-03-03
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多