I'm writing a .NET library to inject managed DLLs into external processes. My current approach is:
- Use
CreateRemoteThread
to force the target process to callLoadLibrary
on an unmanaged bootstrap DLL. From this point we're executing code in the target process. - My bootstrap DLL then creates an instance of the CLR and calls
ExecuteInDefaultAppDomain
on it, which executes a method in a managed helper DLL. - This method creates a new AppDomain and calls
AppDomain.CreateInstanceFromAndUnwrap
to pass execution into my payload DLL, casting the result as anIInjectionPayload
. - The idea is that my payload DLL exposes a class which implements
IInjectionPayload
, so the helper DLL can simply callpayload.Run()
.
I'm doing it this way so that the payload code can be completely unloaded by simply calling AppDomain.Unload
(after signalling it to clean up).
This approach works - the class in my payload DLL is getting instantiated in the target process, so code can be executed - but I can't cast the object returned by CreateInstanceFromAndUnwrap
to an IInjectionPayload
; it throws the following exception:
Unable to cast transparent proxy to type 'blah.Blah.IInjectionPayload'.
I've tried using CreateInstanceAndUnwrap
, and Activator.CreateInstanceFrom
followed by Object.Unwrap
, but both of these methods also cause the same exception to be thrown.
The signature of my payload class is:
public class Program : MarshalByRefObject, IInjectionPayload
I'm stumped because the payload DLL is definitely getting loaded and the class is being instantiated, as intended. Any help would be much appreciated.
Found the fix for this problem here: http://www.west-wind.com/WebLog/posts/601200.aspx
It looks like a bug in the .NET framework. The solution is to add a handler to
AppDomain.CurrentDomain.AssemblyResolve
which manually loads & returns the assembly atargs.Name
. Then you can callCreateInstanceFromAndUnwrap
without it throwing an exception.