windows 用于判断给定二进制文件(EXE 或 DLL)是 x86、x64 还是 ia64 的 Win32 API

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/971689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:36:54  来源:igfitidea点击:

Win32 API to tell whether a given binary (EXE or DLL) is x86, x64, or ia64

windowswinapi64-bit32-bit

提问by user15071

I am trying to find a programmatic way to tell if a binary is x86, x64, or ia64.

我试图找到一种编程方式来判断二进制文件是 x86、x64 还是 ia64。

Platform: Windows. Language: c/c++.

平台:Windows。语言:c/c++。

Background: Before trying to load a third-party dll, I need to find out its bitness.

背景:在尝试加载第三方 dll 之前,我需要找出它的位数。

Appreciate any pointers.

感谢任何指针。

回答by Shay Erlichmen

For EXEs

对于 EXE

use GetBinaryType(...)

使用GetBinaryType(...)

Here is same questionfor manged exe.

这是托管 exe 的相同问题

For DLLs (and EXEs)

对于 DLL(和 EXE)

Use the ImageNtHeader(...)to get the PE data of the file and then check the IMAGE_FILE_HEADER.Machine field.

使用ImageNtHeader(...)获取文件的 PE 数据,然后检查 IMAGE_FILE_HEADER.Machine 字段。

Here is some codeI found using Google Code Search

这是我使用 Google 代码搜索找到的一些代码

No Cleanup and NO error checking

没有清理和没有错误检查

// 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 );

回答by Aaronontheweb

I open-sourced a project on Github that checks for VC++ redistributable DLLsspecifically and there's a code snippet I created based off of the function in Shay's answer that successfully finds, loads, and inspects DLLs for x86 / x64 compatibility.

在 Github 上开源了一个项目,该项目专门检查 VC++ 可再发行 DLL,并且我根据 Shay 的答案中的函数创建了一个代码片段,该函数成功地找到、加载和检查 DLL 的 x86 / x64 兼容性

Full code snippet below:

完整代码片段如下:

/******************************************************************
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;
}

This question and Shay's answer were helpful to me while I was creating this, so I thought I'd post the project here.

这个问题和 Shay 的回答在我创建这个时对我很有帮助,所以我想我会在这里发布这个项目。

回答by yoyoyoyosef

You can check the PE header yourself to read the IMAGE_FILE_MACHINEfield. Here's a C# implementationthat shouldn't be too hard to adapt to C++.

您可以自己检查 PE 标头以读取该IMAGE_FILE_MACHINE字段。 这是一个 C# 实现,它不应该太难适应 C++。