Problem mit C++ CLR \ HostAppDomain



  • Hallo,

    ich habe eine C++ dll, welche meine C# dll nach einer Injection aufrufen soll.
    Also die C++ dll soll in einen Prozess injected werden, und anschließend meinen C# code callen.

    Dies ist meine C++ DLL:

    #include "stdafx.h"
    #include <metahost.h>
    #pragma comment(lib, "mscoree.lib")
    
    DWORD WINAPI ControlThread(LPVOID lpParam)
    {
    	ICLRMetaHost* metaHost = NULL;
    	ICLRRuntimeInfo* runtimeInfo = NULL;
    	ICLRRuntimeHost* runtimeHost = NULL;
    	if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&metaHost) == S_OK)
    	if (metaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&runtimeInfo) == S_OK)
    	if (runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&runtimeHost) == S_OK)
    	if (runtimeHost->Start() == S_OK)
    	{
    		DWORD pReturnValue;
    		runtimeHost->ExecuteInDefaultAppDomain(L"C:\\Dev\\CalledDll.dll", L"CalledDll.InjectedCSharpCode", L"DllMain", L"C# DLL loaded.", &pReturnValue);
    
    		runtimeInfo->Release();
    		metaHost->Release();
    		runtimeHost->Release();
    	}
    	return 0;
    }
    
    BOOL APIENTRY DllMain(HMODULE hModule,
    	DWORD  ul_reason_for_call,
    	LPVOID lpReserved
    )
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    		CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ControlThread, hModule, NULL, NULL);
    		break;
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
    	return TRUE;
    }
    

    Und dies ist meine C# dll:

    using System.Windows.Forms;
    
    namespace CalledDll
    {
        public class InjectedCSharpCode
        {
            public static int DllMain(string InjectStatus)
            {
                MessageBox.Show("Im successfully called from C++ DLL.");
    
                Main();
    
                return 0;
            }
    
            public static void Main()
            {
                var form = new TestForm();
                form.Show();
            }            
            
        }
    }
    

    Das ganze funktioniert soweit ganz gut ABER und jetzt komm ich zu meinem Problem: Es funktioniert nicht bei allen Programmen und ich weiß einfach nicht warum:

    Bei Notepad++ und bei GTA 5 zum Beispiel funktioniert es, bei anderen Spielen und Programmen wieder nicht. Warum? Keine Ahnung.
    Wenn es nicht funktioniert, ist runtimeHost nicht S_OK.

    if (runtimeHost->Start() == S_OK)
    

    Eventuell startet er nicht mal den RunTimeHost...
    Wenn jemand eine Idee hat oder bestenfalls ein Codebeispiel hat, wäre ich sehr Dankbar.

    Mit freundlichen Grüßen



  • Ich weiß jetzt woran es lag... Das ganze funktioniert nicht mit .NET V4, sondern nur mit V2 also :

    if (metaHost->GetRuntime(L"v2.0.50727", IID_ICLRRuntimeInfo, (LPVOID*)&runtimeInfo) == S_OK)
    

    Warum es nicht mit V4 geht? Das Weiß ich bis jetzt auch nicht aber es funktioniert, also alles gut.



  • Kommt mir sehr vage bekannt vor... D.h., es besteht eine gewisse Chance, dass es hier bekannte Stolperfallen gibt, die du ergoogeln könntest.



  • @mechanics Habs jetzt auch mit CLR V4 hinbekommen. Es hat nicht funktioniert weil ich vergessen habe bei den Eigenschaften "use CLR" auszuwählen :D.