Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing a Cross-Platform (32-bit and 64-bit compatible) Program for Windows (like AnyCPU in .NET)

It's been baffling me how the "AnyCPU" feature in .NET works: It loads the executable as native 32-bit if the system is 32-bit, and as 64-bit if the system is 64-bit (which you can easily confirm with Task Manager). So obviously, this isn't impossible.

The question is, how exactly did Microsoft do this? Windows originally didn't know about the .NET framework, so the Windows PE Loader can't possibly look for any extra features in PE headers for the CLR header; this feature must have been added by some sort of kernel-mode extension. But the .NET framework seems to install no such thing... I'm at a complete loss at how the same executable can be native 32-bit and 64-bit at the same time, especially since a disassembly of mscoree.dll doesn't even show references to undocumented native functions.

Does anyone have any knowledge and/or reasonable guesses as to how this was done? It's obviously possible (so no saying things like "it's not possible"), and it makes me want to try to write a native cross-platform EXE...


Edit:

As a side note, consider how you can't run 32-bit executables in a 64-bit Windows PE environment... there's got to be some way to extend or modify the PE loader with some sort of "plugin", right?

like image 233
user541686 Avatar asked Jan 10 '11 03:01

user541686


2 Answers

Your question is based on a misunderstanding. Here's the mistake:

Windows originally didn't know about the .NET framework

Actually, since Windows XP, Windows IS aware of the .NET executable format. And XP was the first version of Windows to support 64-bits.

So the PE header is marked 32-bit and the native import table references the 32 bit mscoree, which on Windows 2000 and earlier, causes 32-bit .NET to be loaded. DllMain for mscoree starts JITting the application code and modifies the entrypoint for the main application.

Windows XP and later, being aware of the .NET metadata, recognizes that it is AnyCPU and loads the appropriate framework.

Here's probably more than you ever wanted to know about the process.

So no, there is no native AnyCPU exe. Although you can embed a 16-bit DOS program in a 32-bit PE, you can't have a combined 32-bit and 64-bit .exe

like image 161
Ben Voigt Avatar answered Nov 09 '22 23:11

Ben Voigt


You actually can have x64 code in an x86 executable if the system has a WOW64 emulation layer (Windows Vista+, dunno about XP). http://vxheavens.com/lib/vrg02.html

I have tested this technique and it works on Win7 as well as WinVista. I wrote a little stub in assembly to resolve imports and load up some C code that was compiled for AMD64.

Microsoft just says you can't transition back and forth because they might change it, but I doubt this will change until the underlying architecture changes to allow something like 128 bit to run as well... at that point I doubt WOW64 will be around :), WOW128 ftl.

like image 28
sm4rtk1d5wh0sm0k3w33d Avatar answered Nov 10 '22 00:11

sm4rtk1d5wh0sm0k3w33d