Last active
May 11, 2023 04:40
-
-
Save BinToss/aa6a269f5eb58088425cdb5a2341e14e to your computer and use it in GitHub Desktop.
Using IsWow64Process2, how do we determine if a process is running natively?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!meta | |
{"kernelInfo":{"defaultKernelName":"csharp","items":[{"aliases":[],"name":"csharp"}]}} | |
#!csharp | |
/** Q: Using IsWow64Process2, how do we determine if a process is running natively? | |
A: pProcessMachine will be assigned the UNKNOWN enum value. | |
*/ | |
using System.Runtime.InteropServices; | |
using Microsoft.Win32.SafeHandles; | |
using System; | |
using System.Diagnostics; | |
using System.Diagnostics.CodeAnalysis; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.Versioning; | |
using System.ComponentModel; | |
try | |
{ | |
IsWow64Process2(System.Diagnostics.Process.GetCurrentProcess().SafeHandle, out IMAGE_FILE_MACHINE pProcessMachine, out IMAGE_FILE_MACHINE pNativeMachine); | |
pProcessMachine.ToString().Display(); /** IMAGE_FILE_MACHINE_UNKNOWN */ | |
pNativeMachine.ToString().Display(); /** IMAGE_FILE_MACHINE_AMD64 */ | |
Console.WriteLine($"Process (PID {Environment.ProcessId}) is running natively i.e. not via WoW64? [{pProcessMachine is IMAGE_FILE_MACHINE.IMAGE_FILE_MACHINE_UNKNOWN}]"); | |
/** Process (PID 8832) is running natively i.e. not via WoW64? [True] */ | |
} | |
catch (Exception ex) | |
{ | |
ex.Display(); | |
} | |
internal struct HANDLE | |
{ | |
internal IntPtr Value; | |
public static implicit operator HANDLE(IntPtr v) => new(){ Value = v }; | |
public static implicit operator IntPtr(HANDLE v) => v.Value; | |
} | |
[DebuggerDisplay("{Value}")] | |
public readonly partial struct BOOL : IEquatable<BOOL> | |
{ | |
public readonly int Value; | |
public BOOL(int value) => this.Value = value; | |
public static implicit operator int(BOOL value) => value.Value; | |
public static explicit operator BOOL(int value) => new BOOL(value); | |
public static bool operator ==(BOOL left, BOOL right) => left.Value == right.Value; | |
public static bool operator !=(BOOL left, BOOL right) => !(left == right); | |
public bool Equals(BOOL other) => this.Value == other.Value; | |
public override bool Equals(object obj) => obj is BOOL other && this.Equals(other); | |
public override int GetHashCode() => this.Value.GetHashCode(); | |
public BOOL(bool value) => this.Value = value ? 1 : 0; | |
public static implicit operator bool(BOOL value) => value.Value != 0; | |
public static implicit operator BOOL(bool value) => new BOOL(value); | |
} | |
public enum IMAGE_FILE_MACHINE : ushort | |
{ | |
IMAGE_FILE_MACHINE_AXP64 = 644, | |
IMAGE_FILE_MACHINE_I386 = 332, | |
IMAGE_FILE_MACHINE_IA64 = 512, | |
IMAGE_FILE_MACHINE_AMD64 = 34404, | |
IMAGE_FILE_MACHINE_UNKNOWN = 0, | |
IMAGE_FILE_MACHINE_TARGET_HOST = 1, | |
IMAGE_FILE_MACHINE_R3000 = 354, | |
IMAGE_FILE_MACHINE_R4000 = 358, | |
IMAGE_FILE_MACHINE_R10000 = 360, | |
IMAGE_FILE_MACHINE_WCEMIPSV2 = 361, | |
IMAGE_FILE_MACHINE_ALPHA = 388, | |
IMAGE_FILE_MACHINE_SH3 = 418, | |
IMAGE_FILE_MACHINE_SH3DSP = 419, | |
IMAGE_FILE_MACHINE_SH3E = 420, | |
IMAGE_FILE_MACHINE_SH4 = 422, | |
IMAGE_FILE_MACHINE_SH5 = 424, | |
IMAGE_FILE_MACHINE_ARM = 448, | |
IMAGE_FILE_MACHINE_THUMB = 450, | |
IMAGE_FILE_MACHINE_ARMNT = 452, | |
IMAGE_FILE_MACHINE_AM33 = 467, | |
IMAGE_FILE_MACHINE_POWERPC = 496, | |
IMAGE_FILE_MACHINE_POWERPCFP = 497, | |
IMAGE_FILE_MACHINE_MIPS16 = 614, | |
IMAGE_FILE_MACHINE_ALPHA64 = 644, | |
IMAGE_FILE_MACHINE_MIPSFPU = 870, | |
IMAGE_FILE_MACHINE_MIPSFPU16 = 1126, | |
IMAGE_FILE_MACHINE_TRICORE = 1312, | |
IMAGE_FILE_MACHINE_CEF = 3311, | |
IMAGE_FILE_MACHINE_EBC = 3772, | |
IMAGE_FILE_MACHINE_M32R = 36929, | |
IMAGE_FILE_MACHINE_ARM64 = 43620, | |
IMAGE_FILE_MACHINE_CEE = 49390, | |
} | |
/// <inheritdoc cref="IsWow64Process2(HANDLE, IMAGE_FILE_MACHINE*, IMAGE_FILE_MACHINE*)"/> | |
[SupportedOSPlatform("windows10.0.10586")] | |
public static unsafe void IsWow64Process2(SafeHandle hProcess, out IMAGE_FILE_MACHINE pProcessMachine, out IMAGE_FILE_MACHINE pNativeMachine) | |
{ | |
bool hProcessAddRef = false; | |
try | |
{ | |
fixed (IMAGE_FILE_MACHINE* pProcessMachineLocal = &pProcessMachine) | |
{ | |
fixed (IMAGE_FILE_MACHINE* pNativeMachineLocal = &pNativeMachine) | |
{ | |
HANDLE hProcessLocal; | |
if (hProcess is object) | |
{ | |
hProcess.DangerousAddRef(ref hProcessAddRef); | |
hProcessLocal = (HANDLE)hProcess.DangerousGetHandle(); | |
if ((IsWow64Process2(hProcessLocal, pProcessMachineLocal, pNativeMachineLocal))) | |
return; | |
else throw new Win32Exception(); | |
} | |
else | |
throw new ArgumentNullException(nameof(hProcess)); | |
} | |
} | |
} | |
finally | |
{ | |
if (hProcessAddRef) | |
hProcess.DangerousRelease(); | |
} | |
} | |
/// <summary>Determines whether the specified process is running under WOW64; also returns additional machine process and architecture information.</summary> | |
/// <param name="hProcess">A handle to the process. The handle must have the <b>PROCESS_QUERY_INFORMATION</b> or <b>PROCESS_QUERY_LIMITED_INFORMATION</b> access right. For more information, see <a href="https://docs.microsoft.com/windows/desktop/ProcThread/process-security-and-access-rights">Process Security and Access Rights</a>.</param> | |
/// <param name="pProcessMachine">On success, returns a pointer to an <a href="https://docs.microsoft.com/windows/desktop/SysInfo/image-file-machine-constants">IMAGE_FILE_MACHINE_*</a> value. The value will be <b>IMAGE_FILE_MACHINE_UNKNOWN</b> if the target process is not a <a href="https://docs.microsoft.com/windows/desktop/WinProg64/running-32-bit-applications">WOW64</a> process; otherwise, it will identify the type of WoW process.</param> | |
/// <param name="pNativeMachine">On success, returns a pointer to a possible <a href="https://docs.microsoft.com/windows/desktop/SysInfo/image-file-machine-constants">IMAGE_FILE_MACHINE_*</a> value identifying the native architecture of host system.</param> | |
/// <returns> | |
/// <para>If the function succeeds, the return value is a nonzero value. If the function fails, the return value is zero. To get extended error information, call <a href="/windows/desktop/api/errhandlingapi/nf-errhandlingapi-getlasterror">GetLastError</a>.</para> | |
/// </returns> | |
/// <remarks> | |
/// <para><see href="https://docs.microsoft.com/windows/win32/api//wow64apiset/nf-wow64apiset-iswow64process2">Learn more about this API from docs.microsoft.com</see>.</para> | |
/// </remarks> | |
[DllImport("KERNEL32.dll", ExactSpelling = true, SetLastError = true)] | |
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)] | |
[SupportedOSPlatform("windows10.0.10586")] | |
public static extern unsafe BOOL IsWow64Process2(HANDLE hProcess, IMAGE_FILE_MACHINE* pProcessMachine, [Optional] IMAGE_FILE_MACHINE* pNativeMachine); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment