Skip to content

Instantly share code, notes, and snippets.

@BinToss
Last active May 11, 2023 04:40
Show Gist options
  • Save BinToss/aa6a269f5eb58088425cdb5a2341e14e to your computer and use it in GitHub Desktop.
Save BinToss/aa6a269f5eb58088425cdb5a2341e14e to your computer and use it in GitHub Desktop.
Using IsWow64Process2, how do we determine if a process is running natively?
#!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