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

狂风中的少年 提交于 2020-06-17 04:19:31

问题


I am trying to print the bitness and dll's that needs to be loaded for a given dll.

My code looks like this (simplified version;without error checking):

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++;
}

However this only works with 32bit dll's. My 'rva' turns out to be 0 when tried on 64 bit dll. Bitness check in the lines above work fine though. Any pointers on what might be going wrong with 64 bit dll's?

EDIT: I guess the problem might be that my target is x86 (and im linking against dbghelp.lib which is 32bit). Changing the target to x64 obviously gives me linker errors. However I dont have any dbghelp.lib 64 bit version to link against. Is that even available. I couldnt find it.


回答1:


For the bitness you should use 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;
}

Yours didn't work because there are 2 different variants of IMAGE_OPTIONAL_HEADER depending on the bitness.
So this should work for 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:


For anyone who stumbles on this post in future.

As I suspected, you would need to link against 64 bit dbghelp.lib and change your target platform to x64 to work with 64 bit dlls. However this does not work for 32 bit dll's.

Looks like you need to have diff bitness programs to work on respective bitness dll.

Also dbghelp.lib is located here: C:\Program Files\Debugging Tools for Windows (x64)\sdk\lib



来源:https://stackoverflow.com/questions/33024608/import-directory-of-a-dll-does-not-work-on-64bit-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!