提问人:jmucchiello 提问时间:9/2/2023 更新时间:9/3/2023 访问量:72
在 C# Harmony 修补中。如何将 CodeInstruction.labels 中的标签与已知标签值进行比较
In C# Harmony patching. how do you compare the labels in CodeInstruction.labels to known label values
问:
所以我有一个 IL 代码流,如下所示:
IL_0047: ldarg.0
IL_0048: ldc.i4.m1
IL_0049: stfld int32 classname/innerclassname::'<>1__state'
IL_004e: ldstr ""
IL_0053: call void classname::set_aProperty(string)
IL_0058: ldstr ""
IL_005d: call void classname::set_aProperty(string)
IL_0062: call int32 classname::get_aProperty()
IL_0067: ldc.i4.8
IL_0068: ble.s IL_0076
我想用跳转到IL_0067(例如)替换IL_004e。System.Reflection.Emit.Label 类是不透明的。你可以比较相等。但是,除非您已经通过反射找到了标签,否则无法指定要与之比较的标签。所以,虽然我可以看到存在一个标签,但我不知道它是什么标签。Label.ToString() 只返回 “System.Reflection.Emit.Label”。有没有办法创建标签:
if (instruction.labels.Contains(x => x == Label.FromString("IL_0067")))
还是一些类似的扩展方法?
答:
0赞
jdewi
9/3/2023
#1
根据这个问题的答案,标签是为了方便而抽象的;在程序集的字节码中,跳转的操作数是相对于下一条指令的偏移量。据我所知,没有现有的方法可以从反编译器生成的标签名称生成System.Reflection.Emit.Label的实例。
但是,您可以将 an 注入到转译器中,该转译器可用于通过 ILGenerator.DefineLabel 创建新标签。您可以使用此标签作为跳转的操作数,并将其添加到要跳转到的指令字段中。您可以通过查找一些上下文来找到该目标指令,例如,在 to 之后的第一条指令。ILGenerator
.labels
call
classname.get_aProperty
有关更多信息,您可以查看 Harmony 文档:Transpiler - CodeInstruction。
评论
0赞
jmucchiello
9/3/2023
生成跳转到标签很简单。不是我想要的。我希望能够扫描 IL,直到我到达已知的标签,这似乎是不可能的。显然,CodeMatch 类是扫描现有代码的“正确”方法。
评论