2011-01-08 55 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; 
}