Thursday, February 19, 2009

Taming CoreClr - 3

Remember mscorlib.dll Assembly must be in same folder of coreclr.dll.
Ok, Now CLR is up what Next!
We have to create new Appdomain where we can execute our code.
Signature for New Appdomain create method:

virtual HRESULT STDMETHODCALLTYPE InitializeAppdoamin(
/* [in] */ LPCWSTR pwzAppdomainname,
/* [in] */ DWORD pwzUnknown,
/* [in] */ LPCWSTR pwzManagerAssemblyName,LPCWSTR pwzMAppdomainmanagerName,
DWORD pwzUnknown2,
/* [in] */ LPCWSTR* appdomainSetup,LPCWSTR* activationData,
/* [out] */ DWORD *appDomainID) = 0;

First parameter (pwzAppdomainname) can be any name you like.
Second parameter (pwzUnknown) is unknown as I don't know its purpose but it should be 13 always to get work. Third parameter is Assembly name where Assembly manager class is defined. Remember if you want to use your own Assembly Manager compile the assembly as Silverlight assembly (Remove reference of mscorlib from project and add explicitly reference of mscorlib of Silverlight).pwzMAppdomainmanagerName is fourth parameter and should be name of manager class.pwzUnknown2 is again unknown but it should be 5 everytime. Sixth parameter (AppdomainSetup) is data to setup the Appdomain. ActivationData is data required by CLR to initialize and setup security policies etc, such as the manifest file name where list of files to be loaded by CLR is given etc. appDomainID will contain ID of new Appdomain.

full example

LPCWSTR* appdomainSetup = new LPCWSTR[4];
LPCWSTR* activationData = new LPCWSTR[4];
appdomainSetup[0] = L"TRUSTEDPATH";
appdomainSetup[1] = L"VERSIONING_MANIFEST_BASE";
appdomainSetup[2] = L"MANIFEST_FILE_PATH";
appdomainSetup[3] = L"LOADER_OPTIMIZATION";
appdomainSetup[4] = L"LOCATION_URI";
activationData[0] = L"..\\Debug";
activationData[1] = L"default:\"..\\Debug\"";
activationData[2] = L"..\\slr.dll.managed_manifest";
activationData[3] = L"SingleDomain";
activationData[4] = L"file://../Debug";
a1 = pCLR->InitializeAppdoamin(L"AppDomain",13,
L"System.Windows.Browser, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e",
L"System.Windows.Hosting.HostAppDomainManager",5, appdomainSetup,activationData,
&appDomainID
);


Here is link to get ISilverlightCLRRuntimeHost interface.
Only few methods will work rest are not implemented in coreclr.

Monday, February 2, 2009

Taming CoreClr Part-2

Hope you did not get bore with first blog of this series :)

I will be more technical going forward with code samples.
After successfully getting the Guid for CoreClr it was time to host CoreClr in custom host.
here is the code for it..

HMODULE clrmodule = LoadLibrary (TEXT ( "..//Coreclr.dll"));
GetCLRRuntimeHost _clrMethod;
_clrMethod = (GetCLRRuntimeHost)GetProcAddress( clrmodule , "GetCLRRuntimeHost" );

You will be eager to know the signature of GetCLRRuntimeHost.

typedef int (__stdcall *GetCLRRuntimeHost)(const IID &CLRGUID,PVOID* clrHost);

We got the method handler(method pointer).
Let us get the SilverlightCLR now:

ISilverlightCLRRuntimeHost *pCLR = NULL;
HRESULT a = _clrMethod(CLRGUID,(PVOID*) &pCLR);

One of the main question is still unanswered definition of ISilverlightCLRRuntimeHost?

As told earlier initial thought was it should be similar to (or same) ICLRRuntimeHost.
I used same interface and tried to call ExecuteApplication.
boom!!!! it crashed.
tried calling Start() again failed...with -2146234334 error code, HOST_E_INVALIDOPERATION.
Tried other methods from ICLRRuntimeHost but none worked.
So again i decided to debug Silverlight with IDA.
After taking the CLRHOST interface pointer they are making a call to
call eax //ECX+38h

where ECX is pointing to the vptr of coreclr object.
Now if i calculate 38h it becomes 12th method of interface,
here was a catch.. ICLRRuntimeHost only has 9 methods.
So it clears that SilverlightCLRRuntime host interface is having additional methods.
This method takes two parameters of int type

pCLR->Magic(2483181568,29805167);

I called this method Magic because the reason was not known for this call.
After making this call again i tried pCLR->Start()

bingo CLR was up :)

to be concluded.......

Tuesday, January 27, 2009

Taming Coreclr Part-1

This is my life's first blog so kindly bear me for mistakes.
CLR fascinates me since beginning. It is the virtual platform to execute managed code.
When i saw the silverlight executing managed code inside the browser, it really thrilled me.
Silerlight is made up of three main components:
1.AgCore.dll
2.NpCtrl.dll
3.Coreclr.dll

NpCtrl is a NP plugin for browsers. So whenever browser loads a page having XAP refrences, NpCtrl is loaded. As per the my research this plugin then loads the AgCore which is the main Silverlight unmanaged execution engine.
AgCore (Ag is symbol of silver in periodic table) is responsible for rendering the contents. if the xap has any Msil references or MSIL code, AgCore asks NpCtrl to load CoreClr. I am not sure about this indirection, as AgCore can itself load the CoreClr but it asks NpCtrl to load the CoreClr.

Dissecting the CoreClr:
CoreClr.dll is unmanaged COM library which is self contained and full CIL execution system(EE,GC etc). Microsoft has not released publicly interfaces and API's supported by CoreClr. So i took a side approach to reverse engineer the CoreClr.
I opened the coreclr with PE explorer and here are the public exports:
1. g_CLREngineMetrics
2. GetCLRRuntimeHost

As the name suggests second export should be used to get the CLRRuntimeHost handle. As its big brother(CLR) usage interface ICLRRuntimeHost for providing the hosting capabilities. To know more about Hosting CLR i recommend read Customizing the Microsoft .NET Framework Common Language Runtime by Steven Pratschner

GetCLRRuntimeHost expects two parameters, one is the GUID for CLRRuntimeHost and second is pointer to pointer to CLRHOST interface which i initial thought is ICLRRuntimeHost type (but it did not). So biggest challenge was to get the GUID for CLRHOST. I disassemble the coreclr using my old time friend IDA PRO. I used GuidFinder a plugin for IDA but it was not able to find any GUID. So i adopted another approach, I created a plugin for firefox a general purpose plugin for txt extensions. So what this plugin does, It loads coreclr explicitly and used Detour to intercept calls made to GetCLRRuntimeHost. So i think you got how i managed to find GUID for CoreCLRHost.
Here is CoreCLR guid

EXTERN_GUID(CLRGUID,
0x712AB73F, 0x2C22,0x4807, 0xAD, 0x7E, 0xF5, 0x01, 0xD7, 0xB7, 0x2C, 0x2D)

I called it CLRGUID.

Rest in next blog.. I will appreciate if you provide any feedback :)