[Mono-dev] mixed-mode assemblies in wine

Kornél Pál kornelpal at gmail.com
Tue Mar 1 05:11:35 EST 2011


Vincent Povirk wrote:
>> My preferred way would be to call exports that Windows calls:
>> - _CorValidateImage on image load
>> - _CorImageUnloading on image unload
>> - _CorExeMain instead of exe entry point
>> - _CorDllMain instaad of dll entry
> Is there a reason for us to add this to the Wine loader soon? I've
> been putting it off because I have to ask for someone else to do it.

WIndows 2000 does not call any of these and .NET Framework still works, 
so Wine will work as well. The whole idea behind this is to increase 
security when using IL-only assemblies. The assemblies are loaded but no 
native code (not even entry points, TLS initialization) is executed 
neither is the IAT resolved.

_CorValidateImage becomes necessary once you want to load PE32 IL-only 
images into a 64-bit process. CorValidateImage will convert the PE32 
image to PE32+ in memory that is possible (see implementation) and required.

CorValidateImage also removes entry point of PE32+ IL-only dlls since 
IAT was not resolved. This is not required if the loader is not treating 
IL-only dlls specially.

In my opinion these callbacks are quite easy to implement. One unusual 
thing I noticed is that suspended process and CreateRemoteThread dll 
injection is not working for managed processes (maybe just IL-only) 
because _CorExeMain is called by the loader initialization code rather 
than process initialization code so it will be called on the new thread 
instead of thread entry point.

>> I also planned to get rid of MonoFixupExe  and drop support for mixed-mode
>> assemblies by using mono.exe and introduce a loader that would call
>> CreateProcess on the managed (may be mixed-mode) .exe, inject a loader .dll
>> (or a custom mscoree.dll) by modifying IAT, remove IL-only flag so that the
>> OS loader will not load MS.NET mscorlib.dll, and do inicialization in that
>> loader .dll called by OS loader. This would not affect functionality of
>> mono.dll just would not fixup mscoree.dll by default that also would play
>> more nicely with standalone verifier, dumper, etc. tools and CoreCLR.
> That's interesting.
> It would seem (to me) that in this case your mscoree.dll and ours can
> and should be the same one. The only difference is how libmono is
> found and loaded.

.NET Framework has a single shared mscoree.dll in system32 that selects 
and loads the appropriate runtime (mscorwks.dll or mscorsvr.dll for .NET 
Framework 2.0). Each new runtime usually updates mscoree.dll but remains 
backwards compatible. Most exports of mscoree.dll are most likely simply 
forwarded to the loaded runtime.

When experimenting with the above approach I have used my own 
mscoree.dll and loaded Mono and worked fine but this is not the way to 
go on Windows, that's why I have plans to create a loader that would do 
the hooking. The same loader would work on Wine but you will not need it 
as Mono will be your native .NET implementation.

>> I also have the impression that implementing .NET Framework functionality in
>> Wine may not be the right architecture. Ideally those belong to Mono. Since
>> I know that Mono does not accept GPL to runtime (requires MIT X11 license or
>> special permissions to Novell; althoug is licensed under GPL) and Wine
>> prefers GPL this may not be suitable.
>> Wine loader should call mscoree.dll just like Windows loader does
>> (system32\mscoree.dll is hardcoded, cannot use your own).
>> If you prefer to keep mscoree.dll code in Wine, then I belive that Wine
>> mscoree.dll should load mono.dll (as it already does) and forward the above
>> five basic exports to mono.dll and implement other exports on its own by
>> calling native Mono API.
> My only strong reason for wanting mscoree.dll to be in Wine is so that
> it can load without any Mono present (which is enough to install many
> apps, and pass tests), and so that it can select between multiple
> available Mono setups at runtime (in order to cover .NET versions 1.1,
> 2.0, and 4.0 simultaneously). For that to work, we need a dll that
> loads Mono dynamically rather than linking to it, and it needs to
> support both embedding ABI's.

mscoree.dll itself is just a loader and forwarder that can and should 
remain in Wine. (Sorry about not being specific previously.)

I however belive that the actual API implementation should be part of 
Mono because that could be used on Windows as well.

> Licensing is not an issue. Wine is LGPL, and we can use MIT code. The
> reverse isn't true, but I think it would be possible to relicense most
> of Wine's current mscoree code as MIT, since most of that architecture
> was written by me for CodeWeavers.
> Still, if you want to work on the .NET embedding API, I think we
> should find a way to collaborate, in whichever project.

coree.c of Mono was written by me and is already MIT licensed. Mono 
runtime is available under LGPL (I previously have mistaken it for GPL).
As a Mono contributor I may be biased but I belive that the best way to 
collaborate would be to have native .NET embedding API code in Mono 
runtime licensed under MIT X11 (should be discussed with Miguel but I 
think this could work). It could be used on Windows as well and Wine was 
not affected by Mono embedding API changes since it only had to support 
the .NET embedding API and be able to find mono.dll.

> Another possible approach, if we don't share mscoree.dll code, would
> be for Wine and Mono to both implement ICLRMetaHost
> (http://msdn.microsoft.com/en-us/library/dd233134.aspx) and
> ICLRRuntimeInfo, both of which can be accessed before a runtime is
> chosen and loaded, and for only Mono to implement ICLRRuntimeHost,
> which requires a loaded runtime. Wine's mscoree.dll's other functions
> (except for the _Cor functions which will have to be special) could
> then work based on those interfaces.

This could work but if we keep the embedding API implementation MIT 
licensed, then any other project can reuse it and customize to its needs 
if needed.


More information about the Mono-devel-list mailing list