Detect x86_64 process on ARM64

Win Sider 101 Reputation points
2021-06-23T17:06:11.96+00:00

I need to determine what architecture a process (not my own) is. With IsWow64Process2 I can get the process architecture and the native architecture. The documentation says of pProcessMachine:

The value will be IMAGE_FILE_MACHINE_UNKNOWN if the target process is not a WOW64 process; otherwise, it will identify the type of WoW process.

So my code checks

if (usProcessMachine == IMAGE_FILE_MACHINE_UNKNOWN)  
  usProcessMachine = usNativeMachine;  

This all works great on i686, x86_64, and released ARM64 versions of Windows with i686, x86_64, ARM32, and ARM64 processes.

BUT, on the ARM64 Insider Preview version, which supports x86_64 processes via emulation, IsWow64Process2 returns pProcessMachine = IMAGE_FILE_MACHINE_UNKNOWN, pNativeMachine = IMAGE_FILE_MACHINE_ARM64, just like it does for ARM64 processes. How can I tell the difference between an ARM64 process and and x86_64 process on ARM64 Windows?

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,426 questions
0 comments No comments
{count} votes

Accepted answer
  1. Win Sider 101 Reputation points
    2021-06-25T19:52:42.463+00:00

    It's probably bad form to answer your own question, but the person who answered this for me is not on this forum, so I figured I'd at least provide an update for posterity. Thanks go to Biswa96

    https://github.com/msys2/MINGW-packages/discussions/8991

    Calling GetProcessInformation with ProcessMachineTypeInfo appears to tell me what I want to know, but unfortunately it doesn't seem to be present in 20H2 or 21H1, only in the Insider Preview. So my answer came out something like

      if (!pIsWow64Process2(process, &process_arch, &native_arch))
        return FALSE;
    
      /* The value will be IMAGE_FILE_MACHINE_UNKNOWN if the target process
       * is not a WOW64 process
       */
      if (process_arch == IMAGE_FILE_MACHINE_UNKNOWN)
        {
          struct _PROCESS_MACHINE_INFORMATION
            {
              /* 0x0000 */ USHORT ProcessMachine;
              /* 0x0002 */ USHORT Res0;
              /* 0x0004 */ DWORD MachineAttributes;
            } /* size: 0x0008 */ process_machine_info;
    
          is_wow = FALSE;
          /* However, x86_64 on ARM64 claims not to be WOW64, so we have to
           * dig harder... */
          /*#define ProcessMachineTypeInfo 9*/
          if (pGetProcessInformation &&
              pGetProcessInformation(process, (PROCESS_INFORMATION_CLASS)9,
                &process_machine_info, sizeof(process_machine_info)))
            process_arch = process_machine_info.ProcessMachine;
          else
            process_arch = native_arch;
        }
      else
        {
          is_wow = TRUE;
        }
      return TRUE;
    
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Xiaopo Yang - MSFT 11,496 Reputation points Microsoft Vendor
    2021-06-24T03:12:44.35+00:00

    As everyone knows, The Insider Preview version is not The Public Stable version.
    And According to WOW64 Implementation Details, Perhaps you can Check The Specific Dll Loaded(such as xtajit.dll and wowarmw.dll for ARM64 Machine) Or Environment Variables(such as PROCESSOR_ARCHITECTURE, PROCESSOR_ARCHITEW6432 etc).

    These DLLs, along with the 64-bit version of Ntdll.dll, are the only 64-bit binaries that can be loaded into a 32-bit process. On Windows 10 on ARM, CHPE (Compiled Hybrid Portable Executable) binaries may also be loaded into an x86 32-bit process.