Example #1
0
static void InitializeClr(void)
{
	ICorRuntimeHost *runtimeHost;

	if (FAILED(CorBindToRuntimeEx(NULL, NULL,
	    STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | STARTUP_CONCURRENT_GC,
	    CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&runtimeHost))) {
		return;
	}

	runtimeHost->Start();

	IUnknownPtr punkAppDomain = NULL;
	runtimeHost->GetDefaultDomain(&punkAppDomain);

	punkAppDomain->QueryInterface(__uuidof(mscorlib::_AppDomain), (void **)&l_AppDomain);

	runtimeHost->Release();
}
DWORD initialize_dotnet_host()
{
	HRESULT hr = S_OK;
	ICLRMetaHost* clrMetaHost = NULL;
	ICLRRuntimeInfo* clrRuntimeInfo = NULL;
	ICorRuntimeHost* clrCorRuntimeHost = NULL;
	IUnknownPtr clrAppDomain = NULL;
	_AppDomainPtr clrAppDomainInterface = NULL;
	_AssemblyPtr clrPowershellAssembly = NULL;
	_TypePtr clrPowershellType = NULL;
	SAFEARRAY* clrByteArray = NULL;
	HMODULE hMsCoree = NULL;

	do
	{
		dprintf("[PSH] Locating CLR instance ...");
		hMsCoree = LoadLibraryA("mscoree.dll");
		if (hMsCoree == NULL)
		{
			hr = (HRESULT)GetLastError();
			dprintf("[PSH] Failed to load mscoree, .NET probably isn't installed. 0x%x", hr);
			break;
		}

		pClrCreateInstance clrCreateInstance = (pClrCreateInstance)GetProcAddress(hMsCoree, "CLRCreateInstance");
		if (clrCreateInstance != NULL)
		{
			dprintf("[PSH] .NET 4 method in use");

			if (FAILED(hr = clrCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&clrMetaHost))))
			{
				dprintf("[PSH] Failed to create instace of the CLR metahost 0x%x", hr);
				break;
			}

			dprintf("[PSH] Getting a reference to the .NET runtime");
			if (FAILED(hr = clrMetaHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&clrRuntimeInfo))))
			{
				dprintf("[PSH] Failed to get runtime v2.0.50727 instance 0x%x", hr);
				if (FAILED(hr = clrMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&clrRuntimeInfo))))
				{
					dprintf("[PSH] Failed to get runtime v4.0.30319 instance 0x%x", hr);
					break;
				}
			}

			dprintf("[PSH] Determining loadablility");
			BOOL loadable = FALSE;
			if (FAILED(hr = clrRuntimeInfo->IsLoadable(&loadable)))
			{
				dprintf("[PSH] Unable to determine of runtime is loadable 0x%x", hr);
				break;
			}

			if (!loadable)
			{
				dprintf("[PSH] Chosen runtime isn't loadable, exiting.");
				break;
			}

			dprintf("[PSH] Instantiating the COR runtime host");
			hr = clrRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(&clrCorRuntimeHost));
			if (FAILED(hr))
			{
				dprintf("[PSH] Unable to get a reference to the COR runtime host 0x%x", hr);
				break;
			}
		}
		else
		{
			dprintf("[PSH] .NET 4 method is missing, attempting to locate .NEt 2 method");
			pCorBindToRuntime corBindToRuntime = (pCorBindToRuntime)GetProcAddress(hMsCoree, "CorBindToRuntime");
			if (corBindToRuntime == NULL)
			{
				dprintf("[PSH] Unable to find .NET clr instance loader");
				hr = E_NOTIMPL;
				break;
			}

			if (FAILED(hr = corBindToRuntime(L"v2.0.50727", L"wks", CLSID_CorRuntimeHost, IID_PPV_ARGS(&clrCorRuntimeHost))))
			{
				dprintf("[PSH] Unable to bind to .NET 2 runtime host: 0x%x", hr);
				break;
			}
		}

		dprintf("[PSH] Starting the COR runtime host");
		if (FAILED(hr = clrCorRuntimeHost->Start()))
		{
			dprintf("[PSH] Unable to start the COR runtime host 0x%x", hr);
			break;
		}

		dprintf("[PSH] Getting a ref to the app domain");
		if (FAILED(hr = clrCorRuntimeHost->GetDefaultDomain(&clrAppDomain)))
		{
			dprintf("[PSH] Unable to get the app domain 0x%x", hr);
			break;
		}

		dprintf("[PSH] Getting a ref to the app domain interface");
		if (FAILED(hr = clrAppDomain->QueryInterface(IID_PPV_ARGS(&clrAppDomainInterface))))
		{
			dprintf("[PSH] Unable to get the app domain interface 0x%x", hr);
			break;
		}

		dprintf("[PSH] CLR app domain ready to run, now loading the powershell runner");
		SAFEARRAYBOUND bounds[1];
		bounds[0].cElements = PSHRUNNER_DLL_LEN;
		bounds[0].lLbound = 0;

		clrByteArray = SafeArrayCreate(VT_UI1, 1, bounds);
		if (clrByteArray == NULL)
		{
			dprintf("[PSH] Failed to create a usable safe array");
			hr = ERROR_OUTOFMEMORY;
			break;
		}

		if (FAILED(hr = SafeArrayLock(clrByteArray)))
		{
			dprintf("[PSH] Safe array lock failed 0x%x", hr);
			break;
		}
		memcpy(clrByteArray->pvData, PowerShellRunnerDll, PSHRUNNER_DLL_LEN);
		SafeArrayUnlock(clrByteArray);

		if (FAILED(hr = clrAppDomainInterface->Load_3(clrByteArray, &clrPowershellAssembly)))
		{
			dprintf("[PSH] Failed to load the powershell runner assembly 0x%x", hr);
			break;
		}

		dprintf("[PSH] Loading the type from memory");
		_bstr_t pshClassName("MSF.Powershell.Runner");
		if (FAILED(hr = clrPowershellAssembly->GetType_2(pshClassName, &clrPowershellType)))
		{
			dprintf("[PSH] Unable to locate the powershell class type 0x%x", hr);
			break;
		}

		dprintf("[PSH] Runtime has been initialized successfully");

	} while(0);

	if (clrByteArray != NULL)
	{
		SafeArrayDestroy(clrByteArray);
	}

	if (FAILED(hr))
	{
		SAFE_RELEASE(clrPowershellAssembly);
		SAFE_RELEASE(clrAppDomainInterface);
		SAFE_RELEASE(clrCorRuntimeHost);
		SAFE_RELEASE(clrRuntimeInfo);
		SAFE_RELEASE(clrMetaHost);
		return (DWORD)hr;
	}

	gClrMetaHost = clrMetaHost;
	gClrRuntimeInfo = clrRuntimeInfo;
	gClrCorRuntimeHost = clrCorRuntimeHost;
	gClrAppDomainInterface = clrAppDomainInterface;
	gClrAppDomain = clrAppDomain;
	gClrPowershellAssembly = clrPowershellAssembly;
	gClrPowershellType = clrPowershellType;
	return ERROR_SUCCESS;
}
Example #3
0
unsigned __stdcall ThreadProc(void *pArg)
{
    RuntimeAndApp *pContext = (RuntimeAndApp *)pArg;

    HRESULT hr;

#define IfFailGoMsg(MSG)                                                        \
    if (FAILED(hr))                                                             \
    {                                                                           \
        printf("Runtime %d (%S): " MSG " (%x)\n",                               \
            pContext->m_dwRuntimeNo,                                            \
            pContext->m_pwzRuntimeVer,                                          \
            hr);                                                                \
        goto lExit;                                                             \
    }

    ICLRRuntimeHost  *pHost_V2 = NULL;
    ICorRuntimeHost     *pHost = NULL;
    IUnknown             *pUnk = NULL;
    mscorlib::_AppDomain  *pAD = NULL;

    // Get ICorRuntimeHost to execute the app.
    hr = pContext->m_pRuntime->GetInterface(
        CLSID_CorRuntimeHost,
        IID_ICorRuntimeHost,
        (LPVOID *)&pHost);
    IfFailGoMsg("Failed to load the runtime");

	// Also try to get ICLRRuntimeHost which has a useful Stop method. (ICorRuntimeHost::Stop is empty.)
    if (SUCCEEDED(pContext->m_pRuntime->GetInterface(
        CLSID_CLRRuntimeHost,
        IID_ICLRRuntimeHost,
        (LPVOID *)&pHost_V2)))
    {
        hr = pHost_V2->Start();
        IfFailGoMsg("Failed to start ICLRRuntimeHost");
    }

    ReportSyncPoint(SyncPointRuntimeStart, pContext->m_dwRuntimeNo);
    hr = pHost->Start();
    IfFailGoMsg("Failed to start ICorRuntimeHost");

    if(g_options.m_bUseDefaultAppDomain)
    {
        hr = pHost->GetDefaultDomain(&pUnk);
        IfFailGoMsg("Failed to get default domain");
    }
    else
    {
        hr = pHost->CreateDomain(L"AD2",NULL,&pUnk);
        IfFailGoMsg("Failed to create AppDomain");
    }

    hr = pUnk->QueryInterface(__uuidof(mscorlib::_AppDomain), (LPVOID *)&pAD);
    IfFailGoMsg("Failed to QI for _AppDomain");

    BSTR bstrPath = SysAllocString(pContext->m_pwzAppPath);
    SAFEARRAY *rgArgs = CreateArgList(pContext->m_pwzAppArgs);

    ReportSyncPoint(SyncPointApplicationStart, pContext->m_dwRuntimeNo);

    if (g_options.m_bUseLoadByName)
    {
        hr = ExecuteAssemblyByName(pAD, bstrPath, rgArgs, &pContext->m_dwRetCode);
    }
    else
    {
        hr = pAD->ExecuteAssembly_3(bstrPath, NULL, rgArgs, &pContext->m_dwRetCode);
    }

    if (hr == COR_E_NEWER_RUNTIME)
    {
        IfFailGoMsg("Failed to execute assembly\nWas it built by a compiler that is newer than this runtime?");
    }
    else
    {
        // we don't know whether the error comes from the runtime (failed to execute assembly) or
        // the assembly actually ran and threw an unhandled exception that was converted to the HR
        IfFailGoMsg("ExecuteAssembly returned an error code");
    }

    SysFreeString(bstrPath);
    SafeArrayDestroy(rgArgs);


    if(!g_options.m_bUseDefaultAppDomain)
    {	
        ReportSyncPoint(SyncPointAppDomainUnload, pContext->m_dwRuntimeNo);
        hr = pHost->UnloadDomain(pAD);
        IfFailGoMsg("Failed to unload AppDomain");
    }
    pAD->Release();  pAD = NULL;
    pUnk->Release(); pUnk = NULL;

    hr = pHost->Stop();
    IfFailGoMsg("Failed to stop ICorRuntimeHost");

    if (pHost_V2 != NULL)
    {
        hr = pHost_V2->Stop();
        IfFailGoMsg("Failed to stop ICLRRuntimeHost");

        pHost_V2 = NULL;
    }

lExit:
    if (pHost_V2 != NULL)
        pHost_V2->Release();

    if (pAD != NULL)
        pAD->Release();

    if (pUnk != NULL)
        pUnk->Release();

    if (pHost != NULL)
        pHost->Release();

    if (g_options.m_bRunMultithreaded)
    {
        // make sure we don't deadlock the other thread
        // this is also needed if the value of g_options.m_dwADUnloadOrder is SameOrder or ReverseOrder
        // since one of the threads will be waiting for the other one to Unload the AppDomain.
        SetEvent(g_rhndEvents[pContext->m_dwRuntimeNo - 1]);

        _endthreadex(0);
    }
    return 0;

#undef IfFailGoMsg
}
Example #4
0
int __stdcall invokeCLR( WCHAR* wszApplication){

    //Initializes the COM library

    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    ICorRuntimeHost* pHost           = NULL;
    IUnknown*        pAppDomainThunk = NULL;
    _AppDomain*      pAppDomain      = NULL;
    long             lReturn         = 0;

    // Load CLR into the process

    HRESULT hr = CorBindToRuntimeEx(NULL,NULL,0,CLSID_CorRuntimeHost,IID_ICorRuntimeHost,(VOID**)&pHost);

    if(!FAILED(hr)) {

        // Start the CLR

        hr = pHost->Start();
        if(!FAILED(hr)) {

            // Get the _AppDomain interface

            hr = pHost->GetDefaultDomain(&pAppDomainThunk);
            if(!FAILED(hr)) {

                hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain), (void**)&pAppDomain);
                if(!FAILED(hr)) {

                    // Execute assembly

                    hr = pAppDomain->ExecuteAssembly_2(_bstr_t(wszApplication), &lReturn);
                    if (FAILED(hr)) {

                        printf("_AppDomain::ExecuteAssembly_2 failed with hr=0x%x.\n", hr);
                        lReturn = -1;
                    }

                }else{
                    printf("Can't get System::_AppDomain interface\n");
                    lReturn = -2;
                }

            }else{
                printf("ICorRuntimeHost->GetDefaultDomain failed with hr=0x%x.\n", hr);
                lReturn = -3;
            }
        }else{
            printf("ICorRuntimeHost->Start failed with hr=0x%x.\n", hr);
            lReturn = -4;
        }

    }else{
        printf("CorBindToRuntimeHost failed with hr=0x%x.\n", hr);
        lReturn = -5;
    }

    // print the error message description if needed

    if(FAILED(hr)){
        LPVOID lpMsgBuf = NULL;

        FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM |
                FORMAT_MESSAGE_IGNORE_INSERTS,
                NULL,
                hr,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &lpMsgBuf,
                0,
                NULL );
        if(lpMsgBuf != NULL)
            printf("Message:%s\n",lpMsgBuf);
        else
            printf("No translation of 0x%x\n",hr);
    }

    // close COM library

    CoUninitialize();

    return lReturn;
}
int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT hr;

	ICLRMetaHost *pMetaHost = NULL;
	ICLRRuntimeInfo *pRuntimeInfo = NULL;
	ICorRuntimeHost *pCorRuntimeHost = NULL;

	IUnknownPtr spAppDomainThunk = NULL;
	_AppDomainPtr spDefaultAppDomain = NULL;

	// The .NET assembly to load.
	bstr_t bstrAssemblyName("PowerShellRunner");
	_AssemblyPtr spAssembly = NULL;

	// The .NET class to instantiate.
	bstr_t bstrClassName("PowerShellRunner.PowerShellRunner");
	_TypePtr spType = NULL;


	// Start the runtime
	hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
	if (FAILED(hr))
	{
		wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hr = pMetaHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&pRuntimeInfo));
	if (FAILED(hr))
	{
		wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Check if the specified runtime can be loaded into the process.
	BOOL fLoadable;
	hr = pRuntimeInfo->IsLoadable(&fLoadable);
	if (FAILED(hr))
	{
		wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	if (!fLoadable)
	{
		wprintf(L".NET runtime v2.0.50727 cannot be loaded\n");
		goto Cleanup;
	}

	// Load the CLR into the current process and return a runtime interface
	hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,
		IID_PPV_ARGS(&pCorRuntimeHost));
	if (FAILED(hr))
	{
		wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Start the CLR.
	hr = pCorRuntimeHost->Start();
	if (FAILED(hr))
	{
		wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}


	// Get a pointer to the default AppDomain in the CLR.
	hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
	if (FAILED(hr))
	{
		wprintf(L"ICorRuntimeHost::GetDefaultDomain failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
	if (FAILED(hr))
	{
		wprintf(L"Failed to get default AppDomain w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Load the .NET assembly.
	// (Option 1) Load it from disk - usefully when debugging the PowerShellRunner app (you'll have to copy the DLL into the same directory as the exe)
	//hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);
	
	// (Option 2) Load the assembly from memory
	SAFEARRAYBOUND bounds[1];
	bounds[0].cElements = PowerShellRunner_dll_len;
	bounds[0].lLbound = 0;

	SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds);
	SafeArrayLock(arr);
	memcpy(arr->pvData, PowerShellRunner_dll, PowerShellRunner_dll_len);
	SafeArrayUnlock(arr);

	hr = spDefaultAppDomain->Load_3(arr, &spAssembly);

	if (FAILED(hr))
	{
		wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Get the Type of PowerShellRunner.
	hr = spAssembly->GetType_2(bstrClassName, &spType);
	if (FAILED(hr))
	{
		wprintf(L"Failed to get the Type interface w/hr 0x%08lx\n", hr);
		goto Cleanup;
	}

	// Call the static method of the class
	wchar_t* argument = L"Get-Process\n\
						 #This is a PowerShell Comment\n\
						 Write-Host \"`n`n*******  The next command is going to throw an exception.  This is planned *********`n`n\"\n\
						 Read-Host\n";
	
	InvokeMethod(spType, L"InvokePS", argument);

Cleanup:

	if (pMetaHost)
	{
		pMetaHost->Release();
		pMetaHost = NULL;
	}
	if (pRuntimeInfo)
	{
		pRuntimeInfo->Release();
		pRuntimeInfo = NULL;
	}
	if (pCorRuntimeHost)
	{
		pCorRuntimeHost->Release();
		pCorRuntimeHost = NULL;
	}

	return 0;
}