Esempio n. 1
0
ff::INativeHostControl *ff::ClrStartup(StringRef configFile, StringRef versionOrAssembly)
{
	ff::ComPtr<ICLRMetaHost> metaHost;
	ff::ComPtr<ICLRRuntimeInfo> clrInfo;
	ff::ComPtr<ICLRRuntimeHost> clrHost;
	ff::ComPtr<ICLRControl> clrControl;
	ff::ComPtr<ICLRGCManager> gcManager;
	ff::ComPtr<ff::INativeHostControl> hostControl;

	assertRetVal(SUCCEEDED(CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (void **)&metaHost)), nullptr);

	assertRetVal(SUCCEEDED(metaHost->GetRuntime(GetClrVersion(metaHost, versionOrAssembly).c_str(), IID_ICLRRuntimeInfo, (void **)&clrInfo)), nullptr);
	assertRetVal(SUCCEEDED(clrInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void **)&clrHost)), nullptr);
	assertRetVal(SUCCEEDED(clrInfo->SetDefaultStartupFlags(STARTUP_CONCURRENT_GC | STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST, configFile.c_str())), nullptr);

	assertRetVal(SUCCEEDED(CreateHostControl(&hostControl)), nullptr);
	assertRetVal(SUCCEEDED(clrHost->SetHostControl(hostControl)), nullptr);
	assertRetVal(SUCCEEDED(clrHost->GetCLRControl(&clrControl)), nullptr);
	assertRetVal(SUCCEEDED(clrControl->GetCLRManager(IID_ICLRGCManager, (void **)&gcManager)), nullptr);

	assertRetVal(SUCCEEDED(clrHost->Start()), nullptr);
	assertRetVal(hostControl->Startup(), nullptr);

	s_metaHost = metaHost;
	s_clrInfo = clrInfo;
	s_clrHost = clrHost;
	s_clrControl = clrControl;
	s_gcManager = gcManager;
	s_hostControl = hostControl.Detach();

	return s_hostControl;
}
Esempio n. 2
0
	void Bootstrap::StartTheDotNetRuntime()
	{		 
		ofstream myfile;
		myfile.open(L"C:\\Temp\\cppLog.txt");
		myfile << "Entered Injection function";
		myfile.close();

		ICLRMetaHost *pMetaHost = NULL;
		CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);

		ICLRRuntimeInfo *pRuntimeInfo = NULL;
		pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);

		ICLRRuntimeHost *pClrRuntimeHost = NULL;
		pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pClrRuntimeHost);		

		//Run the CLR so run a >NET runtime
		pClrRuntimeHost->Start();		

		HRESULT hr = LoadManagedLibrary(pClrRuntimeHost);
		
		myfile.open(L"C:\\Temp\\cppLog.txt");
		myfile << "After to loading .NET dll";
		myfile.close();		

		// free resources
		pMetaHost->Release();
		pRuntimeInfo->Release();
		pClrRuntimeHost->Release();
	}	
Esempio n. 3
0
/**
 * @brief Sets up the common language runtime in the client process
 */
void DotNetHost::LaunchCLR()
{
  m_hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&m_pMetaHost));
  m_hr = m_pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&m_pRuntimeInfo));
  m_hr = m_pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&m_pClrRuntimeHost));
  m_hr = m_pClrRuntimeHost->Start();
}
Esempio n. 4
0
extern "C" __declspec(dllexport) HRESULT Inject(_In_ LPCSTR param)
{
    DWORD pReturnValue;
    ICLRMetaHost*    pMetaHost       = NULL;
    ICLRRuntimeInfo* pRuntimeInfo    = NULL;
    ICLRRuntimeHost* pClrRuntimeHost = NULL;

    if (CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)) != S_OK)
    {
        return -1;
    }
    if (pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)) != S_OK)
    {
        return -1;
    }
    if (pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost)) != S_OK)
    {
        return -1;
    }

    if (pClrRuntimeHost->Start() != S_OK)
    {
        return -1;
    }

    WCHAR wsz[MAX_PATH];
    MultiByteToWideChar(CP_ACP, 0, param, -1, wsz, MAX_PATH);

    HRESULT hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(
        wsz,
        L"FakePacketSender.InjectedEntry",
        L"Run",
        wsz,
        &pReturnValue);

    if (hr = pClrRuntimeHost->Stop() != S_OK)
    {
        _com_error err(hr);
        MessageBox(0, err.ErrorMessage(), L"Error", 0);
        return -1;
    }

    if (hr != S_OK)
    {
        _com_error err(hr);
        MessageBox(0, err.ErrorMessage(), L"Error", 0);
        return -1;
    }

    pMetaHost->Release();
    pRuntimeInfo->Release();
    pClrRuntimeHost->Release();

    return hr;
}
HRESULT clrWrapper(LPCWSTR runtimeVersion, std::function<HRESULT(ICLRRuntimeHost* pClrRuntimeHost)> callback)
{
    HRESULT hr = E_FAIL;
    ICLRMetaHost* pMetaHost = nullptr;
    ICLRRuntimeInfo* pRuntimeInfo = nullptr;
    ICLRRuntimeHost* pClrRuntimeHost = nullptr;

    do {
        hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
        if (FAILED(hr)) {
            break;
        }

        hr = pMetaHost->GetRuntime(runtimeVersion, IID_PPV_ARGS(&pRuntimeInfo));
        if (FAILED(hr)) {
            break;
        }

        hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost));
        if (FAILED(hr)) {
            break;
        }

        hr = pClrRuntimeHost->Start();
        if (FAILED(hr)) {
            break;
        }

        if (callback) {
            hr = callback(pClrRuntimeHost);
            if (FAILED(hr)) {
                break;
            }
        }
    } while (false);

    if (pClrRuntimeHost) {
        pClrRuntimeHost->Release();
        pClrRuntimeHost = nullptr;
    }

    if (pRuntimeInfo) {
        pRuntimeInfo->Release();
        pRuntimeInfo = nullptr;
    }

    if (pMetaHost) {
        pMetaHost->Release();
        pMetaHost = nullptr;
    }

    return hr;
}
Esempio n. 6
0
// Try to get the right version of the CLR running.
HRESULT LoadClr(std::wstring clrVersion, ICorRuntimeHost **ppHost)
{
	// Check whether the .Net 4+ MetaHost interfaces are present.
	// The checks here are according to this blog post: 
	// http://bradwilson.typepad.com/blog/2010/04/selecting-clr-version-from-unmanaged-host.html
	/*
	1. LoadLibrary mscoree
	2. GetProcAddress for CLRCreateInstance. If you get NULL, fall back to legacy path (CorBindToRuntimeEx)
	3. Call CLRCreateInstance to get ICLRMetaHost. If you get E_NOTIMPL, fall back to legacy path (same as above)
	4. Otherwise, party on the ICLRMetaHost you just got
	*/
	// If present, load the desired version using the new interfaces.
	// If not, check if we want .Net 4+, if so fail, else load old-style.

	HRESULT hr = E_FAIL;
	HMODULE hMscoree = NULL;
	ICLRMetaHostPtr pMetaHost;

	bool needNet40 = (CompareNoCase(clrVersion, L"v4.0") >= 0);
	bool needMetaHost = needNet40;

	hMscoree = LoadLibrary(L"mscoree.dll");
	if (hMscoree == 0)
	{
		// No .Net installed
		// CONSIDER: Doing explicit checking according to http://support.microsoft.com/kb/318785
		if (needNet40)
		{
				ShowMessage(IDS_MSG_HEADER_NEEDCLR40, 
					IDS_MSG_BODY_LOADMSCOREE, 
					IDS_MSG_FOOTER_ENSURECLR40 );
		}
		else
		{
				ShowMessage(IDS_MSG_HEADER_NEEDCLR20, 
					IDS_MSG_BODY_LOADMSCOREE, 
					IDS_MSG_FOOTER_ENSURECLR20 );
		}
		hr = E_FAIL;
	}
	else
	{
		pfnCLRCreateInstance CLRCreateInstance = (pfnCLRCreateInstance)GetProcAddress(hMscoree, "CLRCreateInstance");
		if (CLRCreateInstance == 0)
		{
			// Certainly no .Net 4 installed
			if (needMetaHost)
			{
				// We need .Net 4.0 but it is not installed
				ShowMessage(IDS_MSG_HEADER_NEEDCLR40, 
							IDS_MSG_BODY_NOCLRCREATEINSTANCE, 
							IDS_MSG_FOOTER_ENSURECLR40 );
				hr = E_FAIL;
			}
			else
			{
				// We need only .Net 2.0 runtime and cannot MetaHost.
				// Load .Net 2.0 with old code path
				hr = LoadClr20(ppHost);
			}
		}
		else
		{
			hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
			if (FAILED(hr))
			{
				// MetaHost is not available, even though we have a new version of MSCorEE.dll
				// Certainly no .Net 4 installed
				if (needMetaHost)
				{
					// We need .Net 4.0 but it is not installed
					ShowMessage(IDS_MSG_HEADER_NEEDCLR40, 
								IDS_MSG_BODY_CLRCREATEINSTANCEFAILED, 
								IDS_MSG_FOOTER_ENSURECLR40, 
								hr );
					hr = E_FAIL;
				}
				else
				{
					// We need only .Net 2.0 runtime and cannot MetaHost.
					// Load .Net 2.0 with old code path
					hr = LoadClr20(ppHost);
				}
			}
			else
			{
				// Yay! We have a metahost
				hr = LoadClrMeta(clrVersion, pMetaHost, ppHost);
			}
		}
		FreeLibrary(hMscoree);
	}
	return hr;
}
Esempio n. 7
0
ICLRRuntimeHost* StartCLR(LPCWSTR dotNetVersion)
{
	HRESULT hr;

	ICLRMetaHost* pClrMetaHost = NULL;
	ICLRRuntimeInfo* pClrRuntimeInfo = NULL;
	ICLRRuntimeHost* pClrRuntimeHost = NULL;

	// Get the CLRMetaHost that tells us about .NET on this machine
	hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pClrMetaHost);

	if (hr == S_OK)
	{
		OutputDebugStringW(L"[Bootstrap] Created CLR instance\n");
		// Get the runtime information for the particular version of .NET
		hr = pClrMetaHost->GetRuntime(dotNetVersion, IID_PPV_ARGS(&pClrRuntimeInfo));
		if (hr == S_OK)
		{
			OutputDebugStringW(L"[Bootstrap] Got CLR runtime\n");
			// Check if the specified runtime can be loaded into the process. This
			// method will take into account other runtimes that may already be
			// loaded into the process and set pbLoadable to TRUE if this runtime can
			// be loaded in an in-process side-by-side fashion.
			BOOL fLoadable;
			hr = pClrRuntimeInfo->IsLoadable(&fLoadable);
			if ((hr == S_OK) && fLoadable)
			{
				OutputDebugStringW(L"[Bootstrap] Runtime is loadable!\n");
				// Load the CLR into the current process and return a runtime interface
				// pointer.
				hr = pClrRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
					IID_PPV_ARGS(&pClrRuntimeHost));
				if (hr == S_OK)
				{
					OutputDebugStringW(L"[Bootstrap] Got interface.\n");
					// Start it. This is okay to call even if the CLR is already running
					hr = pClrRuntimeHost->Start();
					//       if (hr == S_OK)
					//     {
					OutputDebugStringW(L"[Bootstrap] Started the runtime!\n");
					// Success!
					return pClrRuntimeHost;
					//   }
				}
			}
		}
	}
	// Cleanup if failed
	if (pClrRuntimeHost)
	{
		pClrRuntimeHost->Release();
		pClrRuntimeHost = NULL;
	}
	if (pClrRuntimeInfo)
	{
		pClrRuntimeInfo->Release();
		pClrRuntimeInfo = NULL;
	}
	if (pClrMetaHost)
	{
		pClrMetaHost->Release();
		pClrMetaHost = NULL;
	}

	return NULL;
}
/// <summary>
/// Starts the dot net runtime.
/// </summary>
/// <remarks>http://www.codingthewheel.com/archives/how-to-inject-a-managed-assembly-dll/</remarks>
HRESULT StartTheDotNetRuntime(_In_ LPCTSTR lpCommand)
{
	FILE *file;
	fopen_s(&file, logPath, "a+");

	fprintf(file, "binding runtime.\r\n");
	fflush(file);

    fprintf(file, "Loading the .NET runtime host.\n");
	fflush(file);
      
	ICLRMetaHost *pMetaHost = NULL;
	auto result = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
	if (FAILED(result))
	{
		fprintf(file, "Error: failed to create CLR instance.\n");
		fflush(file);
		
		return result;
	}
 
	fprintf(file, "Loading the .NET runtime.\n");
	fflush(file);

	ICLRRuntimeInfo *pRuntimeInfo = NULL;
	result = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
	if (FAILED(result))
	{
		fprintf(file, "Error: failed to create CLR instance.\n");
		fflush(file);

		pMetaHost->Release();
		return result;
	}
 
	fprintf(file, "Acquiring the .NET runtime.\n");
	fflush(file);

	ICLRRuntimeHost *pClrRuntimeHost = NULL;
	result = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost));
	if (FAILED(result))
	{
		fprintf(file, "Error: failed to acquire CLR runtime.\n");
		fflush(file);

		pMetaHost->Release();
		return result;
	}

	fprintf(file, "Starting the .NET runtime.\n");
	fflush(file);

	result = pClrRuntimeHost->Start();
	if (FAILED(result))
	{
		fprintf(file, "Error: failed to start CLR runtime.\n");
		fflush(file);

		pClrRuntimeHost->Release();
		pMetaHost->Release();
		return result;
	}

	fprintf(file, "Executing payload assembly.\n");
	fflush(file);
    DWORD dwRet = 0;
    result = pClrRuntimeHost->ExecuteInDefaultAppDomain(
            assemblyPath,
            classFqn, methodName, parameter, &dwRet);
	if (FAILED(result))
	{
		fprintf(file, "Error: unable to execute example code.\n");
		fflush(file);

		pClrRuntimeHost->Stop();
		pClrRuntimeHost->Release();
		pMetaHost->Release();
		return result;
	}

	fprintf(file, "Stopping the .NET runtime.\n");
	fflush(file);

	pClrRuntimeHost->Stop();

	fprintf(file, "Releasing the .NET runtime.\n");
	fflush(file);

	pClrRuntimeHost->Release();
	pMetaHost->Release();

	fclose(file);

	return ERROR_SUCCESS;
}
Esempio n. 9
0
HRESULT WINAPI CreateInterface(REFCLSID clsid, REFIID riid, LPVOID *ppInterface)
{
    TRACE("(%s,%s,%p)\n", debugstr_guid(clsid), debugstr_guid(riid), ppInterface);

    return CLRCreateInstance(clsid, riid, ppInterface);
}
Esempio n. 10
0
EASYHOOK_NT_INTERNAL CompleteManagedInjection(LPREMOTE_INFO InInfo)
{
    /// Region: Temporary workaround for InInfo->Assemblies not being received correctly
    InInfo->AssembliesCount = 3;
    InInfo->Assemblies = new RhAssemblyInfo[InInfo->AssembliesCount];
    InInfo->Assemblies[0].FullName = L"ProcMonInject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d34a061f079be347, ProcessorArchitecture=MSIL";
    InInfo->Assemblies[0].AssemblyLoadPath = L"D:/Documenten/Documenten/Projects/EasyHook/EasyHook - CLRHostingAPI - vs2008/Debug/x64/ProcMonInject.dll";
    InInfo->Assemblies[0].AssemblyDebugInfoPath = NULL;
    InInfo->Assemblies[1].FullName = L"ProcessMonitor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d34a061f079be347, ProcessorArchitecture=MSIL";
    InInfo->Assemblies[1].AssemblyLoadPath = L"D:/Documenten/Documenten/Projects/EasyHook/EasyHook - CLRHostingAPI - vs2008/Debug/x64/ProcessMonitor.exe";
    InInfo->Assemblies[1].AssemblyDebugInfoPath = NULL;
    InInfo->Assemblies[2].FullName = L"EasyHook, Version=2.5.0.0, Culture=neutral, PublicKeyToken=4b580fca19d0b0c5, ProcessorArchitecture=MSIL";
    InInfo->Assemblies[2].AssemblyLoadPath = L"D:/Documenten/Documenten/Projects/EasyHook/EasyHook - CLRHostingAPI - vs2008/Debug/x64/EasyHook.dll";
    InInfo->Assemblies[2].AssemblyDebugInfoPath = NULL;
    /// Endregion

/*
Description:

    Loads the NET runtime into the calling process and invokes the
    managed injection entry point.
*/

#ifdef _NET4
    ICLRMetaHost*	        pMetaClrHost = NULL;
    ICLRRuntimeInfo*        pRuntimeInfo = NULL;
#endif
    REMOTE_ENTRY_INFO       EntryInfo;
	ICLRRuntimeHost*	    pClr = NULL;
    WCHAR                   ParamString[MAX_PATH];
    DWORD                   ErrorCode = 0;
    HMODULE                 hMsCorEE = LoadLibraryA("mscoree.dll");
    PROC_CorBindToRuntime*  CorBindToRuntime = (PROC_CorBindToRuntime*)GetProcAddress(hMsCorEE, "CorBindToRuntime");

    if(CorBindToRuntime == NULL)
        UNMANAGED_ERROR(10);

    // Invoke user defined entry point
    EntryInfo.HostPID = InInfo->HostProcess;
    EntryInfo.UserData = InInfo->UserData;
    EntryInfo.UserDataSize = InInfo->UserDataSize;

    RtlLongLongToUnicodeHex((LONGLONG)&EntryInfo, ParamString);

    // Load the Common Language Runtime
    if(!RTL_SUCCESS(CorBindToRuntime(NULL, NULL, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void**)&pClr)))
        UNMANAGED_ERROR(11);
    if (!RTL_SUCCESS(AssociateCustomCLRHost(pClr, InInfo->Assemblies, InInfo->AssembliesCount)))
        UNMANAGED_ERROR(14);
	pClr->Start();

    /*
		Test library code.
		This is because if once we have set the remote signal, there is no way to
		notify the host about errors. If the following call succeeds, then it will
		also do so some lines later... If not, then we are still able to report an error.

        The EasyHook managed injection loader will establish a connection to the
        host, so that further error reporting is still possible after we set the event!
	*/
    RtlLongLongToUnicodeHex((LONGLONG)&EntryInfo, ParamString);

    HRESULT result = pClr->ExecuteInDefaultAppDomain(
                            InInfo->UserLibrary, 
                            L"EasyHook.InjectionLoader", L"Main", 
                            ParamString, &ErrorCode);
	if(!RTL_SUCCESS(result))
	{
        // Test failed!
#ifdef _NET4
        // Target CLR might be .NET 4.0, try to load this CLR instead.
		if(NULL != pClr)
	        pClr->Release();
		if(FAILED(CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (void**)&pMetaClrHost)))
			UNMANAGED_ERROR(11);
		if(FAILED(pMetaClrHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (void**)&pRuntimeInfo)))
			UNMANAGED_ERROR(11);
		if(FAILED(pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void**) &pClr)))
			UNMANAGED_ERROR(11);
        AssociateCustomCLRHost(pClr);
		pClr->Start();
		RtlLongLongToUnicodeHex((LONGLONG)&EntryInfo, ParamString);
		if(!RTL_SUCCESS(RuntimeClrHost->ExecuteInDefaultAppDomain(InInfo->UserLibrary, L"EasyHook.InjectionLoader", L"Main", ParamString, &RetVal)))
#endif
			UNMANAGED_ERROR(12);
	}

	if(!ErrorCode)
        UNMANAGED_ERROR(13);

	// set and close event
	if(!SetEvent(InInfo->hRemoteSignal))
		UNMANAGED_ERROR(22);
	CloseHandle(InInfo->hRemoteSignal);

	InInfo->hRemoteSignal = NULL;

	// Execute library code (no way for error reporting, so we dont need to check)
	pClr->ExecuteInDefaultAppDomain(
        InInfo->UserLibrary, 
        L"EasyHook.InjectionLoader", 
        L"Main", 
        ParamString, 
        &ErrorCode);

ABORT_ERROR:

	// Release Resources
	if(NULL != pClr)
		pClr->Release();

#ifdef _NET4
    if (NULL != pMetaClrHost)
        pMetaClrHost->Release();
    if (NULL != pRuntimeInfo)
        pRuntimeInfo->Release();
#endif

	return ErrorCode;
}
Esempio n. 11
0
bool CLRHost::Initialize()
{
    assert(!isInitialized);

    HRESULT hr;
    std::vector<std::wstring> clrRuntimeList;

    Log(L"CLRHost::Initialize() attempting to load and start the .NET runtime "
        L"%s", clrRuntimeVersion);

    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&clrMetaHost));
    if (FAILED(hr)) {
        Log(L"CLRCreateInstance() failed: 0x%08lx", hr);
        goto errorCleanup;
    }

    if (clrRuntimeVersion) {
        hr = clrMetaHost->GetRuntime(clrRuntimeVersion,
            IID_PPV_ARGS(&clrRuntimeInfo));
        if (FAILED(hr)) {
            Log(L"ICLRMetaHost::GetRuntime(%s) failed: 0x%08lx",
                clrRuntimeVersion, hr);
        }
    }

    if (!clrRuntimeInfo) {
        hr = GetInstalledClrRuntimes(clrMetaHost, clrRuntimeList);
        if (SUCCEEDED(hr)) {
            if (clrRuntimeList.size()) {
                for (auto itor = clrRuntimeList.begin();
                    itor < clrRuntimeList.end(); itor++)
                {
                    Log(L"CLRHost::Initialize() Found version %s .NET runtime",
                        (*(itor)).c_str());
                }

                std::wstring version = *(clrRuntimeList.end() - 1);

                Log(L"CLRHost::Initialize() attempting to use %s .NET runtime",
                    version.c_str());

                hr = clrMetaHost->GetRuntime(version.c_str(),
                    IID_PPV_ARGS(&clrRuntimeInfo));

                if (FAILED(hr)) {
                    Log(L"ICLRMetaHost::GetRuntime(%s) failed: 0x%08lx",
                        version.c_str(), hr);
                    goto errorCleanup;
                }
            }
            else {
                Log(L"CLRHost::Initialize() no .NET Runtimes found!");
                goto errorCleanup;
            }
        }
        else {
            Log(L"CLRHost::GetInstalledClrRuntimes) failed: 0x%08lx", hr);
            goto errorCleanup;
        }
    }

    BOOL isLoadable;
    hr = clrRuntimeInfo->IsLoadable(&isLoadable);
    if (FAILED(hr)) {
        Log(L"ICLRRuntimeInfo::IsLoadable() failed: 0x%08lx", hr);
        goto errorCleanup;
    }

    if (!isLoadable) {
        Log(L".NET runtime %s cannot be loaded", clrRuntimeVersion);
        goto errorCleanup;
    }

    hr = clrRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost,
        (LPVOID *) &corRuntimeHost);
    if (FAILED(hr)) {
        Log(L"ICLRRuntimeInfo::GetInterface() failed when retrieving "
            L"ICorRuntimeHost instance: 0x%08lx", hr);
        goto errorCleanup;
    }

    // Start the CLR.
    hr = corRuntimeHost->Start();
    if (FAILED(hr)) {
        Log(L"ICorRuntimeHost::Start() failed: 0x%08lx", hr);
        goto errorCleanup;
    }

    isInitialized = true;
    goto success;

errorCleanup:

    if (clrMetaHost) {
        clrMetaHost->Release();
        clrMetaHost = nullptr;
    }
    if (clrRuntimeInfo) {
        clrRuntimeInfo->Release();
        clrRuntimeInfo = nullptr;
    }
    if (corRuntimeHost) {
        corRuntimeHost->Release();
        corRuntimeHost = nullptr;
    }

success:
    return isInitialized;
}
Esempio n. 12
0
VOID StartAssembly(vector<wstring> const& params) 
{
	ICLRMetaHost *pMetaHost = NULL;
    HRESULT hr;
    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost,
        (LPVOID*)&pMetaHost);

    if (SUCCEEDED(hr))
    {
        IEnumUnknown *peunkRuntimes;
        hr = pMetaHost->EnumerateInstalledRuntimes(&peunkRuntimes);
        if (SUCCEEDED(hr))
        {
            // *** FINDING LATEST RUNTIME ***
            IUnknown *punkRuntime;
            ICLRRuntimeInfo *prtiLatest = NULL;
            WCHAR szLatestRuntimeVersion[MAX_PATH];
            while (peunkRuntimes->Next(1, &punkRuntime, NULL) == S_OK)
            {
                ICLRRuntimeInfo *prtiCurrent;
                hr = punkRuntime->QueryInterface(IID_PPV_ARGS(&prtiCurrent));
                if (SUCCEEDED(hr))
                {
                    if (!prtiLatest)
                    {
                        hr = prtiCurrent->QueryInterface(IID_PPV_ARGS(&prtiLatest));
                        if (SUCCEEDED(hr))
                        {
                            DWORD cch = ARRAYSIZE(szLatestRuntimeVersion);
                            hr = prtiLatest->GetVersionString(szLatestRuntimeVersion, &cch);
                        }
                    }
                    else
                    {
                        WCHAR szCurrentRuntimeVersion[MAX_PATH];
                        DWORD cch = ARRAYSIZE(szCurrentRuntimeVersion);
                        hr = prtiCurrent->GetVersionString(szCurrentRuntimeVersion, &cch);
                        if (SUCCEEDED(hr))
                        {
                            if (wcsncmp(szLatestRuntimeVersion, szCurrentRuntimeVersion, cch) < 0)
                            {
                                hr = prtiCurrent->GetVersionString(szLatestRuntimeVersion, &cch);
                                if (SUCCEEDED(hr))
                                {
                                    prtiLatest->Release();
                                    hr = prtiCurrent->QueryInterface(IID_PPV_ARGS(&prtiLatest));
                                }
                            }
                        }
                    }
                    prtiCurrent->Release();
                }
                punkRuntime->Release();
            }
            peunkRuntimes->Release();

            // *** STARTING CLR ***
            if (SUCCEEDED(hr))
            {
                ICLRRuntimeHost *prth;
                hr = prtiLatest->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&prth);
                if (SUCCEEDED(hr))
                {
					hr = prth->Start();
					if (SUCCEEDED(hr))
					{
						DWORD dwRet = 0;
						hr = prth->ExecuteInDefaultAppDomain(params.at(0).c_str(), params.at(1).c_str(), 
							params.at(2).c_str(), params.at(3).c_str(), &dwRet);
						// hr = 0x80131513 (System.MissingMethodException)

						if (SUCCEEDED(hr))
						{
							// *** Success ***
							MessageBox(GetDesktopWindow(), L"Successfully called managed function.", L"Success", MB_OK);
						}
						hr = prth->Stop();
					}
					prth->Release();
                }
            } 
        }
        pMetaHost->Release();
    }
}
Esempio n. 13
0
DWORD InitRuntime( )
{
    DWORD         dwRet     = 0;
    HRESULT       hr        = S_OK;
    WCHAR         ver[255]  = {0};
    IEnumUnknown *pRuntimes = nullptr;

    // MetaHost instance 
    hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pClrHost);
    if(!SUCCEEDED(hr))
        return 1;

    // Get available runtimes
    hr = pClrHost->EnumerateInstalledRuntimes(&pRuntimes);
    if(!SUCCEEDED(hr))
        return 1;

    // Search for target runtime needed for managed dll to run
    while(pRuntimes->Next(1, (IUnknown**)&pRuntimeinfo, &dwRet) == S_OK && dwRet > 0)
    {
        dwRet = ARRAYSIZE(ver);

        hr = pRuntimeinfo->GetVersionString(ver, &dwRet);

        // ver - string "vA.B[.X]"
        if(ver[1] == TARGET_RUNTIME)
            break;

        pRuntimeinfo->Release();
        pRuntimeinfo = nullptr;
    }

    // Found runtime
    if(pRuntimeinfo != nullptr)
    {
        BOOL started = FALSE;

        // Get CLR hosting interface
        hr = pRuntimeinfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pRuntimeHost);
        if(!SUCCEEDED(hr))
            return 1;

        // Check if runtime is already running
        hr = pRuntimeinfo->IsStarted(&started, &dwRet);
        if(!SUCCEEDED(hr))
            return 1;

        // Start .NET runtime if needed
        if(started == FALSE)
        {
            hr = pRuntimeHost->Start();
            if(!SUCCEEDED(hr))
                return 1;
        }
    }

    if(pRuntimes)
        pRuntimes->Release();

    return 0;
}
Esempio n. 14
0
__declspec(dllexport) DWORD STDMETHODCALLTYPE LaunchCrazyNateManaged(LPVOID inputOutputBuffer)
{
  IEnumUnknown * pRuntimes = NULL;
  ICLRMetaHost * pMetaHost = NULL;
  ICLRRuntimeInfo * pRuntimeInfo = NULL;
  ICLRRuntimeHost * pRuntime = NULL;
  DWORD returnValue = 0;
  DWORD done = 0;
  WCHAR versionBuffer[100];
  DWORD versionBufferLen = 100;
  DWORD numRuntimesEnumerated = 0;
  WCHAR * dllPath;
  WCHAR * typeName;
  WCHAR * methodName;
  WCHAR * argument;
  WCHAR * errorMessageBuffer;
  size_t lengthArg;
  size_t lengthTotal;

  while (InterlockedExchange(&inputBufferLock, 3) != 0)
  {
    // spin wait
  }

  // copy inputs to separate buffer, so 'inputOutputBuffer' can be used for output
  memcpy(inputBufferCopy, inputOutputBuffer, ERROR_BUFFER_SIZE * sizeof(WCHAR));
  errorMessageBuffer = (WCHAR*)inputOutputBuffer;
  memset(errorMessageBuffer, 0, ERROR_BUFFER_SIZE * sizeof(WCHAR));

  // prepare to find the individual strings in 'inputBufferCopy'
  lengthTotal = 0;
#define GetArg(varName) \
  if (lengthTotal < ERROR_BUFFER_SIZE) \
  { \
    if (S_OK == StringCchLength(&inputBufferCopy[lengthTotal], ERROR_BUFFER_SIZE - lengthTotal, &lengthArg)) \
    { \
      varName = &inputBufferCopy[lengthTotal]; \
      lengthTotal += lengthArg + 1; \
    } \
    else \
    { \
      lengthTotal = ERROR_BUFFER_SIZE + 1; \
    } \
  }

  // arguments are managed dll path, mananged type name, method name, and argument
  GetArg(dllPath);
  GetArg(typeName);
  GetArg(methodName);
  GetArg(argument);
  
  // complain if inputs were too large
  if (lengthTotal > ERROR_BUFFER_SIZE)
  {
    StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"inputs were too large");
  }
  else
  {
    // get CLR com object
    if (S_OK == CLRCreateInstance(&CLSID_CLRMetaHost, &IID_ICLRMetaHost, (LPVOID*)&pMetaHost))
    {
      if (S_OK == pMetaHost->lpVtbl->EnumerateLoadedRuntimes(pMetaHost,
        GetCurrentProcess(),
        &pRuntimes))
      {
        while (done == 0 &&
          S_OK == pRuntimes->lpVtbl->Next(pRuntimes,
          1,
          (IUnknown**)&pRuntimeInfo,
          NULL))
        {
          numRuntimesEnumerated++;

          // try to be smart about which runtime it is.
          // I want the .NET 4.5.1 runtime
          memset((void*)versionBuffer, (int)0, (size_t)sizeof(versionBuffer));
          if (S_OK == pRuntimeInfo->lpVtbl->GetVersionString(pRuntimeInfo, versionBuffer, &versionBufferLen))
          {
            versionBuffer[99] = 0;

            if (versionBuffer[0] == 'v' &&
              versionBuffer[1] == '4' &&
              versionBuffer[2] == '.' &&
              versionBuffer[3] == '0')
            {
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"found CLR, version is ");
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, versionBuffer);
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"\r\n");

              // load the CLR
              // (TODO: it should already be loaded! this is just going to get me a reference to it, right?)
              if (S_OK == pRuntimeInfo->lpVtbl->GetInterface(pRuntimeInfo,
                &CLSID_CLRRuntimeHost,
                &IID_ICLRRuntimeHost,
                &pRuntime))
              {
                if (S_OK == pRuntime->lpVtbl->ExecuteInDefaultAppDomain(pRuntime,
                  dllPath, // L"CrazyNateManaged.dll", // assembly path
                  typeName, // L"CrazyNateManaged.ManagedEntryPoint", // type name
                  methodName, // L"Enter", // method name
                  argument, // L"and I mean it!", // argument
                  &returnValue)) // TODO: do I have any use for this?
                {
                  // great. Can I have a doughnut?
                  done = 1;
                }
                else
                {
                  StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"ignoring CLR because ICLRRuntimeHost.ExecuteInDefaultAppDomain(CrazyNateManaged.ManagedEntryPoint.Enter) failed\r\n");
                }

                pRuntime->lpVtbl->Release(pRuntime);
              }
              else
              {
                StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"ignoring CLR because ICLRRuntimeInfo.GetInterface failed\r\n");
              }
            }
            else
            {
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"found CLR, but ignoring because version is ");
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, versionBuffer);
              StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"\r\n");
            }
          }
          else
          {
            StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"found CLR, but ignoring because ICLRRuntimeInfo.GetVersionString() failed\r\n");
          }
          pRuntimeInfo->lpVtbl->Release(pRuntimeInfo);
        }
        if (numRuntimesEnumerated == 0)
        {
          StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"no CLR runtimes were loaded\r\n");
        }
        pRuntimes->lpVtbl->Release(pRuntimes);
      }
      else
      {
        StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"EnumerateLoadedRuntimes() failed\r\n");
      }
      pMetaHost->lpVtbl->Release(pMetaHost);
    }
    else
    {
      StringCchCat(errorMessageBuffer, ERROR_BUFFER_SIZE, L"CLRCreateInstance() failed\r\n");
    }
  }

  // release spin lock
  InterlockedExchange(&inputBufferLock, 0);

  return done;
}