【问题标题】:Win32 API to tell whether a given binary (EXE or DLL) is x86, x64, or ia64Win32 API 来判断给定的二进制文件(EXE 或 DLL)是 x86、x64 还是 ia64
【发布时间】:2010-11-01 14:00:22
【问题描述】:

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

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

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

感谢任何指针。

【问题讨论】:

标签: windows winapi 64-bit 32-bit


【解决方案1】:

对于 EXE

使用GetBinaryType(...)

Here is same question 用于管理的 exe。

对于 DLL(和 EXE)

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

Here is some code我使用谷歌代码搜索找到的

无清理和无错误检查

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

【讨论】:

  • 感谢您的回复。看起来那个特定的 API 会因为 .dll 而失败。
【解决方案2】:

您可以自己检查 PE 标头以读取 IMAGE_FILE_MACHINE 字段。 Here's a C# implementation 适应 C++ 应该不会太难。

【讨论】:

    【解决方案3】:

    我专门开源了a project on Github that checks for VC++ redistributable DLLs,并且我根据Shay 回答successfully finds, loads, and inspects DLLs for x86 / x64 compatibility 中的函数创建了一个代码sn-p。

    完整代码sn-p如下:

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

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

    【讨论】:

      猜你喜欢
      • 2011-09-12
      • 2011-03-10
      • 1970-01-01
      • 2023-03-03
      • 2023-02-09
      • 1970-01-01
      • 2010-10-03
      • 2016-04-17
      • 2010-11-12
      相关资源
      最近更新 更多