im trying to load a managed c++/cli dll into a native process so i created a bootstrap dll that start the clr and call the managed dll, everything works fine but i can't kill/unload the clr this is the code. InitCLR and FinitCLR are called by the injector the call to UnloadAppDomain return 0x80131015, and the GetAppdomainId managed function is a function that return AppDomain::CurrentDomain->Id;
auto StartCLR(std::wstring clr_version) -> ICLRRuntimeHost * {
ICLRMetaHost *meta_host = nullptr;
ICLRRuntimeInfo *runtime_info = nullptr;
ICLRRuntimeHost *runtime_host = nullptr;
if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, reinterpret_cast<LPVOID *>(&meta_host)) == S_OK) {
if (meta_host->GetRuntime(clr_version.c_str(), IID_PPV_ARGS(&runtime_info)) == S_OK) {
BOOL loadable = false;
if (runtime_info->IsLoadable(&loadable) == S_OK && loadable) {
if (runtime_info->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&runtime_host)) == S_OK) {
return runtime_host;
}
}
}
}
if (meta_host) {
meta_host->Release();
}
if (runtime_info) {
runtime_info->Release();
}
if (runtime_host) {
runtime_host->Release();
}
return nullptr;
}
extern "C" __declspec(dllexport) int InitCLR() {
if (pCLR) {
MessageBoxA(NULL, "CLR already initialized", "", NULL);
return 1;
}
pCLR = StartCLR(L"v4.0.30319");
if (!pCLR) {
MessageBoxA(NULL, "StartCLR failed", "", NULL);
return 1;
} else {
pCLR->Start();
}
DWORD result = 0;
auto err = pCLR->ExecuteInDefaultAppDomain(managed_DLL_PATH.c_str(), L"Managed.Helpers", L"Say", L"Hello", &result);
if (err != S_OK) {
MessageBoxA(NULL, "ExecuteInDefaultAppDomain failed", "", NULL);
return 1;
}
return 0;
}
extern "C" __declspec(dllexport) int FinitCLR() {
if (!pCLR) {
MessageBoxA(NULL, "CLR is noy initialized", "", NULL);
return 1;
}
DWORD current_appdomain_id = 0;
auto err = pCLR->ExecuteInDefaultAppDomain(managed_DLL_PATH.c_str(), L"Managed.Helpers", L"GetAppdomainId", L"", ¤t_appdomain_id);
if (err != S_OK) {
MessageBoxA(NULL, "ExecuteInDefaultAppDomain(GetAppdomainId) failed", "", NULL);
return 1;
}
err = pCLR->UnloadAppDomain(current_appdomain_id, true);
if (err != S_OK) {
MessageBoxA(NULL, "UnloadAppDomain failed", "", NULL);
return 1;
}
pCLR->Stop();
pCLR->Release();
pCLR = nullptr;
return 0;
}
Unfortunately unloading a once loaded CLR is not possible as stated here in the Important section:
This method does not release resources to the host, unload application domains, or destroy threads. You must terminate the process to release these resources.
User contributions licensed under CC BY-SA 3.0