【问题标题】:Why this modified assembly does not run? (JIT Compiler encountered an internal limitation.)为什么这个修改后的程序集不运行? (JIT 编译器遇到内部限制。)
【发布时间】:2012-05-22 13:41:40
【问题描述】:

我已经修改了程序集的字节码以消除错误,现在当我尝试使用它时,我得到了 InvalidProgramException。 我所做的就是用 NOPS 替换这段代码:

catch (Exception exception1)
{
    Exception exception = exception1;
    if (exception as InvalidValueException == null)
    {
        throw new InvalidGenerationException(2);
    }
    else
    {
        throw exception;
    }
}

IL 之前:

catch [mscorlib]System.Exception
{
    IL_022f: stloc.s exception
    IL_0231: ldloc.s exception
    IL_0233: isinst Custom.InvalidValueException
    IL_0238: brfalse.s IL_023d

    IL_023a: ldloc.s exception
    IL_023c: throw

    IL_023d: ldc.i4.1
    IL_023e: newobj instance void Custom.InvalidGenerationException ...
    IL_0243: throw
}

IL 之后:

catch [mscorlib]System.Exception
{
    IL_022f: nop
    IL_0230: nop
    IL_0231: nop
    IL_0232: nop
    IL_0233: nop
    IL_0234: nop
    IL_0235: nop
    IL_0236: nop
    IL_0237: nop
    IL_0238: nop
    IL_0239: nop
    IL_023a: nop
    IL_023b: nop
    IL_023c: nop
    IL_023d: nop
    IL_023e: nop
    IL_023f: nop
    IL_0240: nop
    IL_0241: nop
    IL_0242: nop
    IL_0243: nop
}

关于为什么这是错误的任何想法?

谢谢!

【问题讨论】:

  • 如果你删除所有的 nop 会发生什么?
  • 我无法使用我目前拥有的工具来更改程序集的长度,通常不是一个好主意(不确定 IL 是否有此类跳转)
  • 为什么不能简单地处理异常?吞下异常通常是个坏主意。
  • 因为不是我的代码,它是一个有缺陷的第 3 方程序集,并且它的第 3 方本身就是它在不应该处理异常时处理异常的一方。我正在等待第 3 方的新版本时解决此问题,这肯定需要一些时间。
  • Protip:在运行ilasm 后始终使用PEVerify

标签: bytecode .net-assembly il


【解决方案1】:

你原来的catch 块总是会抛出。也就是说,没有办法“正常”退出该块。

您修改后的catch 块不会抛出,因此您需要正常退出该块。您需要使用 leaveleave.s 来执行此操作。

(您可能还需要 pop 将捕获的异常从堆栈中删除以保持整洁。不过我不确定那个,您必须自己尝试一下。)

catch [mscorlib]System.Exception
{
    IL_022f: pop                // not certain if pop is necessary
    IL_0230: leave.s IL_0244
    IL_0232: nop
    IL_0233: nop
    IL_0234: nop
    IL_0235: nop
    IL_0236: nop
    IL_0237: nop
    IL_0238: nop
    IL_0239: nop
    IL_023a: nop
    IL_023b: nop
    IL_023c: nop
    IL_023d: nop
    IL_023e: nop
    IL_023f: nop
    IL_0240: nop
    IL_0241: nop
    IL_0242: nop
    IL_0243: nop
}
IL_0244: ret    // or whatever

【讨论】:

  • 离开指令清空评估堆栈,因此看起来不需要弹出。谢谢!
  • @SoMoS:我有一种感觉,可能是这种情况,但不是 100% 确定,也没有时间检查。
  • 是的,我知道,我只是把评论放上来供以后参考。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2014-09-19
  • 2020-03-06
  • 2015-12-20
  • 2014-06-09
  • 2013-05-16
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多