2011-01-08 64 views
3

我在C#中编写代码。 我的代码将运行在Any CPU模式和提升。在C中检测特定进程的CPU体系结构#

我的目标是枚举机器的所有进程与Process.GetProcesses(),并为每个进程检测其CPU架构:,或IA64

我在C#中实现代码注入,需要检测目标进程的体系结构以决定注入哪些操作码。

如何做到这一点?

谢谢。

+2

如果你正在实现代码注入,你可能会调用很多Win32 APIs?我可能会建议使用C++/CLI来做这件事会容易得多......你最终会得到。就像你用C#编写它们一样,但是你不必去翻译所有的结构,因为C++编译器直接从Win32头文件中为你完成。 – 2011-01-08 19:55:15

+0

+1给Ben。另外不要忘记,1.0/1.1/2.0 CLR无法在该进程中托管2个运行时,因此您需要确定进程是否运行托管代码(或者稍后是否运行不同版本的托管代码)并注入匹配代码(除了4.0以外,最好还有至少2.0版本的代码) – 2011-01-08 21:12:06

+0

@Alexei:不能在同一个进程中同时使用.NET 4和1.0/1.1/2.0吗?因此,如果您总是注入.NET 4代码,那么CLR版本是否已经加载并不重要。 – 2011-01-08 21:16:20

回答

0

你可以尝试的P/Invoke:

BOOL WINAPI IsWow64Process( __in HANDLE hProcess, __out PBOOL Wow64Process); 
1

你要调出的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,只是它的“比特级”。

1

您可以输入/调用QueryFullProcessImageNameGetProcessImageFileName,然后读取.exe文件的PE标头。

2

定义:

[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。

1

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; 
    } 
0

我认为你们都在正确的轨道上,但返回值缺少一个不是操作符。如果你使用的是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; 
}