简体   繁体   中英

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

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.

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;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM