zoukankan      html  css  js  c++  java
  • 通过学习反编译和修改IL,阅读高人的代码,提高自身的水平。 【转】

     

    本文取了一个很“高雅”的名字,实际上可以用一个英文单词概括:crack。

    当然,我不鼓吹随意的crack别人劳动成果以便自身谋取利益。我更推崇的是通过阅读掌握他人优雅的代码,提高自身的程序水平。

    恩!大家阅读正文前,请端正下自己的心态。(。。。。)

    正文

    最近一连研究了几个优秀的webui和winform ui控件,例如divelement, componentart。感觉很是水平,特别自己正在做一个schedule的框架,需要表现力强的ui去好好验证自己的思路,于是拿起工具玩了一把。

    传统的crack,无非是写个注册器,生成注册码什么的,可是!这个不是老子的目标!我要做的是连和注册相关的代码全部都delete掉,成为一个真真正正干净的dll。

    那么工作前,先列举一些工具:

    1. reflector.net 反编译为c#,非常有用,主要用户导出vs项目,然后查看类的调用关系。

    2. UntraEdit,用16进制去阅读代码,可以看到很多dotfuscator混淆的乱码。

    3.  ildasm.exe 微软.net 自带的一个对dll解压成为il的工具。找不到可以用资源管理器搜索一下。

    4.  ilasm.exe 对il再次编译为dll

    5. 附加一个 Remotesoft .net Explorer。可以方便的查看il。不过貌似和ildasm差不多。作为备胎吧。

    工作流水账

    1. 获取需要玩的dll,一般安装了对方的控件,在program files目录下面可以获得。

    2. 使用ildasm.exe 转成il文件,这里有个细节,必须转成Utf-8的格式,不能转成Acsii,否则部分混淆的代码会丢失一些信息。

    3. 使用ilasm.exe 对il进行打包,只要这步能够通过,那么表示咱们的工作可以继续了。否则,作者的安全措施就太丰富了,咱们搞不下去。

    4. 一般来说,我们对于dotfuscator可以无视。这种小儿科骗骗外行就可以了,只要涉及到了public class/ public method,所有的混淆都不会处理,这个是必然的。而我们需要破解的地方,往往就是这些地方,所以不管你怎么混,和我没有关系。

    5. 一切工作准别就绪了后,我们现在已经用有了il源码,现在开始直接在上面修改!

    6.  打开reflector.net(如果可以),导出dll为一个c#项目。各位大侠先别笑,我不是傻逼到修改c#代码然后编译。这种水平的事情我不会还正儿八经的拿出来说事的。导出c#目的是方便研究各种类之间的调用关系,特别和注册相关的类。

    一般来说,reflector.net导出的项目都会编译不通过,但是无所谓,只要能够分析了调用关系就可以了。

    7. 一般老外使用的注册机制基于了System.ComponentModel, 例如ComponentArt里面的:

    这里就使用了License, LicenseProvider, RegistryFileLicenseProvider。

    而传统的crack就是针对了他们的算法,写各种注册机。可是各位高手也闲着蛋疼,搞这么多注册机,不如我简单的把这几个类直接从IL里面删了来得快!

    8. 现在开始动真格的了。我估计99%的.netor不会认真学习IL,所以不怎么敢动。我现在就告诉大家一个超级简单的CRACK方法,就算你不懂IL,一样改。这个方法就是 辰式对照法

    新建一个c#项目,把需要修改的源码片段COPY一份到新项目,然后修改到能编译通过之后,直接改新项目里的源码,再编译为IL,对着copy到原项目的il。

    比如,我通过reflector看见了源码里面有一段代码:

    代码

    public virtual bool IsLicensed()
    {
    if (this.License != null)
        {
    return true;
        }
    try
        {
    this.License = LicenseManager.Validate(base.GetType(), this);
    return true;
        }
    catch
        {
    return false;
        }
    }

    明摆着,我们需要返回true,于是我copy这段代码到新的项目,例如:

    代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    namespace ComponentArt.Licensing.Providers
    {
    public class Hello
        {
            System.ComponentModel.License License;
    public virtual bool IsLicensed()
            {
    if (this.License != null)
                {
    return true;
                }
    try
                {
    this.License = LicenseManager.Validate(base.GetType(), this);
    return true;
                }
    catch
                {
    return false;
                }
            }
        }
    }

    除了方法内部我不变动外,其他的依赖项我尽量虚构出来,您需要什么类,我就建个空类,您需要调用什么方法,我就虚构一个方法。只要您能编译通过,我做您孙子都可以!

    如果不放心,可以试着反编译这段代码编程IL,和原IL对比一下。

    然后我们修改这段代码为:

    代码

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    namespace ComponentArt.Licensing.Providers
    {
    public class Hello
        {
            System.ComponentModel.License License;
    public virtual bool IsLicensed()
            {
    return true;
            }
        }
    }

    再反编译为IL,直接替换原来的IL。哈哈,之前做孙子,今儿是你爷!

    估计大家能领会这段思路了,我们让变动的地方尽量的隔离出来分析,然后整块替换。这样就能够任意修改IL代码了。而且根本不需要管你的注册机制是怎么实现的,我一并端了。

    经验分享

    九阴真经我已经写了,这里就写点经验吧。也许有哥们说,既然reflector都看的着了,你还瞎忙什么。

    这样说就大有问题了。因为reflector倒出来的代码一般都不能够反编译回去,但是只要dll能够编程IL,暂就有办法去改。而且练到一定等级的高手,以后直接就打开IL改了,根本不管你什么方法。当然要到高手的水平,还是有点积累的,例如:

    1. 删除强名称

    打开IL,在开头一段,找到一下代码,直接删除。

    代码

      .publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00   // .$..............
                    00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00   // .$..RSA1........
                    8F B8 4C 20 4D AD 24 D4 AC FF 94 0C 9C 74 AB F4   // ..L M.$......t..
                    E1 F7 7D 41 81 9F BB 3B 43 5C 4A 16 B6 9C C1 04   // ..}A...;C\J.....
                    AE 54 6C C0 7A FA A8 65 F0 D4 7B 89 AE 63 70 48   // .Tl.z..e..{..cpH
                    23 C7 67 35 BC 1C 00 A9 BC C1 B6 F0 CC F6 D9 90   // #.g5............
                    55 8E 30 3C 00 E1 6A AF E2 C4 2F A2 2E D4 0B BC   // U.0<..j.../.....
                    A3 9A 71 40 FA 9F 95 D9 E6 F9 96 6F 01 9C 0B E3   // ..q@.......o....
                    4A 79 D9 00 57 85 A3 AA 70 5B 0F A1 48 B4 B1 07   // Jy..W...p[..H...
                    C9 3C 1C 11 10 7E 7F BB BF C5 50 09 E3 9E A6 B4 ) // .<...~....P.....
      .hash algorithm 0x00008004

    2. 删除VS2005对项目的权限检查。

    一般就是依赖了LicenseProviderAttribute,打开IL,找到类似的代码,直接删除。

    代码

      .custom instance void [System]System.ComponentModel.LicenseProviderAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 3C 43 6F 6D 70 6F 6E 65 6E 74 41 72 74 2E   // ..<ComponentArt.
                                                                                                                           4C 69 63 65 6E 73 69 6E 67 2E 50 72 6F 76 69 64   // Licensing.Provid
                                                                                                                           65 72 73 2E 52 65 67 69 73 74 72 79 46 69 6C 65   // ers.RegistryFile
                                                                                                                           4C 69 63 65 6E 73 65 50 72 6F 76 69 64 65 72 00   // LicenseProvider.
                                                                                                                           00 )

    3. 修改对License的依赖

    一般dll里面会存在多个license版本,当然会有一个正式的license,然后代码中间会运行类似以下片段获取license:

    this.License = LicenseManager.Validate(base.GetType(), this);

    我们现在直接新建一个正式的license就可以了。甚至可以自己虚构一个出来,然后嵌入IL。例如:

    this.License = new FullLicense();

    做到这部,就需要我上面说的对照法,或者熟悉IL的,直接写IL。

    4.  删除所有和licenseProvider相关的类和代码。

    反正是继承了licenseProvider之类的,还是调用了,能改就改(借鉴了reflector.net),之后把licenseprovider删了。

    小结

    本文的目的,是让大家能够更加深入的学习.net,甚至掌握IL。我就是通过改中,慢慢掌握了IL的。感觉比起c#,IL简单多了。希望大家能够成为独霸一方的高人,将来多指导小弟我了!


    作者:水木    
     
  • 相关阅读:
    hadoop中namenode发生故障的处理方法
    开启虚拟机所报的错误:VMware Workstation cannot connect to the virtual machine. Make sure you have rights to run the program, access all directories the program uses, and access all directories for temporary fil
    Hbase的安装与部署(集群版)
    分别用反射、编程接口的方式创建DataFrame
    用Mapreduce求共同好友
    SparkSteaming中直连与receiver两种方式的区别
    privot函数使用
    Ajax无刷新显示
    使用ScriptManager服务器控件前后台数据交互
    数据库知识
  • 原文地址:https://www.cnblogs.com/hsapphire/p/1669658.html
Copyright © 2011-2022 走看看