Skip to content

Instantly share code, notes, and snippets.

@xpn
Created April 11, 2018 21:34
Show Gist options
  • Save xpn/e95a62c6afcf06ede52568fcd8187cc2 to your computer and use it in GitHub Desktop.
Save xpn/e95a62c6afcf06ede52568fcd8187cc2 to your computer and use it in GitHub Desktop.

Revisions

  1. xpn created this gist Apr 11, 2018.
    71 changes: 71 additions & 0 deletions clr_via_native.c
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,71 @@
    #include "stdafx.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;

    printf("CLR via native code.... @_xpn_\n\n");

    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);
    }
    }
    }

    // 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"myassembly.dll",
    L"myassembly.Program",
    L"test",
    L"argtest",
    &result
    ) != S_OK) {
    printf("[x] Error: ExecuteInDefaultAppDomain(..) failed\n");
    return 2;
    }
    printf("[*] ======= Done =======\n");


    return 0;
    }