我在C#中編寫代碼。 我的代碼將運行在Any CPU
模式和提升。在C中檢測特定進程的CPU體系結構#
我的目標是枚舉機器的所有進程與Process.GetProcesses()
,併爲每個進程檢測其CPU架構:,或IA64。
我在C#中實現代碼注入,需要檢測目標進程的體系結構以決定注入哪些操作碼。
如何做到這一點?
謝謝。
我在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