I am running a .net 5 Windows service process, which cannot be complied to AnyCPU.
For the user compatible reason(some client still use 32 bit Windows), I need to build it to x86 App.
When I try to enum the details of a x64 process on x64 Windows, it said a x86 process cannot do so.
Is there a workaround to get the x64 process's exact running path on x64 Windows?
e.g. running another x64 bit process and communicate with the process to get process info, but it's not graceful way. I wanna know if any better way exists?
Related
I'm writing a set of PowerShell functions that could theoretically be running in an x86, AMD64, ARM, or ARM64 PowerShell process. The script function will launch a specified executable, but first I'd like to check if the executable's "machine type" is actually supported by the current Windows installation.
Examples:
Windows Server 2019 can have its WOW64 compatibility layer removed - I'd like to detect that WOW64 is unavailable before attempting to launch an x86 EXE
Windows 10 on ARM64 supports x86, ARM, and ARM64 executables at the time of writing, but Microsoft is reportedly working on AMD64 (x64) application support through an extension of the WOW subsystem. So, in some future release of Windows, Windows 10 on ARM64 will support AMD64 applications.
Rather than hardcoding a bunch of checks, is there a way to determine whether the native OS or its WOW subsystem can run a given executable?
Ignoring the specifics of the PowerShell language and using pseudocode, the ideal function would be something like:
IsProcessorArchitectureAvailable(strProcessorArchitecture)
strProcessorArchitecture would be "x86", "AMD64", "ARM", or "ARM64"
The function would return True if applications that use the specified processor architecture can run, False otherwise.
Is there a way to do this?
The IsWow64GuestMachineSupported API can be used to determine if WOW64 is turned off or not:
Apps that need to determine if WOW64 is turned off or not. For example,
many apps assume x86-64 systems can always execute x86-32 code at all
times, everywhere. Note that this ability does not exist on WinPE or
Xbox, and it is an optional component in Server.
Using this API you can also check for ARM architectures, see Image File Machine Constants.
There is also IsWow64Process2 which returns the native architecture of the host system.
To call these API's you would need to P/Invoke with C# from PowerShell.
Full C# Example can be found here and PowerShell example here.
I'm trying to debug a 32 bit program on 64 bit Windows 7.
So I use gflags to set the debugger for that app. I fill in the path of the application, and the one of the debugger. But when I start the application, WinDBG doesn't run.
The same configuration works on 32 bit Windows 7.
So, is it impossible to debug a 32 bit application on 64 bit environment?
For me this has always worked, even if I use the "wrong" architecture gflags.
However Windbg must be in the PATH, or you must include path when you specify the debugger to gflags.
UPDATE
This is an old question. Older versions of gflags used to store the settings in one of the locations:
HTML\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
or
HTML\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Depending on which architecture you pick for gflags.exe, it will affect either 64 bit or 32 bit processes.
Apparently at some point (thanks, #Thomas Weller to point it out), Microsoft changed gflags behavior and now (November 2016) current version of gflags.exe writes to both 32-bit and 64-bit registry locations, irrespective of the architecture.
This is a bit of a problem, because I used to use to attach 32-bit debugger to 32-bit processes and 64-bit debugger to 64 bit processes with the same process name. Now I cannot use gflags for this. However the workaround is to directly modify registry keys under Image File Execution Options.
Old Answer
Processor architecture of gflags.exe actually matters. If you use 64-bit version of Windows Debugging tools and launch gflags.exe from there, it will affect behavior of 64-bit applications. Similarly, if you use 32-bit version of Windows Debugging Tools and launch gflags.exe, it will affect 32-bit applications.
32-bit and 64-bit versions could be installed side-by-side. Pay close attention on bitness of application you are debugging and use the same architecture of the debugger/tools.
Attempting to call SetupDiCallClassInstaller from a program compiled in 32 bit mode fails on 64 bit Windows.
Apparently this is by design, but I'd like to know the reason.
According to MSDN:
Device Installations on 64-Bit Systems:
The 32-bit version of the application must check the value returned by UpdateDriverForPlugAndPlayDevices. If the return value is ERROR_IN_WOW64, the 32-bit application is executing on a 64-bit platform and cannot update inbox drivers. Instead, it must call CreateProcess (described in the Windows SDK documentation) to start the 64-bit version of the application. The 64-bit version can then call UpdateDriverForPlugAndPlayDevices, specifying a FullInfPath parameter that identifies the location of the 64-bit versions of all files.
So it looks like any API that is designed to report ERROR_IN_WOW64 is specifically intended NOT to work in WOW64, a 32bit process has to invoke a 64bit process to call the API.
If you are making that call from a 32bit process on a 64bit OS, it fails because it has to modify some registry keys in the 64bit portion of the registry. Where else if you were to make that call from a 64bit process on a 64bit OS, it would succeed likewise with 32bit process on a 32bit OS.
Here's my scenario: the company I work has applications deployed to a 32bit Windows 2003 server and they want to move to a Windows 2008 Server that is 64 bit. It has been noted that these 32bit custom developed applications will not run on a 64 bit machine. I was not aware of this.
I have always thought that 32bit software CAN run on a 64 bit OS and just use the 32bit address. A 64 bit software on the other cannot run on a 32 bit OS. On a 64 bit, one does have to create 64 bit software but can and still also create software that is designed for 32 bit machines.
Can someone please elaborate on this?
In general, 32-bit applications will run under a 64-bit Windows (This is technically called WOW64 - Windows On Windows). This applies to all 64-bit Windows version to date, including Server.
WOW64 processes are marked in task manager with *32, For example: chrome.exe *32. Sysinternals' Process Explorer has a separate column for this: Image Type (64 vs 32-bit).
If the app has components hosted inside other processes, then those components must accommodate processes they're hosted in. Examples:
Shell extensions are hosted in explorer.exe, whose bitness matches the OS' bitness. Therefore, you should compile the extension in both 32- and 64-bit, and register the one matching the OS' bitness during installation.
Kernel-mode driver are hosted in the Kernel, whose bitness also matches the OS' bitness. So, the above applies.
Winsock LSPs (Layered Service Providers) are hosted in all processes, both 64-bit (native) and 32-bit (WOW64). Therefore, you should compile the LSP in both 32- and 64-bit, and register both in their respective catalogs during installation.
There are also considerations regarding file redirection (System32 / SysWOW64 / SysNative) and registry redirection (Wow6432Node), which I will not go into.
In general, 32-bit applications will run under a 64-bit OS. If your app relies on a 32-bit kernel driver (say, a VPN client), then you will have to port to 64-bit.
We are in the process of building a 64bit version of our software, but we use Flash player's OCX control to host Flash in our windows. This OCX file is a 32bit build, do you know if it's possible to host this 32bit version of Flash within our 64bit application?
It's certainly possible... Firefox has 64 bit versions that embed the 32 bit Flash player. On Linux, this is accomplished by nspluginwrapper, which is open source so perhaps you can figure out how they do it. There must be something similar for Windows.
I do not believe that loading 32-bit DLLs into 64-bit processes is supported by Windows. An OCX is a DLL with a different extension.
You need to use some kind of external (COM) host process