Tuesday, January 21, 2014

As far as I know, .NET platform architecture were similar to JVM's architecture, each .NET assembly or DLL consist of intermediate language (IL) bytecodes similar to JVM bytecode. So in theory, there suppose to be no problem running .NET DLL in x64 platform without using 32-bit support, right?

It turns out the reality is not like that. I recently found out that there is 3 kind of target in Visual Studio Project settings :

Anycpu

x86

x64

For Anycpu, the resulting DLL is loadable in both environment (x86 and x64). The x64 target is only loadable in 64-bit platform. The x86 target would ensure the resulting DLL runs either in 32 bit platform or, in case of physical 64-bit platform, in the WOW64 x86 emulator. This means such DLL would be unable to run in real-64 bit environment, such as in Microsoft IIS with 32-bit app support flag turned off.

The characteristic of such DLL can be determined using Corflags.exe tool :

PE32 : this means 32-bit executable format. This format is readable both in x64 (64 bit) and x86 (a.k.a 32-bit) environments. The opposite : PE32+, the format that only readable in x64 environment
ILONLY : 1 means the DLL only contains IL code. The opposite, 0, means the DLL contains mix of native (32-bit or 64-bit) code modules and IL code module.
32BIT : 0 means the DLL could run both in 64 and 32 bit environments. The opposite, 1, means the DLL must be run in 32 bit environment.

So, even though the DLL consists of only IL code, and no native x86/x64 code, a DLL with 32BIT set to 1 still would refuse to load on x64 platform, resulting in BadImageFormatException. Why on earth someone would want to do that? Well, the DLL might calls functions from a native 32-bit DLL.
But you might want to try to force this DLL to run in 64-bit mode, to see whether it actually need a 32-bit platform or not :