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.
This is the technique that makes execute-assembly
command possible in Cobalt Strike.
Overview
At a high level, it works as follows:
CLRCreateInstance
is used to retrieve an interfaceICLRMetaHost
ICLRMetaHost->GetRuntime
is used to retrieveICLRRuntimeInfo
interface for a specified CLR versionICLRRuntimeInfo->GetInterface
is used to load the CLR into the current process and retrieve an interfaceICLRRuntimeHost
ICLRRuntimeHost->Start
is used to initialize the CLR into the current processICLRRuntimeHost->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 toLoadCLR.exe
) - a C++ program that loads a C# assemblyCLRHello1.exe
and invokes its methodspotlessMethod
managed.cs
(in my lab compiled toCLRHello1.exe
) - a C# program that is loaded by the unmanaged process (LoadCLR.exe
). It has a methodspotlessMethod
that is invoked viaExecuteInDefaultAppDomain.
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
https://gist.github.com/xpn/e95a62c6afcf06ede52568fcd8187cc2
Last updated