在使用Telerik JustDecompile反编译的c#中是否有任何神圣的知识?

时间:2016-09-20 15:08:53

标签: c# decompiling

有人向我提供了他需要进行逆向工程和替换的实用程序的源代码。代码中有很多赋值如下:

var a = checked(checked(checked((int)SomeArray.Length) - 1) + 1);

这是一些我不知道的设计模式,还是它反编译的方式

var a = SomeArray.Length;

3 个答案:

答案 0 :(得分:1)

在为Array.Length生成代码时,我从未知道C#编译器会发出额外的算术指令。在IL中,Array.Length看起来像这样:

ldloc.1 // Assuming an array was stored in local slot 1
ldlen

即使在经过检查的情况下,这就是它的样子。现在,在IL中没有像C#中那样的已检查上下文。 IL只是检查了不同的算术指令(例如add.ovf而不是add)。

如果有人写了这样的代码:

int length = checked( array.Length - 1 + 1 );

发出的IL代码如下所示:

ldloc.1
ldlen
conv.i4
ldc.i4.1
sub.ovf
ldc.i4.1
add.ovf
stloc.2

如果反编译器将每个*.ovf指令和conv.i4指令视为具有自己的已检查上下文,则不会让我感到惊讶。阅读说明并逐步构建C#表达式将得到如下内容:

ldloc.1    // array
ldlen      // array.Length
conv.i4    // checked( (int) array.Length )
ldc.i4.1   
sub.ovf    // checked( checked( (int) array.Length ) - 1 )
ldc.i4.1
add.ovf    // checked( checked( checked( (int) array.Length ) - 1 ) + 1 )
stloc.2

答案 1 :(得分:0)

这就是我的想法。

这是因为C#编译器是有损的,'因为C#编译器会计算出数据类型转换之类的内容,然后将这些转换直接输出到它正在编写的DLL中。所有DLL都是用CIL编写的,它不像C#那样丰富,因此复杂的检查和构造被转换为更多但更简单的指令。

例如,C#具有lambda函数的思想,但CIL没有,所以C#编译器将生成一个带有方法的类,然后调用该方法。 E.g;

str => str.Length

变得类似

class DisplayClass234
{
    public int Execute(string str) 
    {
         return str.Length;
    }
}

那么,如果您尝试反编译,Telerik会看到该类" DisplayClass234"而不是原来的lambda。

答案 2 :(得分:0)

如果JustDecompile有Kyle所描述的错误,我不会感到惊讶。我无法记得收到涉及checked的任何支持请求,因此部分代码确实没有进行过良好的声音检查。

如果原始代码是checked(SomeArray.Length + 1 - 1),则编译器可能会取消1-1部分,因此它永远不会到达反编译器。

为什么不要求IL发表该声明并将其发布在此处?反编译它的人也应该能够获得IL。