我现在正在做突变测试。我正在研究的突变之一涉及交换参数,我可能需要交换这些参数,例如 Ldarg.0
和 Ldarg_S
以及指示索引的操作数。
这个操作数类型是一个内联参数,在 Mono.Cecil 中我相信它需要我创建一个正确实例化的 ParameterDefinition
来存储 32 位 int 索引。有没有人对 Cecil 有足够的经验,可以为我指明正确的方向,以简单的方式创建一个 Instruction
实例,其中 OpCode
为 Ldarg_S
和适当类型的操作数
?
最佳答案
这里有两种操作码,ldarg.0
,和ldarg
(及其_s)变体。
第一个是“宏”操作码,这意味着它用于减少常用值的代码大小。
如果您需要修改方法的参数,我建议您首先将所有宏操作码转换为完整的形式,这是使用 SimplifyMacros()
完成的MethodBody
上的扩展方法来自辅助库 Mono.Cecil.Rocks:
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
// ..
method.Body.SimplifyMacros();
完成此操作后,现有的 ldarg.0
指令现在为 ldarg
使用正确的操作数,正如您所猜测的,a ParameterDefinition
.
完成后,您可以重新排序参数并创建新指令:
var il = method.Body.GetILProcessor();
var instruction = il.Create(OpCodes.Ldarg, aParameterDefinition);
il.InsertBefore(xxx, instruction);
完成后,您可以调用SimplifyMacros()
的逆函数。 , OptimizeMacros()
,如果可能的话,它将尝试将操作码优化为其宏形式。
您必须注意的一件事是,实例方法的第一个参数(隐式“this”)用 method.Body.ThisParameter
表示。您在方法的 .Parameters 集合中找不到的特殊参数。
关于.net - 使用 Mono.Cecil 创建带有内联参数的 IL 指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10231409/