gpt4 book ai didi

c# - 托管代码中的 GetBinaryType 给出相反的结果

转载 作者:太空宇宙 更新时间:2023-11-03 15:23:07 26 4
gpt4 key购买 nike

我发现,当从托管代码调用 GetBinaryType 时,我得到的结果与从同一台机器上的 native 代码调用 GetBinaryType 的结果相反。

我从别处借用了编码声明:

    public enum BinaryType : uint
{
SCS_32BIT_BINARY = 0, // A 32-bit Windows-based application
SCS_64BIT_BINARY = 6, // A 64-bit Windows-based application.
SCS_DOS_BINARY = 1, // An MS-DOS – based application
SCS_OS216_BINARY = 5, // A 16-bit OS/2-based application
SCS_PIF_BINARY = 3, // A PIF file that executes an MS-DOS – based application
SCS_POSIX_BINARY = 4, // A POSIX – based application
SCS_WOW_BINARY = 2 // A 16-bit Windows-based application
}

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetBinaryType(
string lpApplicationName,
out BinaryType dwBinType
);

然后将函数调用为

bool is64bit = false;
BinaryType binType = BinaryType.SCS_32BIT_BINARY;
// Figure out if it's 32-bit or 64-bit binary
if (GetBinaryType(phpPath, out binType) &&
binType == BinaryType.SCS_64BIT_BINARY)
{
is64bit = true;
}

对于 32 位 native 二进制文件,GetBinaryType 返回 BinaryType.SCS_64BIT_BINARY (6),对于 64 位 native 二进制文件,返回 BinaryType.SCS_32BIT_BINARY (0)。

为了验证,我编写了一个 native 命令行工具,并针对相同的二进制文件运行它。

PCWSTR rgBinTypes[] = {
L"SCS_32BIT_BINARY", // 0
L"SCS_DOS_BINARY", // 1
L"SCS_WOW_BINARY", // 2
L"SCS_PIF_BINARY", // 3
L"SCS_POSIX_BINARY", // 4
L"SCS_OS216_BINARY", // 5
L"SCS_64BIT_BINARY", // 6
};


int _tmain(int argc, _TCHAR* argv[])
{
DWORD binType;

if (argc < 2)
{
wprintf(L"Usage: %S <binary-path>\n", argv[0]);
goto Cleanup;
}

if (!GetBinaryType(argv[1], &binType))
{
wprintf(L"Error: GetBinaryType failed: %d\n", GetLastError());
goto Cleanup;
}

wprintf(L"Binary type: %d (%s)\n", binType, binType < 7 ? rgBinTypes[binType] : L"<unknown>");

Cleanup:
return 0;
}

命令行工具为 32 位 native 二进制文件正确返回 0 (SCS_32BIT_BINARY),为 64 位 native 二进制文件正确返回 6 (SCS_64BIT_BINARY)。

我发现有人提到了同样的问题,但没有提供答案:https://social.msdn.microsoft.com/Forums/en-US/fc4c1cb4-399a-4636-b3c3-a3b48f0415f8/strange-behavior-of-getbinarytype-in-64bit-windows-server-2008?forum=netfx64bit

还有其他人遇到过这个问题吗?

我意识到我可以在我的托管枚举中翻转定义,但这看起来非常笨拙。

最佳答案

这是 WinAPI 错误/开发人员的疏忽。 You may find this related question useful to read , 和 it's top answer may help you find the appropriate workaround ,

  1. Use a separate 64 bit process, and some IPC, to retrieve the information.

  2. Use WMI to get the module file name.

  3. Use QueryFullProcessImageName.

我最终采用了完全不同的解决方法。 This answer关于 PE 头文件提到了 32 位和 64 位 Windows 可执行文件中的 PE 头文件。您可以完全绕过 WinAPI 检查,并通过以二进制模式读取目标可执行文件并检查它是否与 PE 签名匹配来检查您的目标可执行文件。

遗憾的是,网上没有太多关于该问题的信息。我记得在某个论坛上看到过这个问题,它被明确列为错误,但这是大约 10 年前的事了。我希望在我们讨论这个问题时,更多的人会意识到这一点。

关于c# - 托管代码中的 GetBinaryType 给出相反的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36486618/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com