简体   繁体   中英

Is there a Win32 function to get the architecture of a DLL?

There is GetBinaryType() for determining if an .exe file is 32-bit or 64-bit, but how can I do this for a .dll file? I want to ensure that a DLL is the right architecture before trying to load it with LoadLibrary() .

if you want use dll for call functions or load resource from it - just try load it. if it was wrong architecture - you got error ERROR_BAD_EXE_FORMAT and dll wil be not loaded. check before this nothing more give. the try load is check already.

if you need check for some other reasons, exist several ways. most correct is next - open file, create image section from it and check section (last operation is undocumented)

HRESULT CheckImage( _In_ PCWSTR lpLibFileName, _Out_ PUSHORT Machine)
{
    HANDLE hFile = CreateFileW(lpLibFileName, FILE_EXECUTE|FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        HANDLE hSection = CreateFileMappingW(hFile, 0, PAGE_EXECUTE_READ|SEC_IMAGE, 0, 0, 0);
        NtClose(hFile);
        if (hSection)
        {
            SECTION_IMAGE_INFORMATION sii;
            NTSTATUS status = ZwQuerySection(hSection, SectionImageInformation, &sii, sizeof(sii), 0);
            NtClose(hSection);

            *Machine = sii.Machine;

            return status ? HRESULT_FROM_NT(status) : S_OK;
        }
    }
    return HRESULT_FROM_WIN32(GetLastError());
}

you got or some error from this func (file not found, bad image, etc) or some IMAGE_FILE_MACHINE_* . usually IMAGE_FILE_MACHINE_AMD64 or IMAGE_FILE_MACHINE_I386

another way - use LoadLibraryExW with LOAD_LIBRARY_AS_DATAFILE and check IMAGE_NT_HEADERS of mapped image - really this way do all what first (including ZwQuerySection call internally) + mapped dll to memory - last is not need. so this is less efficient way.

HRESULT CheckImage2( _In_ PCWSTR lpLibFileName, _Out_ PUSHORT Machine)
{
    if (HMODULE hmod = LoadLibraryExW(lpLibFileName, 0, LOAD_LIBRARY_AS_DATAFILE))
    {
        HRESULT hr = S_OK;

        if (PIMAGE_NT_HEADERS pinth = RtlImageNtHeader(PAGE_ALIGN(hmod)))
        {
            *Machine = pinth->FileHeader.Machine;
        }
        else
        {
            hr = HRESULT_FROM_NT(STATUS_INVALID_IMAGE_NOT_MZ);
        }
        FreeLibrary(hmod);

        return hr;
    }
    return HRESULT_FROM_WIN32(GetLastError());
}

else one way - direct read file and check it headers. this from one side is fastest, from another side - even if headers is correct - no guarantee that whole file is ok and not corrupted

HRESULT CheckImage3( _In_ PCWSTR lpLibFileName, _Out_ PUSHORT Machine, _Out_ PBOOL Is64Bit)
{
    HANDLE hFile = CreateFileW(lpLibFileName, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    
    if (hFile != INVALID_HANDLE_VALUE)
    {
        HRESULT hr = HRESULT_FROM_NT(STATUS_INVALID_IMAGE_NOT_MZ);

        union {
            IMAGE_DOS_HEADER idh;
            IMAGE_NT_HEADERS inth;
        };

        OVERLAPPED ov {};

        ULONG dwBytesRead;
        if (ReadFile(hFile, &idh, sizeof(idh), &dwBytesRead, &ov))
        {
            if (dwBytesRead == sizeof(idh) && idh.e_magic == IMAGE_DOS_SIGNATURE)
            {
                hr = HRESULT_FROM_NT(STATUS_INVALID_IMAGE_FORMAT);

                ov.Offset = idh.e_lfanew;

                if (ReadFile(hFile, &inth, sizeof(inth), &dwBytesRead, &ov))
                {
                    if (dwBytesRead == sizeof(inth) && inth.Signature == IMAGE_NT_SIGNATURE)
                    {
                        switch (inth.OptionalHeader.Magic)
                        {
                        case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
                            *Is64Bit = FALSE;
                            hr = S_OK;
                            break;
                        case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
                            *Is64Bit = TRUE;
                            hr = S_OK;
                            break;
                        }

                        *Machine = inth.FileHeader.Machine;
                    }
                }
            }
        }

        CloseHandle(hFile);

        return hr;
    }

    return HRESULT_FROM_WIN32(GetLastError());
}

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