DLL 的导入目录不适用于 64 位 dll

import directory of a DLL does not work on 64bit dll

我正在尝试打印需要为给定 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(并且我 linking 反对 dbghelp.lib 是 32 位)。将目标更改为 x64 显然会给我 linker 错误。但是我没有任何 dbghelp.lib 64 位版本可以 link 反对。那甚至可用吗?我找不到它。

对于将来无意中遇到此问题的任何人post。

如我所料,您需要 link 反对 64 位 dbghelp.lib 并将您的目标平台更改为 x64 以使用 64 位 dll。然而,这不适用于 32 位 dll。

看来您需要有不同的位数程序才能在相应的位数 dll 上工作。

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

工具

对于位数你应该使用 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;