Daily Archives: June 18, 2008

Snip-It Pro 1.0.1.9

一个比较有意思的保存代码片断的东西。启动后位于桌面的一侧的sidebar,可以作用于任何编辑器。比如你在Visual studio写东西,可以从这里面将常用的一些代码方便的拉入vs中。官方网站在http://www.snipitpro.com/。下载的试用版本有30天试用期。

目前snipit pro工作于dotnet 2.0,除了dotfuscator保护关键代码外,还使用了一个的license保护组件(来自Interactive Studio Inc.)。license组件包括QlmLicenseLib.dll和IsLicense30.dll,后者是一个c++ native PE,前者由于调用后者,ildasm出来的il代码编译后无法通过ilasm使用。

然而问题是,snipit pro是保护十分脆弱,尽管dotfuscator使得reflector反编译后的代码无法编译,比如它将类里的方法名和变量名命名为一样,而c#编译器不允许这样。然后这种情况ilasm是可以编译的。反编译snipitpro.exe,可以看到以下类似代码:

        public aa(SnipItConfig A_0)
        {
            this.a = new QlmLicense();
            this.a.DefineProduct(1, "Snip-It Pro", 1, 0, "SkunkyFo78!", "{24EAA3C1-3DD7-40E0-AEA3-D20AA17A6005}");

            bool flag = false;
            string licenseKey = A_0.LicenseKey;
            this.a.ValidateLicense(licenseKey);
            int status = (int)this.a.GetStatus();
            if ((this.a(status, 8) || this.a(status, 0x10)) || ((this.a(status, 0x20)
                || this.a(status, 0x100)) || this.a(status, 0x80)))
            {
                flag = false;
                this.a(r.d);
            }
            else if (this.a(status, 4))
            {
                if (this.a(status, 0x40))
                {
                    this.a(r.b);
                    flag = false;
                }
                else
                {
                    this.a(r.a);
                    flag = true;
                }
            }
            else if (this.a(status, 2))
            {
                this.a(r.c);
                flag = true;
            }
            this.a(flag);
        }

关键在于status的判断,无论license key是如何被保护,只要status被设置为2,保护即被解除。

int status = (int) this.a.GetStatus();  对应的MSIL代码是,

IL_0045:  ldarg.0
IL_0046:  ldfld      class [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.QlmLicense/*010000F0*/ aa/*02000022*/::a /* 0400013B */
IL_004b:  callvirt   instance valuetype [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.ELicenseStatus/*010000F1*/ [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.QlmLicense/*010000F0*/::GetStatus() /* 0A000266 */
IL_0050:  stloc.2

我们注释掉 IL_0045~IL004b,在IL_004f处添加 ldc.i4.2,即达到以上status设置为2的效果。为了保证文件大小一致,0045~004e IL用nop来填充。修改后的MSIL代码如下,

    //IL_0045:  ldarg.0
    //IL_0046:  ldfld      class [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.QlmLicense/*010000F0*/ aa/*02000022*/::a /* 0400013B */
    //IL_004b:  callvirt   instance valuetype [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.ELicenseStatus/*010000F1*/ [QlmLicenseLib/*23000007*/]InteractiveStudios.QlmLicenseLib.QlmLicense/*010000F0*/::GetStatus() /* 0A000266 */
    IL_0045: nop
    IL_0046: nop
    IL_0047: nop
    IL_0048: nop
    IL_0049: nop
    IL_004a: nop
    IL_004b: nop
    IL_004c: nop
    IL_004d: nop
    IL_004e: nop
    IL_004f:    ldc.i4.2
    IL_0050:  stloc.2

Patch后的snip-it pro 1.0.1.9保护成功解除。在原SnipItpro.exe文件的0x0000d5b1开始的027b3b0100046f6602000a,代替成027b3b0100046f66020018,保存。