在大图中我试图从主域中的dll执行方法,但之后,卸载该DLL。到目前为止,我已经创建了新AppDomain
加载了Assembly
\ dll,MarshalByRefObject
我将方法的主体和MaxStackSize
提取到主域,创建了{{} 1}},重新创建其中的主体并调用它。
但是当我调用它时,我得到了异常:
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
是Proxy类型的对象。
一些可能需要的说明:
marshal
。public static void Run();
和加载dll \ assembly的AppDomain
具有相同的引用。修改
我修改了签名,将第一个字节从AppDomain
方法更改为0x07
。
但是有新问题GetSignature
答案 0 :(得分:2)
您的实现有一个很大的错误,来自MethodBase.GetMethodBody 的字节数组不可移植。
使用OpCodes.Call或OpCodes.Callvirt的方法调用会产生几个字节,一个指示调用类型(call / callvirt),后跟四个字节,表示元数据令牌。在这种情况下,此令牌可以解析为Int32并使用Module.ResolveMethod解析为MethodBase。
请注意,这些元数据令牌是在编译时生成的;它们可能在编译之间有所不同。 (虽然它是编译器的实现细节,但我相信它们只是基于编译期间看到的方法顺序的自动递增数字。)
这意味着您尝试使用的实际字节包含动态模块中无效的元数据令牌。他们可能会指出一种现有的方法,其签名不同于您期望的,或者可能根本不存在于您的模块中。
您需要解析您的il代码并再次发出所有内容,从而生成新的有效元数据标记。