首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在MSIL中调用正在执行的程序集之外的方法?

如何在MSIL中调用正在执行的程序集之外的方法?
EN

Stack Overflow用户
提问于 2020-11-18 10:19:36
回答 1查看 97关注 0票数 2

我可以使用这样的函数body中间语言:

代码语言:javascript
运行
复制
byte[] ilCodes = NestedFooInfo.GetMethodBody().GetILAsByteArray();

我能够修改它的IL代码,以便在执行方法主体之前调用以下方法OnChangeField

代码语言:javascript
运行
复制
public static void OnChangeField()
{
    Console.WriteLine("VICTORY");
    return;
}

到目前为止我是这样做的:

我将调用指令定义为要调用的方法:

代码语言:javascript
运行
复制
MethodInfo OnStfld = typeof(MethodBoundaryAspect).GetMethod("OnChangeField");
byte[] callIL = new byte[5];
callIL[0] = (byte)OpCodes.Call.Value;
callIL[1] = (byte)(OnStfld.MetadataToken & 0xFF);
callIL[2] = (byte)(OnStfld.MetadataToken >> 8 & 0xFF);
callIL[3] = (byte)(OnStfld.MetadataToken >> 16 & 0xFF);
callIL[4] = (byte)(OnStfld.MetadataToken >> 24 & 0xFF);

注意,OnChangeField位于MethodBoundaryAspect类中。该类位于编辑的方法程序集之外。

我就是这样修改原始(NestedFoo(...))方法主体的:

代码语言:javascript
运行
复制
byte[] ilCodes = NestedFooInfo.GetMethodBody().GetILAsByteArray();
InjectionHelper.UpdateILCodes(NestedFooInfo, callIL.Concat(ilCodes).ToArray());

我得到了一个:

System.BadImageFormatException:“未找到索引”( HRESULT: 0x80131124中的例外)

但是,只有在挂钩方法OnChangeField在外部(至少我理解)的情况下,执行才是可靠的。如果我将OnChangeField移动到与NestedFoo相同的类中,或者在NestedFoo的程序集的另一个类中,它将完美地工作。

据我所知,元数据指向一个无效的内存位置。有办法改变这种状况吗?

这里的引用是:修改后的方法的方法主体是什么样子的:

代码语言:javascript
运行
复制
public class ExceptionHandlingService : IExceptionHandlingService
{
        public static string var1 = "initialValue";
        public static string Var2 { get; set; } = "initialValue";
        public string var3 = "initialValue";
        public string Var4 { get; set; } = "initialValue";

        public string NestedFoo(SampleClass bar)
        {
            var1 = "value set in NestedFoo()";
            Var2 = "value set in NestedFoo()";
            var3 = "value set in NestedFoo()";
            Var4 = "value set in NestedFoo()";
            AddPerson("From", "NestedFoo", 2);
            return Foo();
        }
        [...]
}

以及我如何称之为改变的方法:

代码语言:javascript
运行
复制
var a = new ExceptionHandlingService();
var b = new SampleClass("bonjour", 2, 3L); // Not really relevant
a.NestedFoo(b);

对于那些想知道InjectionHelper.UpdateILCodes(NestedFooInfo, newIlCodes);中会发生什么的人,您可以检查此链接,它显示了如何在运行时编辑Il代码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-24 14:57:29

您需要向MemberRef和连续的TypeRefTypeSpec元数据表添加记录,以包含对类型的引用并引用这些标记。这也涉及到正确地写签名点。

参见分区II 22.38,22.25 of ECMA-335

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64891113

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档