none
Loading CLR into process RRS feed

  • Question

  • Hello.

    I'm trying to load my managed dll into native process. So I start the native process suspended, inject small code that loads native dll and set EIP register to that code. After loading native dll it redirects with JMP back to original EIP. That works pretty nice. So I was trying to start CLR within DllMain but it didnt work at all (dunno why) so I've replaced first 5 bytes at entry point to JMP myEntryPointHookAddress and tryed to start CLR there and after that of course restore original entry point bytes and JMP there. And YES it works, however not for all applications. For example NOTEPAD or CALC (Windows 7) crashes without any errors immediately after JMP originalEntryPoint. Any of applications for older versions of windows and .NET applications seems to work fine. Also any of my .NET applications using WPF crashes - with error for a change:

    Popis:
      Stopped working
    
    Podpis problému:
      Název události problému:	CLR20r3
      Podpis problému 01:	wpftest.exe
      Podpis problému 02:	1.0.0.0
      Podpis problému 03:	4a32460e
      Podpis problému 04:	PresentationFramework
      Podpis problému 05:	3.0.0.0
      Podpis problému 06:	49d44a46
      Podpis problému 07:	624f
      Podpis problému 08:	e1
      Podpis problému 09:	System.Windows.Markup.XamlParse
      Verze operačního systému:	6.1.7100.2.0.0.256.1
      ID národního prostředí:	1029

    There is my CLR starting rutine (ignore the FormatString functions, its just helper):
            CComPtr<IUnknown> pUnknown;
    
            CComPtr<ICorRuntimeHost> pRuntimeHost;
            HRESULT result = CorBindToRuntimeEx( NULL, L"wks", STARTUP_LOADER_SAFEMODE | STARTUP_CONCURRENT_GC, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void**)&pRuntimeHost);
            if ( FAILED( result ) ) throw FormatString( L"Failed to load CLR: 0x%X", result );
            
    	    result = pRuntimeHost->Start();
            if( FAILED( result ) ) throw FormatString( L"Failed to start CLR: 0x%X", result );
    
            CComPtr<IAppDomainSetup> pAppDomainSetup;
            result = pRuntimeHost->CreateDomainSetup( &pUnknown );
            if ( FAILED( result ) ) throw FormatString( L"Failed to create domain setup: 0x%X", result );
    
            result = pUnknown->QueryInterface( &pAppDomainSetup );
            if ( FAILED( result ) ) throw FormatString( L"Failed to query IAppDomainSetup: 0x%X", result );
            pUnknown.Release();
    
            pAppDomainSetup->put_ApplicationBase( _bstr_t( "D:\\Development\\Projects\\Packetzor\\bin\\Debug" ) );
    
            CComPtr<_AppDomain> pAppDomain;
            result = pRuntimeHost->CreateDomainEx( L"Packetzor", pAppDomainSetup, NULL, &pUnknown );
            if ( FAILED( result ) ) throw FormatString( L"Failed to create domain: 0x%X", result );
    
            result = pUnknown->QueryInterface( &pAppDomain );
            if ( FAILED( result ) ) throw FormatString( L"Failed to query _AppDomain: 0x%X", result );
            pUnknown.Release();
    
            CComPtr<_ObjectHandle> pObjectHandle;
            result = pAppDomain->CreateInstance( _bstr_t( "Packetzor" ), _bstr_t( "Interop.ComObject" ), &pObjectHandle );
            if ( FAILED( result ) ) throw FormatString( L"Failed to create instance: 0x%X", result );
    
            CComVariant variant;
            result = pObjectHandle->Unwrap( &variant );
            if ( FAILED( result ) ) throw FormatString( L"Failed to unwrap object handle: 0x%X", result );
    
            if ( variant.vt != VT_DISPATCH ) throw FormatString( L"Variant is not VT_DISPATCH: 0x%X", variant.vt );
    
            CComPtr<IDispatch> pDispatch;
            pDispatch = variant.pdispVal;
    
            result = pDispatch->QueryInterface( &pComObject );
            if ( FAILED( result ) ) throw FormatString( L"Failed to query IComObject: 0x%X", result );
            pDispatch.Release();
    
            pComObject->Init();
    I've also tryed to find out what part crashes it and it works only when i comment out everything but first two blocks so it seems to be caused by "pRuntimeHost->CreateDomainSetup( &pUnknown );". Any ideas what I'm doing wrong?
    Saturday, June 13, 2009 9:09 AM

Answers

  • Actually there never can be already running CLR because the application has no time to start it - my code is the first thing that executes because I'm replacing entry point, however your right I should check for it for the case of using code somewhere else or even just for more clear code. The problem was, the applications using WinFX require to run its windows in STA thread. So when I call CoInitialize as first thing in entry point hook, everything works fine. 

    Thanks, Lukáš
    • Marked as answer by Asyrk Monday, June 22, 2009 7:53 PM
    Monday, June 22, 2009 7:52 PM

All replies

  • Before starting the runtime you should check if the bind returned S_FALSE , if it did then there already is a running CLR in the process and no start is necessary.Also make sure the stack is properly preserved when you get back from the hooking call and try to get a more meaningful stack trace - download the debug symbols from Microsoft's website (http://support.microsoft.com/kb/311503), set _NT_SYMBOL_PATH and run with a debugger attached to see what you get.

    I would suggest you to move your post here : http://social.msdn.microsoft.com/Forums/en-US/netfxtoolsdev/threads.

    HTH
    Paul
    Saturday, June 13, 2009 3:08 PM
  • Actually there never can be already running CLR because the application has no time to start it - my code is the first thing that executes because I'm replacing entry point, however your right I should check for it for the case of using code somewhere else or even just for more clear code. The problem was, the applications using WinFX require to run its windows in STA thread. So when I call CoInitialize as first thing in entry point hook, everything works fine. 

    Thanks, Lukáš
    • Marked as answer by Asyrk Monday, June 22, 2009 7:53 PM
    Monday, June 22, 2009 7:52 PM