Listing 1 The Bind routine
//Bind routine works in the address space of the target process. //It uses CLR hosting interfaces to inject an agent into the CLR environment. enum HookErrors Bind() { TRACE("Bind()\n"); ICorRuntimeHost *l_pHost = NULL; HCORENUM l_hEnum = NULL; IUnknown * l_pUnknown = NULL; mscorlib::_AppDomain * l_pDomain = NULL; enum HookErrors l_eError = eNoErrors; try { LPWSTR l_pszVersion = NULL; HINSTANCE l_hMscoree = GetModuleHandle("mscoree"); if(l_hMscoree == NULL) { TRACE("GetModuleHandle(mscoree) returned NULL\n"); return eNoClrRuntime; } T_CorBindToRuntimeEx * l_pCorBindToRuntimeEx = (T_CorBindToRuntimeEx *) GetProcAddress(l_hMscoree, "CorBindToRuntimeEx"); if(l_pCorBindToRuntimeEx == NULL) { TRACE("GetProcAddress(CorBindToRuntimeEx) returned NULL\n"); return eCannotGetAddrCorBindToRuntimeEx; } HRESULT l_hResult = l_pCorBindToRuntimeEx(l_pszVersion, NULL, NULL, CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (void **)&l_pHost); if(FAILED(l_hResult) || !l_pHost) { TRACE("CorBindToRuntimeEx() failed. Result %d\n", l_hResult); return eCannotGetRuntimeHost; } l_hResult = l_pHost->EnumDomains(&l_hEnum); if (SUCCEEDED(l_hResult)) { while(SUCCEEDED(l_hResult = l_pHost->NextDomain(l_hEnum, &l_pUnknown)) && l_pUnknown) {//l_pUnknown is System.AppDomain interface l_pUnknown->QueryInterface(__uuidof(mscorlib::_AppDomain), (void**)&l_pDomain); if(l_pDomain) { _bstr_t l_Path(g_szAssemblyPath); _bstr_t l_Name(g_szAgentClass); SAFEARRAY * l_pArray; SAFEARRAYBOUND l_Bounds[1]; l_Bounds[0].lLbound = 0; l_Bounds[0].cElements = 1; l_pArray = SafeArrayCreate(VT_VARIANT, 1, l_Bounds); if(l_pArray == NULL) { TRACE("SafeArrayCreate failed\n"); l_eError = eSafeArrayFailure; } else { long l_Index; _variant_t l_Element(g_szServerURL); l_Index = 0; l_hResult = SafeArrayPutElement (l_pArray, &l_Index, &l_Element); if(FAILED(l_hResult)) { TRACE("SafeArrayPutElement failed. Result %d\n", l_hResult); l_eError = eSafeArrayFailure; } else { TRACE("Before CreateInstanceFrom_3\n"); mscorlib::_ObjectHandlePtr l_Handle = l_pDomain->CreateInstanceFrom_3(l_Path, l_Name, VARIANT_TRUE, mscorlib::BindingFlags_Default, NULL/*Binder*/, l_pArray, NULL/*culture*/, NULL/*activationAttributes*/, NULL/*securityAttributes*/); TRACE("CreateInstanceFrom_3 ret %x\n", l_Handle); l_eError = l_Handle? eNoErrors : eCreateInstanceFailed; } SafeArrayDestroy(l_pArray); } l_pDomain->Release(); l_pDomain = NULL; }//if(l_pDomain) l_pUnknown->Release(); l_pUnknown = NULL; }//while enum l_pHost->CloseEnum(l_hEnum); l_hEnum = NULL; }//if (SUCCEEDED(l_hResult)) else { TRACE("EnumDomains() failed. Result %d\n", l_hResult); l_eError = eEnumDomainsFailed; } } catch(...) { TRACE("Exception in Bind()\n"); l_eError = eException; } try { if(l_pHost) { if(l_pDomain) l_pDomain->Release(); if(l_pUnknown) l_pUnknown->Release(); if(l_hEnum) l_pHost->CloseEnum(l_hEnum); l_pHost->Release(); } } catch(...) { } TRACE("Bind() returns %d\n", l_eError); return l_eError; }//Bind