在C中检测特定进程的CPU体系结构#
我在C#中编写代码。 我的代码将运行在Any CPU
模式和提升。在C中检测特定进程的CPU体系结构#
我的目标是枚举机器的所有进程与Process.GetProcesses()
,并为每个进程检测其CPU架构:,或IA64。
我在C#中实现代码注入,需要检测目标进程的体系结构以决定注入哪些操作码。
如何做到这一点?
谢谢。
你可以尝试的P/Invoke:
BOOL WINAPI IsWow64Process( __in HANDLE hProcess, __out PBOOL Wow64Process);
你要调出的Win32得到这个信息:
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
public static extern bool IsWow64Process(System.IntPtr hProcess, out bool lpSystemInfo);
public bool IsWow64Process(System.Diagnostics.Process process)
{
bool retVal = false;
IsWow64Process(process.Handle, out retVal);
return retVal;
}
调用IsWow64Process(process)
为每个进程会告诉你是否是64或不是。我还没有遇到一种方法来确定一个进程是x64还是IA64,只是它的“比特级”。
您可以输入/调用QueryFullProcessImageName
或GetProcessImageFileName
,然后读取.exe文件的PE标头。
定义:
[DllImport("kernel32.dll")]
internal static extern void GetNativeSystemInfo(ref SystemInfo lpSystemInfo);
[DllImport("kernel32.dll")]
internal static extern void GetSystemInfo(ref SystemInfo lpSystemInfo);
[StructLayout(LayoutKind.Sequential)]
internal struct SystemInfo
{
public ushort wProcessorArchitecture;
public ushort wReserved;
public uint dwPageSize;
public IntPtr lpMinimumApplicationAddress;
public IntPtr lpMaximumApplicationAddress;
public UIntPtr dwActiveProcessorMask;
public uint dwNumberOfProcessors;
public uint dwProcessorType;
public uint dwAllocationGranularity;
public ushort wProcessorLevel;
public ushort wProcessorRevision;
}
internal const ushort ProcessorArchitectureIntel = 0;
internal const ushort ProcessorArchitectureIa64 = 6;
internal const ushort ProcessorArchitectureAmd64 = 9;
internal const ushort ProcessorArchitectureUnknown = 0xFFFF;
GetNativeSystemInfo将返回关于你的机器上运行信息。 GetSystemInfo将返回有关您在其中运行的虚拟化环境的信息(如果没有一个,它将与GetNativeSystemInfo相同)。
即时通讯: 在32位Windows上,您总是会拥有wProcessorArchitecture == ProcessorArchitectureIntel。
在64位Windows上,如果您以32位进程的方式运行,那么您将拥有wProcessorArchitecture == ProcessorArchitectureIntel用于GetSystemInfo,但wProcessorArchitecture == ProcessorArchitectureAmd64用于GetNativeSystemInfo。
如果您是64位Windows上的64位进程,它们显然都是ProcessorArchitectureAmd64。
Alastair是正确的,你不能只调用IsWow64Process,但你也不需要直接调用另一个WinApi函数。这是一个较短的解决方案。
/// <summary>
/// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
/// If the process is running under 32-bit Windows, the value is set to FALSE.
/// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
/// </summary>
[DllImport("kernel32.dll")]
static extern bool IsWow64Process(System.IntPtr aProcessHandle, out bool lpSystemInfo);
/// <summary>
/// Indicates if the process is 32 or 64 bit.
/// </summary>
/// <param name="aProcessHandle">process to query</param>
/// <returns>true: process is 64 bit; false: process is 32 bit</returns>
public static bool Is64BitProcess(System.IntPtr aProcessHandle)
{
bool lIs64BitProcess = false;
if (System.Environment.Is64BitOperatingSystem) {
IsWow64Process(aProcessHandle, out lIs64BitProcess);
}
return lIs64BitProcess;
}
我认为你们都在正确的轨道上,但返回值缺少一个不是操作符。如果你使用的是64位机器,并且进程是WOW64,那么它是一个32位进程(参见上面的注释IsWow64Process)。此外,IsWow64Process返回错误的可能性未被处理。这是一个固定的版本:
/// <summary>
/// TRUE if the process is running under WOW64. That is if it is a 32 bit process running on 64 bit Windows.
/// If the process is running under 32-bit Windows, the value is set to FALSE.
/// If the process is a 64-bit application running under 64-bit Windows, the value is also set to FALSE.
/// </summary>
[DllImport("kernel32.dll", SetLastError=true)]
static extern bool IsWow64Process(System.IntPtr aProcessHandle, out bool isWow64Process);
/// <summary>
/// Indicates if the process is 32 or 64 bit.
/// </summary>
/// <param name="aProcessHandle">process to query</param>
/// <returns>true: process is 64 bit; false: process is 32 bit</returns>
public static bool Is64BitProcess(System.IntPtr aProcessHandle)
{
if (!System.Environment.Is64BitOperatingSystem)
return false;
bool isWow64Process;
if (!IsWow64Process(aProcessHandle, out isWow64Process))
throw new Win32Exception(Marshal.GetLastWin32Error());
return !isWow64Process;
}
如果你正在实现代码注入,你可能会调用很多Win32 APIs?我可能会建议使用C++/CLI来做这件事会容易得多......你最终会得到。就像你用C#编写它们一样,但是你不必去翻译所有的结构,因为C++编译器直接从Win32头文件中为你完成。 – 2011-01-08 19:55:15
+1给Ben。另外不要忘记,1.0/1.1/2.0 CLR无法在该进程中托管2个运行时,因此您需要确定进程是否运行托管代码(或者稍后是否运行不同版本的托管代码)并注入匹配代码(除了4.0以外,最好还有至少2.0版本的代码) – 2011-01-08 21:12:06
@Alexei:不能在同一个进程中同时使用.NET 4和1.0/1.1/2.0吗?因此,如果您总是注入.NET 4代码,那么CLR版本是否已经加载并不重要。 – 2011-01-08 21:16:20