【问题标题】:Where do Label_ markers come from in Reflector and how to decipher them?Label_ 标记在 Reflector 中来自哪里以及如何破译它们?
【发布时间】:2009-09-02 13:33:33
【问题描述】:

我正在尝试了解一种使用 Reflector 反汇编功能的方法。任何使用过此工具的人都知道,某些代码显示时带有(可能)未在原始源代码中使用的 C# 标签。

在我查看的 110 行方法中,有 11 个标签语句。随机 sn-p 示例:

Label_0076:
    if (enumerator.MoveNext())
    {
        goto Label_008F;
    }
    if (!base.IsValid)
    {
        return;
    }
    goto Label_0219;
Label_0087:
    num = 0;
    goto Label_01CB;
Label_01CB:
    if (num < entityArray.Length)
    {
        goto Label_0194;
    }
    goto Label_01AE;
Label_01F3:
    num++;
    goto Label_01CB;

是什么代码让Reflector到处显示这些标签,为什么不能反汇编?

有破解它们的好方法吗?

【问题讨论】:

    标签: c# .net reflector disassembly


    【解决方案1】:

    实际上,C# 编译器并没有做太多的优化——它把优化留给了 JIT 编译器(或 ngen)。因此,它生成的 IL 非常一致且可预测,这就是 Reflector 等工具能够如此有效地反编译 IL 的原因。编译器确实转换您的代码的一种情况是在 iterator 方法中。您正在查看的方法可能包含以下内容:

    foreach(var x in something)
      if(x.IsValid)
        yield return x;
    

    由于迭代器转换可能非常复杂,Reflector 无法真正处理它。要熟悉要查找的内容,请编写您自己的迭代器方法并通过 Reflector 运行它们,以查看基于您的 C# 代码生成的 IL 类型。然后你就会知道要寻找什么。

    【讨论】:

      【解决方案2】:

      您正在查看编译器生成的代码。编译器不尊重你。不完全是。它也不尊重我或其他任何人。它查看我们的代码,嘲笑我们,然后重写它以尽可能高效地运行。

      嵌套 if 语句、递归、“yield”、case 语句和其他代码快捷方式会导致代码看起来很奇怪。而且,如果您使用带有很多外壳的 lambda,那么不要指望它会很漂亮。

      编译器可以在任何地方、任何机会​​重写您的代码以使其运行得更快。所以没有任何一种“代码”会导致这种情况。 Reflector 尽最大努力反汇编,但它无法从重写后的版本中推断出作者的原始代码。它尽最大努力(有时甚至是不正确的!)将 IL 转换为某种形式的可接受代码。

      如果您难以破译它,您可以手动编辑代码以内联只被调用一次的 goto,并将多次调用的 goto 重构为方法调用。另一种选择是反汇编成另一种语言。将 IL 翻译成高级语言的代码是不一样的。 C++/CLI 反编译器可能会为您做得更好,并且仍然足够相似(查找/替换 -> 用 .)以便于理解。

      这真的没有灵丹妙药;至少在有人写出更好的反汇编插件之前不会。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-12
        • 2014-04-25
        • 1970-01-01
        相关资源
        最近更新 更多