How to consistently tell Windows process architecture - windows

I am currently writing a function which given a foreign process handle should use Windows API to find out which architecture is be used (x86, x64, arm, arm64). Throught a combination of GetProcessInformation(ProcessMachineTypeInfo), IsWow64Process2() and IsWow64Process() I am able to query most possible combinations. However, I would like to be able to support all combinations possible on modern windows, starting with the earliest windows 10. A particular problem I have is telling apart x86 and arm applications on 32-bit ARM windows 10. GetProcessInformation(ProcessMachineTypeInfo) is not supported on windows 10 at all, and IsWow64Process2() and IsWow64Process() don't return sensible results in that case either because x86 emulation on arm is not considered WOW.
Is there any way to tell such processes apart using WinAPI on 32-bit windows 10 on ARM?

Related

Is there a programmatic way to determine which application processor architectures are supported?

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.

How can I use DOS interrupts in 32-bit Windows assembly?

So I was writing assembly code in TASM. But now I want to migrate it to MASM and have it run on 32-bit Windows. Can I still keep the DOS interrupts or is there some other way to do it?
I want to ideally run this on Windows 10.
16 bit code from Windows 95 will still run on 32 bit windows at least until windows 7 (I don't have the software to try it on Windows 10).
However for 32 and 64 bit code, you have to start using the win32 api which use the less exciting "call" instruction instead of interrupts.
Simple answer: no, you can't. Under Win32/Win64, calling a DOS interrupt from a Windows program will crash your program with an "Invalid operation" message. Figure out what are you trying to do with DOS interrupts (console output? writing to files?), find corresponding Win32 API functions, and call them.
UPDATE: depends on what are you after. DOS interrupts are only available to DOS executables; Windows executables have to use Windows API. It's entirely possible to make Windows executables in assembly, MASM included, but you'd have to learn new techniques. Building DOS executables is supported in older versions of MASM, but that skillset is rather pointless in today's computing environment. For one thing, the DOS subsystem is slowly but surely going away from Windows - 64-bit versions of Windows don't have it anymore.

Load a 16-bit DLL into a 32-bit Process on Windows 7 64-bit

I wrote a 32-bit application that launches a 16-bit executable, which loads some 16-bit DLLs to perform some of the application's functions. It runs fine on Windows 7 32-bit, but not on Windows 7 64-bit since that version of the OS does not include the NTVDM.
The 16-bit portion of the code is pretty extensive and would be pretty expensive to port to 32-bit. Also, it uses some 3rd-party 16-bit APIs from a company that is no longer in business; therefore, that code would have to be recreated completely, thereby increasing the cost.
Is there any possible way to simply load the existing 16-bit DLLs directly from the 32-bit application, removing the 16-bit executable completely?
I've looked into thunking, but it doesn't appear that is supported in Windows 7 either.
You have to use an emulator or a virtual machine.
Or, if that is not an option then you can write a primitive emulator yourself, read the machinecode instruction-by-instruction and modify fake-registers and memory accordingly, and when the program calls outward then you will have to generate responses.
No. This is not possible in Windows.

porting windows 7 drivers to winXP

Is it possible to manually edit the driver to make it function on windows XP?
I guess there are many differences, but it must be possible for simple drivers, kind of porting the locations / buses they use?
Do you mean without re-compilation? If so its not recommended.
If you are willing to compile then use appropriate WDK and select appropriate build environment and try to build. You may have to change the code depending upon any APIs changed/availability.
Also note that drivers are compiled per OS i.e. there are different build environments for WinXP, Windows 2003, Windows Vista, Windows 7 etc.

Ensuring a Program Written for 32-bit Windows is Compatible with 64-bit Windows

While it's my understanding that there's no fundamental reason a program written for 32-bit hardware / OSs not to run on 64-bit hardware / OSs, in practice, I've found many programs intended for 32-bit versions of Windows that will not work on 64-bit versions of Windows. Examples include a number of popular security utilities (most products from Norton and Check Point's Zone Alarm) and several games (I've been trying to get Grand Theft Auto 4 to run for a few weeks now, but to no avail - of course, that might be related to any number of other problems related to GTA4, but that's neither here nor there).
I've heard that a program's incompatibility might result from something as simple as not wanting to run from the "Program Files (x86)" folder, but what are some of the other reasons? Why would a virus scanner or firewall written for a 32-bit system not run on a 64-bit system? Why would a game not run when everything is theoretically backwards-compatible?
There is a lot of misinformation on this thread.
When a 32-bit application is run on 64-bit windows:
Most of the compatibility problems come when the application tries to install a kernel-mode driver. A 32-bit driver can't be installed on the 64-bit OS. This is amost certainly the problem with a firewall. It's trying to hook into the TCP/IP driver stack.
THERE IS NO EMULATOR! The 32-bit object code is executed by the cpu completely natively at full speed.
There is no support for old 16-bit code. This broke a lot of installers.
Accessing the right folders is generally not a problem. When a 32-bit program opens a file in, say %windir%\system32\, the OS automagically redirects it to %windir%\syswow64. The same for certain parts of the registry. There are a few potential gotchas here, but they're generally along the lines of assuming that various WINAPI Get...Directory() functions return the same strings that they did in Windows 95.
Whether it was compiled 10 years ago or just yesterday, then C/C++ pointers are still 32-bits (4 bytes) and all of the code that just assumed that -- including SendMessage()! -- still works. The 8-byte pointer issue doesn't come into the picture until you start converting to 64-bit compilers.
The best explanation I've found is offered here which basically says 32-bit programs are run on an layer of emulation which doesn't allow the system access you'd get from native programs run in a 64-bit environment:
http://blogs.msdn.com/oldnewthing/archive/2008/12/22/9244582.aspx
I would assume this means that problems with programs like GTA4 come from the layer of emulation not producing the expected results found on a 32-bit native system. This is why you keep seeing Microsoft release compatibility updates all the time.
Here's what the MSDN has to say about the matter:
http://msdn.microsoft.com/en-us/library/bb427430(VS.85).aspx
Drivers are a different story that programs:
http://support.microsoft.com/kb/896456
Zone Alarm uses a special 32-bit driver created by Check Point to do the monitoring. This is probably what's creating the issue with that application. As for Grand Theft Auto 4? I have no idea.
There can be any number of reasons.
Any application which is programmed ad a low level might be expecting 32 bit register. The Zone Alarm driver posted by novatrust is a good example. GTA4 might be using assembly to improve performance at several points which might result on anything or even simply assuming 32 bits on C++. For example take the following code:
struct GPoint
{
int x;
int y;
}
// Array of twenty GPoints
GPoint[] myArr = malloc(20 * sizeof(GPoint);
GPoint* myPointer = myArr;
int index = GetIndexAffectedPoint();
// Invert X and Y for the point
myPointer += 8*index;
swap(myPointer);
I know the example is pretty naive but anyway, in that code you are assuming you're struct is 8 bytes long (4 bytes of the x integer and 4 bytes for the y integer) but in a 64 bit system is actually twice that long so you'll end up swapping the wrong point... things like that happen a lot on low level languages, specially when trying to improve performance...
Security applications are a bad example. They all perform unsupported things against undocumented things. Changes between one 32-bit version of Windows to the next are enough to break them, nevermind moving to 64-bit.
That said, there are some compatibility shims that fixup your code on 32-bit that won't when the app is 64-bit. This is because Microsoft assumes you've tested it on 64-bit.
One resulting gotcha is with .NET applications. When running on a 32-bit system, the exe is jitted to 32-bits - where there are compatibility shims to fix your bugs. If your customer happens to be running on a 64-bit system, the executable will be jitted to 64-bits, where those compatibility shims that were protected you from yourself are no longer present.
Chris Jackson had a nice blog entry about this: Shimming Applications on Windows Vista 64-Bit
The problem is probably drivers. With games, it's probably some kind of slimy DRM scheme. Try getting the no-CD crack for the game so you can run it without DRM.
32-bit to 64-bit Migration Considerations
EDIT: Alternative link
If you are using the file system or the registry, make sure that you access the right folders. As a x86 program you will probably want to access "Program Files (x86)", "SysWOW64", "WOW6232Node" and such folders instead of the x64 ones.
Products with x86 applications like Norton and Check Point's Zone Alarm fail to run their x86 driver, as the driver needs to x64 to be able to ran by the operating system.

Resources