2017-02-11 15 views
2

У меня есть байтовый массив .NET-приложения внутри C++-кода. Я хочу выполнить это приложение .NET без написания этих байтов на диске. ICLRRuntimeHost::ExecuteInDefaultAppDomain ожидает путь к сборке, поэтому он находится вне уравнения здесь. Я ищу возможный способ (или взломать), чтобы передать двоичный файл непосредственно в clr.running .net application from C++

Итак, что я могу сделать?

+0

@ пользователь4581301 точно. – 0x3h

+2

Интерфейс '_AppDomain' можно использовать в собственном C++. Это позволяет вам вызвать метод Load (byte []). Используйте ICorRuntimeHost :: GetDefaultDomain(). –

+0

@ HansPassant кажется отличной идеей, я попробую. – 0x3h

ответ

0
//todo error checks/cleanup 
HRESULT hr; 
ICLRMetaHost *pMetaHost = NULL; 
ICLRRuntimeInfo *pRuntimeInfo = NULL; 
ICorRuntimeHost *pCorRuntimeHost = NULL; 
IUnknownPtr spAppDomainThunk = NULL; 
_AppDomainPtr spDefaultAppDomain = NULL; 
bstr_t bstrAssemblyName(L""); 
_AssemblyPtr spAssembly = NULL; 
bstr_t bstrClassName(L""); 
_TypePtr spType = NULL; 
variant_t vtEmpty; 
bstr_t bstrStaticMethodName(L"Main"); 
variant_t vtLengthRet; 
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)); 
const wchar_t* pszVersion = L"v2.0.50727"; 
hr = pMetaHost->GetRuntime(pszVersion, IID_PPV_ARGS(&pRuntimeInfo)); 
BOOL fLoadable; 
hr = pRuntimeInfo->IsLoadable(&fLoadable); 
if (!fLoadable) { wprintf(L".NET runtime %s cannot be loaded\n", pszVersion); return; } 
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(&pCorRuntimeHost)); 
hr = pCorRuntimeHost->Start(); 
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk); 
hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain)); 
SAFEARRAYBOUND bounds[1]; 
bounds[0].cElements = array_len; 
bounds[0].lLbound = 0; 
SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds); 
SafeArrayLock(arr); 
memcpy(arr->pvData, bytearray, array_len); 
SafeArrayUnlock(arr); 
hr = spDefaultAppDomain->Load_3(arr, &spAssembly); 
hr = spAssembly->GetType_2(bstrClassName, &spType); 
hr = spType->InvokeMember_3(bstrStaticMethodName, static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public), NULL, vtEmpty, nullptr, &vtLengthRet); 
SafeArrayDestroy(arr); 

Обратите внимание, что в тот момент, программа загружается в память может быть легко сбрасывал на него первоначально .NET двоичный, вам нужно больше, чем просто это сделать процесс обратного проектирования его сложнее.