从另一个 AppDomain 的程序集中复制方法并从 CurrentDomain 执行它

2024-02-06

总体而言,我尝试从主域中的 dll 执行方法,但之后卸载该 dll。到目前为止我已经创建了新的AppDomain加载了Assembly\dll 在那里,与MarshalByRefObject我取回了尸体并MaxStackSize方法到主域,创建DynamicMethod在那里,在其中重新创建了身体并调用了它。 但是当我调用它时我得到异常:System.BadImageFormatException: Signature is not IMAGE_CEE_CS_CALLCONV_LOCAL_SIG.

获取并调用它的代码:

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是一个类型的对象Proxy http://pastebin.com/3yhPPcqN。 一些可能需要的注释:

  1. 我正在获取\调用的方法是public static void Run();.
  2. The AppDomain试图调用该方法和AppDomain加载 dll\程序集具有相同的引用。

Edit

我通过将第一个字节更改为来修复签名0x07来自GetSignature方法。 但又有新问题了System.InvalidProgramException: Common Language Runtime detected an invalid program.


你的实现有一个很大的错误,来自的字节数组MethodBase.GetMethodBody http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getmethodbody.aspx 不便于携带.

方法调用使用操作码调用 http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.call.aspx or 操作码.Callvirt http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.callvirt.aspx结果包含几个字节,其中一个表示调用类型 (call/callvirt),后跟四个字节,表示元数据令牌。在这种情况下,可以将此标记解析为 Int32 并使用以下方法解析为 MethodBase模块.ResolveMethod http://msdn.microsoft.com/en-us/library/k16h33dz.aspx.

请注意,这些元数据标记是在编译时生成的;它们在编译之间可能有所不同。 (虽然这是编译器的实现细节,但我相信它们只是根据编译期间看到的方法的顺序自动递增的数字。)

这意味着您尝试使用的实际字节包含在动态模块中无效的元数据标记。它们可能指向具有与您预期不同的签名的现有方法,或者可能根本不存在于您的模块中。

您需要解析您的 il 代码并再次发出所有内容,从而生成新的有效元数据令牌。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从另一个 AppDomain 的程序集中复制方法并从 CurrentDomain 执行它 的相关文章

随机推荐