Jai*_*ews 1 .net mono mono.cecil
我有这个方法:
public int Test()
{
ExternalClass cls = new ExternalClass();
return cls.ExternalMethod();
}
Run Code Online (Sandbox Code Playgroud)
我需要使用IL Injection更改它,因此我可以将类型作为参数传递并删除直接对象创建,如下所示:
public int Test(ExternalClass cls)
{
return cls.ExternalMethod();
}
Run Code Online (Sandbox Code Playgroud)
我可以使用<>.Parameters.Add(_ ___)添加附加参数,并生成新的Assembly.
问题是我无法删除新对象创建的指令.以下是我用来删除它的行.
ILProcessor ilProcessor = <<MethodDefinition>>.Body.GetILProcessor();
ilProcessor.Remove(<<newobj instruction>>);
Run Code Online (Sandbox Code Playgroud)
一旦我尝试调用如下所示的修改后的汇编方法,就会抛出错误"Common Language Runtime检测到无效程序".
ExternalClass ext = new ExternalClass();
int i = prg1.Test(ext);
Run Code Online (Sandbox Code Playgroud)
我知道我可能也需要处理内存分配相关的东西.如果有人能够在这里提供额外的步骤,我将不胜感激.
你不能只是删除newobj指令; 你留下了一个无效的程序,正如运行时告诉你的那样.这里大致是原始方法如何转换为IL:
public Int32 Test()
{
.local ExternalClass 0;
// ExternalClass cls = new ExternalClass();
newobj class ExternalClass();
stloc.0;
// return cls.ExternalMethod();
ldloc.0;
callvirt Int32 class ExternalClass:ExternalMethod();
ret;
}
Run Code Online (Sandbox Code Playgroud)
如果仅删除newobj指令,则stloc指令将不会在堆栈中存储任何内容以存储在本地.您需要将方法转换为:
public Int32 Test(ExternalClass cls)
{
// return cls.ExternalMethod();
ldarg.1;
callvirt Int32 class ExternalClass:ExternalMethod();
ret;
}
Run Code Online (Sandbox Code Playgroud)
所以你需要做三件事:
ldloc指令.ldarg.1在方法的开头插入指令.或者,您也可以删除ExternalClass本地.(这将通过JIT编译器进行优化,但会使IL图像膨胀.)
| 归档时间: |
|
| 查看次数: |
416 次 |
| 最近记录: |