Copy method from another AppDomain's assembly and execute it from CurrentDomain

旧巷老猫 提交于 2019-12-10 17:40:04

问题


In the big picture I am trying to execute method from dll in the main domain but after that, unload that dll. So far I've created new AppDomain loaded the Assembly\dll there, with MarshalByRefObject I fetched the body and MaxStackSize of the method to the main domain, created DynamicMethod there, recreated the body inside it and invoked it. But when I invoke it I get exception: System.BadImageFormatException: Signature is not IMAGE_CEE_CS_CALLCONV_LOCAL_SIG.

The code that fetches and invokes it:

DynamicMethod method = new DynamicMethod( "func", typeof( void ), new Type[ 0 ] );
var info = method.GetDynamicILInfo( );
info.SetCode( marshal.GetILCode( ), marshal.GetMaxStackSize());
info.SetLocalSignature(
    SignatureHelper.GetMethodSigHelper( CallingConventions.Standard, typeof( void ) ).GetSignature( ) );
method.Invoke( null, new object[ 0 ] ); //<-- exception here

marshal is an object of type Proxy. Some notes that might be necessary:

  1. The method that I am fetching\invoking is public static void Run();.
  2. The AppDomain that trying to invoke the method and the AppDomain that loads the dll\assembly have the same references.

Edit

I fixed the signature with changing the first byte to 0x07 from the GetSignature method. But there's new problem System.InvalidProgramException: Common Language Runtime detected an invalid program.


回答1:


Your implementation has a big fault, the byte array from MethodBase.GetMethodBody is not portable.

A method invocation using OpCodes.Call or OpCodes.Callvirt results in several bytes, one indicating the type of call (call/callvirt) followed by four bytes that represents a metadata token. This token can, in this case, be parsed as an Int32 and resolved to a MethodBase using Module.ResolveMethod.

Note that these metadata tokens are generated at compile time; they may differ between compilations. (While it's an implementation detail of the compiler, I believe they are just auto-incremented numbers based on the order of the methods seen during compilation.)

This means that the actual bytes you're trying to use contains metadata tokens that are invalid in your dynamic module. They may point to an existing method with a different signature than you're expecting, or may not be present at all in your module.

You would need to parse your il-code and emit everything again, thus generating new and valid metadata tokens.



来源:https://stackoverflow.com/questions/24350769/copy-method-from-another-appdomains-assembly-and-execute-it-from-currentdomain

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!