githubEdit

Injecting .NET Assembly to an Unmanaged Process

Injecting .NET Assembly to an Unmanaged Process

This is a quick lab to see what API sequence makes it possible to inject C# .NET assemblies / PE files (.exe and .dll) into an unmanaged process and invoke their methods.

circle-info

This is the technique that makes execute-assembly command possible in Cobalt Strike.

Overview

At a high level, it works as follows:

  1. CLRCreateInstance is used to retrieve an interface ICLRMetaHostarrow-up-right

  2. ICLRMetaHost->GetRuntime is used to retrieve ICLRRuntimeInfoarrow-up-right interface for a specified CLR version

  3. ICLRRuntimeInfo->GetInterface is used to load the CLR into the current process and retrieve an interface ICLRRuntimeHostarrow-up-right

  4. ICLRRuntimeHost->Start is used to initialize the CLR into the current process

  5. ICLRRuntimeHost->ExecuteInDefaultAppDomain is used to load the C# .NET assembly and call a particular method with an optionally provided argument

Code

  • unmanaged.cpp (in my lab compiled to LoadCLR.exe) - a C++ program that loads a C# assembly

    CLRHello1.exe and invokes its method spotlessMethod

  • managed.cs (in my lab compiled to CLRHello1.exe) - a C# program that is loaded by the unmanaged process (LoadCLR.exe). It has a method spotlessMethod that is invoked via ExecuteInDefaultAppDomain.O

Once invoked, the spotlessMethod prints out Hi from CLR to the console window.

Demo

Below shows how LoadCLR.exe loaded our C# assembly CLRHello.exe (seen in LoadCLR.exe loaded modules tab) and invoked the spotlessMethod, that printed Hi from CLR to the console:

References

Last updated