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

发布于 2024-07-24 02:07:48 字数 137 浏览 4 评论 0原文

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

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

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

感谢任何指点。

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

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

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

Appreciate any pointers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

熟人话多 2024-07-31 02:07:49

我在 Github 上开源了一个专门检查 VC++ 可再发行 DLL 的项目,并且有一个代码我根据 Shay 的答案中的函数创建的代码段 成功查找、加载并检查 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;
}

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

I open-sourced a project on Github that checks for VC++ redistributable DLLs specifically 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.

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.

旧人 2024-07-31 02:07:49

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

You can check the PE header yourself to read the IMAGE_FILE_MACHINE field. Here's a C# implementation that shouldn't be too hard to adapt to C++.

惜醉颜 2024-07-31 02:07:48

对于 EXE,

请使用 GetBinaryType(...)

这是同样的问题对于受管理的 exe。

对于 DLL(和 EXE),

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

这是我使用 Google 代码搜索发现的一些代码

无清理且无错误检查

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

For EXEs

use GetBinaryType(...)

Here is same question for manged exe.

For DLLs (and EXEs)

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

Here is some code I found using Google Code Search

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 );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文