2017-02-11 133 views
2

我有一個.NET應用程序內的c + +代碼的字節數組。 我想執行這個.NET應用程序而不寫入磁盤上的這些字節。 ICLRRuntimeHost::ExecuteInDefaultAppDomain需要一個裝配路徑,所以它不在這裏。我正在尋找一種可能的方式(或黑客)將二進制文件直接傳遞給clr。運行.net應用程序從c + +

所以我能做什麼?

+0

@ user4581301正好。 – 0x3h

+2

您可以在本機C++中使用'_AppDomain'接口。它可以讓你調用它的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,你需要更多的只是本作的逆向工程它更難過程。