Win32 API, чтобы определить, является ли данный двоичный файл (EXE или DLL) x86, x64 или ia64 - PullRequest
5 голосов
/ 09 июня 2009

Я пытаюсь найти программный способ определить, является ли двоичный файл x86, x64 или ia64.

Платформа: Windows. Язык: c / c ++.

Предыстория: Прежде чем пытаться загрузить сторонний dll, мне нужно выяснить его битность.

Цените любые указатели.

Ответы [ 3 ]

12 голосов
/ 09 июня 2009

Для EXE

использовать GetBinaryType (...)

Вот тот же вопрос для управляемого exe.

Для DLL (и EXE)

Используйте ImageNtHeader (...) , чтобы получить данные PE файла, а затем проверьте поле IMAGE_FILE_HEADER.Machine.

Вот код Я нашел с помощью Google Code Search

Без очистки и проверки ошибок

// map the file to our address space
// first, create a file mapping object
hMap = CreateFileMapping( 
  hFile, 
  NULL,           // security attrs
  PAGE_READONLY,  // protection flags
  0,              // max size - high DWORD
  0,              // max size - low DWORD      
  NULL );         // mapping name - not used

// next, map the file to our address space
void* mapAddr = MapViewOfFileEx( 
  hMap,             // mapping object
  FILE_MAP_READ,  // desired access
  0,              // loc to map - hi DWORD
  0,              // loc to map - lo DWORD
  0,              // #bytes to map - 0=all
  NULL );         // suggested map addr

peHdr = ImageNtHeader( mapAddr );
2 голосов
/ 14 ноября 2013

Я с открытым исходным кодом проект на Github, который специально проверяет распространяемые библиотеки VC ++ , и есть фрагмент кода, который я создал на основе функции из ответа Шэя, что успешно находит, загружает и проверяет DLL для совместимости с x86 / x64 .

Полный фрагмент кода ниже:

/******************************************************************
Function Name:  CheckProductUsingCurrentDirectory
Description:    Queries the current working directory for a given binary.
Inputs:         pszProductFolderToCheck - the product name to look up.
pBinaryArchitecture - the desired processor architecture
of the binary (x86, x64, etc..).
Results:        true if the requested product is installed
false otherwise
******************************************************************/
bool CheckProductUsingCurrentDirectory(const LPCTSTR pszProductBinaryToCheck, Architecture pBinaryArchitecture){
        bool bFoundRequestedProduct = false;

        //Get the length of the buffer first
        TCHAR currentDirectory[MAX_PATH];
        DWORD currentDirectoryChars = GetCurrentDirectory(MAX_PATH, currentDirectory);

        //exit if couldn't get current directory
        if (currentDirectoryChars <= 0) return bFoundRequestedProduct;

        TCHAR searchPath[MAX_PATH];
        //exit if we couldn't combine the path to the requested binary
        if (PathCombine(searchPath, currentDirectory, pszProductBinaryToCheck) == NULL) return bFoundRequestedProduct;

        WIN32_FIND_DATA FindFileData;
        HANDLE hFind= FindFirstFile(searchPath, &FindFileData);

        //exit if the binary was not found
        if (hFind == INVALID_HANDLE_VALUE) return bFoundRequestedProduct;

        HANDLE hFile = CreateFile(searchPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
        if (hFile == INVALID_HANDLE_VALUE) goto cleanup;

        HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, pszProductBinaryToCheck);
        if (hMapping == INVALID_HANDLE_VALUE) goto cleanup;

        LPVOID addrHeader = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
        if (addrHeader == NULL) goto cleanup; //couldn't memory map the file

        PIMAGE_NT_HEADERS peHdr = ImageNtHeader(addrHeader);
        if (peHdr == NULL) goto cleanup; //couldn't read the header

        //Found the binary, AND its architecture matches. Success!
        if (peHdr->FileHeader.Machine == pBinaryArchitecture){
                bFoundRequestedProduct = true;
        }

cleanup: //release all of our handles
        FindClose(hFind);
        if (hFile != INVALID_HANDLE_VALUE)
                CloseHandle(hFile);
        if (hMapping != INVALID_HANDLE_VALUE)
                CloseHandle(hMapping);
        return bFoundRequestedProduct;
}

Этот вопрос и ответ Шэя были полезны для меня, когда я создавал это, поэтому я решил опубликовать проект здесь.

0 голосов
/ 16 июня 2009

Вы можете проверить PE-заголовок самостоятельно, чтобы прочитать поле IMAGE_FILE_MACHINE. Вот реализация C # , которую не должно быть слишком сложно адаптировать к C ++.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...