How do I prevent my Win32 process starting on WOW64? - winapi

I've got a Win32 process that is compiled and packaged in both 32-bit (x86) and 64-bit (x64) variants. I'd like the x86 variant to refuse to run on a 64-bit version of Windows (i.e. WOW64).
Is there any way to do this by setting linker flags? If not, what do I need to do?

You can check whether you're running under emulation by calling IsWow64Process.
Note, that you may need to load the function dynamically if you want to support older versions the OS.

Related

Detect OS x86 or x64, when compiled as x86

I developed bootstrap software to start my game. I did this with Go. It was especially important for me to be cross-platform. Also, I didn't want to divide the download links into two as x86 / x64. I wanted to handle everything in one output. That's why I had to compile to x86. When I do this, I cannot properly detect that the operating system is x86 or x64.
In a software compiled as x86, how can i properly detect operating system x86 or x64 (in Go).
This code is not correct when compiled as x86.
const is64Bit = uint64(^uintptr(0)) == ^uint64(0)
On Windows you can call IsWow64Process to determine whether you are a 32-bit process running on a 64-bit OS. Note that it returns false if you are a 64-bit process running on a 64-bit OS, but if you have a 64-bit process running, then you know the OS is 64-bit or it wouldn't run.
Also note that 32-bit Windows is considered obsolete. Microsoft is already phasing out support for 32-bit Windows - they no longer want it to be installed on new computers.
On Linux you can call uname and look at the machine field. Here's a list of possible values. Note that most of them won't be compatible with your program, only i386, i686 and x86_64.

How to bind 64-bit and 32-bit executable into one?

Alright so my idea was some way to bind both 64-bit and 32-bit Windows executables into one application so if it doesn't run the 64-bit version it would then try the 32-bit one.
I was reading up about PE's and learned a little about MS-DOS Real Mode Stub and it says how it invokes an application (usually an error message). But every time I tried to do research about MS-DOS Real Mode Stub it seemed to only show error messages. So my idea was to overwrite the STUB with my 32-bit application.
My self being naive figured when the 32-bit operating system would run the the 64-bit executable it would fail and then run the stub file.
Is there any way to make my executable 32-bit/64-bit independent?
You could not create a single executable file, containing both x86 and x64 code. However you could create separate 32bit and 64bit applications, pack x64 app into the x86 app resources. On the program start you could check, that you are running x64 environment using IsWow64Process then if needed, unpack your x64 version and run it instead
There are fat binaries in MacOS, Linux and DOS (or hybrid DOS-Windows) but not 32 and 64-bit Windows
You can simply compile separate versions of the program, distribute both and then select the required version at run time by a script or another executable
Another way is installing only the desired version at install time. This is used by many programs like CCleaner. The installer is a 32-bit app or a universal one like .NET so that it can run anywhere. If it detects 64-bit Windows then it only installs the 64-bit version, and in the other case only the 32-bit version.
Read more:
Universal binary
Windows 8 fat binary (exe for x86 & ARM)
Windows NT has always been a multi-platform OS, but the binaries are not

Compiling for both x86 and x64

Is it possible to set up the compiler in such a way so it compiles the executable/DLL for both x86 and x64? I mean, one file suitable for both platforms.
I only know of a way to choose the platforms separately, but I want both.
Is it possible?
x86 executable is fully supported on x64 host. E.g. any EXE you compile in 32-bit mode will run without any problems on 32-bit and 64-bit host. If you don't know why you need 64-bit executable, you probably don't, so 32-bit executable alone will suffice.
However, with DLLs it is a different matter. The DLL's architecture (32-bit or 64-bit) must match the executable where the DLL is going to be used. E.g. if you're writing an Explorer extension for x64 Windows, explorer.exe is going to be 64-bit, so your DLL must also be 64-bit, otherwise it cannot be loaded.
There is no way to combine two different architectures into one DLL or EXE on Windows. So you're going to need two DLLs if you need to support both 32-bit and 64-bit hosts.

Why do some programs compiled for x86 do not run under x64, while some do

I have seen that some programs which were written by me and assembled for x86 using ml.exe run fine on my Win 7 x64. I believe this is because of Wow technology.
However, there are some programs (not written by me) which don't run. They give the error that:
The version of this file is not compatible with the version of Windows you're running. Check you computer system infromation to see whether you need an x86 (32-bit) or x64 (64-bit) version of the program, and then contact the software publisher
Is there any way I can modify the EXE of these programs to make it run on Win 7 x64. What is the fundamental difference in these programs which make it different from other programs which run transparently.
They're actually 8- or 16-bit programs. Windows x64 runs in Long Mode, which does not support Virtual 8086 Mode, required for such programs. There is no way to make them work short of recompiling them from source or running them in a virtual machine.
One reason can be combination of .NET and native libraries. .NET libraries are compiled in runtime as x64 (if you don't specify explicitly x86) and native libraries run in x86 mode. it cannot run togehther.
Another reason is access to registry. Depending on used API, x86app in wow64 mode can be forwarded to another part of registry. If the registry access API is inconsistent, it can make a problem.

Compile unmanaged executable for BOTH x86 and x64

Is there any way to compile an EXE file, so that it will run natively in both x86 and x64? Something like: compile both codebases and pack them into a single executable.
I know .NET code could run in "any cpu" mode, but it is not what I want.
A 32-bit executable will run natively on 32-bit and x64 Windows machines. The only way you're going to get x64 execution within a 32-bit PE file is by using an undocumented gate, which I highly doubt anyone uses in practice because it's highly version dependent (and undocumented).
Then again you make it so the 32-bit binary will execute a 64-bit version of the binary and exit if it detects a 64-bit CPU...
You could take the Process Explorer approach. In your 32-bit binary embed the 64-bit binary as a resource. If the 32-bit binary is launched on a 64-bit machine, extract the 64-bit binary and launch that.

Resources