[转载] – 让Reflector的反编译不能正常工作

用过Reflector的都知道,这是一个功能非常强大的反编译工具,几乎能够将你的.net代码完全还原,并且能够立即重新

编译运行,本文提供了一个方法让Reflector的反编译不能正常工作,据研究,目前很多代码混淆工具已经使用了该技术,

为了便于理解,我将该方法姑且叫做代码顺序扰乱技术。

下面来研究一个具体的例子:

1。StrConv.cs源代码如下:

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~using System;

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~public class StrTool

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~{

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~ public static void Main(String[] argv)[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~{

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~  String s1=”???”;

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~  int num=0x4308d77e;

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~  Console.WriteLine(conv(s1,num));

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~ }

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~ public static string conv(string str, int num)

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~ [转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~{

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    char[] chArray1 = str.ToCharArray();

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    for (int num1 = 0; num1 < chArray1.Length; num1++)

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    [转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~{

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    chArray1[num1] = (char)(chArray1[num1] – num);

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    num += 0x6fd;

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    }

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~    return new string(chArray1);

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~ }

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~}

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~

[转载] - 让Reflector的反编译不能正常工作 - 夏 - 隨心漂泊~~~

运行csc strconv.cs编译运行,结果是SHA1,程序的功能是简单的字符串加密处理。

用Reflector打开strconv.exe文件,发现所有代码可以准确的反编译为c#。

2。用ildasm反编译,导出IL文件StrConv.il,打开找到conv方法的代码如下:

.method public hidebysig static string  conv(string str,

                                             int32 num) cil managed

{

  // 代码大小       65 (0x41)

  .maxstack  4

  .locals init (char[] V_0,

           int32 V_1,

           string V_2)

  IL_0000:  ldarg.0

  IL_0001:  callvirt   instance char[] [mscorlib]System.String::ToCharArray()

  IL_0006:  stloc.0

  IL_0007:  ldc.i4.0

  IL_0008:  stloc.1

  IL_0009:  br.s       IL_0013

  IL_000b:  ldloc.0

  IL_000c:  ldloc.1

  IL_000d:  br         IL_0027

  IL_0012:  stloc.1

  IL_0013:  ldloc.1

  IL_0014:  ldloc.0

  IL_0015:  ldlen

  IL_0016:  conv.i4

  IL_0017:  blt.s      IL_000b

  IL_0019:  ldloc.0

  IL_001a:  newobj     instance void [mscorlib]System.String::.ctor(char[])

  IL_001f:  stloc.2

  IL_0020:  br.s       IL_003f

  IL_0022:  br         IL_003f

  IL_0027:  ldloc.0

  IL_0028:  ldloc.1

  IL_0029:  ldelem.u2

  IL_002a:  ldarg.1

  IL_002b:  sub

  IL_002c:  conv.u2

  IL_002d:  stelem.i2

  IL_002e:  ldarg.1

  IL_002f:  ldc.i4     0x6fd

  IL_0034:  add

  IL_0035:  starg.s    num

  IL_0037:  ldloc.1

  IL_0038:  ldc.i4.1

  IL_0039:  add

  IL_003a:  br         IL_0012

  IL_003f:  ldloc.2

  IL_0040:  ret

} // end of method StrTool::conv

下面将上面的代码顺序扰乱编排如下,中间夹了几个跳转指令br

.method public hidebysig static string

          conv(string str,

               int32 num) cil managed

  {

    // 代码大小       50 (0x32)

    .maxstack  4

    .locals init (char[] V_0,

             int32 V_1,

             string V_2)

    IL_0000:  ldarg.0

    IL_0001:  callvirt   instance char[] [mscorlib]System.String::ToCharArray()

    IL_0006:  stloc.0

    IL_0007:  ldc.i4.0

    IL_0008:  stloc.1

    IL_0009:  br.s       IL_0021

    IL_000b:  ldloc.0

    IL_000c:  ldloc.1

    //开始跳转

    br IL_000d

   

    IL_0020:  stloc.1

    IL_0021:  ldloc.1

    IL_0022:  ldloc.0

    IL_0023:  ldlen

    IL_0024:  conv.i4

    IL_0025:  blt.s      IL_000b

    IL_0027:  ldloc.0

    IL_0028:  newobj     instance void [mscorlib]System.String::.ctor(char[])

    IL_002d:  stloc.2

    IL_002e:  br.s       IL_0030

    br IL_0030

    //***移动过来的代码

    IL_000d:  ldloc.0

    IL_000e:  ldloc.1

    IL_000f:  ldelem.u2

    IL_0010:  ldarg.1

    IL_0011:  sub

    IL_0012:  conv.u2

    IL_0013:  stelem.i2

    IL_0014:  ldarg.1

    IL_0015:  ldc.i4     0x6fd

    IL_001a:  add

    IL_001b:  starg.s    num

    IL_001d:  ldloc.1

    IL_001e:  ldc.i4.1

    IL_001f:  add

    //***返回

    br IL_0020

    IL_0030:  ldloc.2

    IL_0031:  ret

  } // end of method StrTool::conv

修改完毕,保存。大家可以看到只是简单的将代码顺序移动了一下,没有其他任何改变。

用ilasm重新组装ilasm strconv.il成新的strconv.exe

3.重新运行结果正常。然后用Reflector打开strconv.exe文件,反编译conv方法为C#,这时就出现错误了。

System.InvalidOperationException: Invalid branching statement for condition expression with target offset 0027.

   at _127._4(Int32 )

   at _127._1(Int32 )

   at _127._1(Int32 , Int32 )

   at _127._1(IMethodDeclaration , IMethodBody )

   at _123.VisitMethodDeclaration(IMethodDeclaration value)

   at _146._1(Boolean )

不信大家可以试试!

 

本文只是简单演示了这种代码处理的方法,如果多次移动代码,那么要想还原就更加复杂了。

对于这种问题,Reflector在将来的版本看会不会解决,不过目前最新版本仍然不能处理该问题。

 

http://www.cnblogs.com/midea0978/articles/110365.html