r.a.d.treeview2.5破解手记

类别:Asp 点击:0 评论:0 推荐:

       自从开始使用DotNet做网站以来便顺手开发一个自己的技术论坛,倒没有别的目的,只是想检验一下自己对DotNet的掌握程度。整个论坛的帖子作为叶片绑定在Web树控件上,树控件使用的是微软的Microsoft.Web.UI.WebControls组件中的TreeView,由于Microsoft.Web.UI.WebControls的资源是指向IIS主目录的,当服务商未装载Microsoft.Web.UI.WebControls组件时,这棵树便成了一堆干柴,无奈之下,便下载了Microsoft.Web.UI.WebControls的源码啃了一阵,将资源指向了站点的虚拟目录,编译成自己的版本。论坛终于在局域网中建起来了,我给他起名就叫 “好大一棵树论坛”。朋友给我找了个免费空间让我测试,我便用那只56K的老猫灌起水来,运行当然是正常,但速度实在是不理想,闪烁问题虽然可以通过关闭回传来避免,但这是以牺牲论坛的实时性和其他重要功能为代价的。改用宽带再试,效果果然好了许多,但我的论坛便也就被同事戏称为“好大一棵树论坛 DotNet宽带版”了。由于一时找不到轻巧好用的Web树控件,这棵大树也就一直锁在深闺。

        前几日在CSDN看到大家在对微软的TreeView大贬一通的同时,极力推崇r.a.d.treeview ,这便又一次勾起了我对那个论坛改换“树种”的想法。到r.a.d.treeview的老家http://www.telerik.com 上看了一下,果然响应速度和视觉效果都十分可心,便顺手下载了一个最新的2.5版。装入本机后,其演示画面如下:

        由于是30天的免费试用版,我把计算机的日期向后调整了一年,结果随机的出现了如下过期提示。

    由于两天前刚探究过DotNetTextBox1.3的授权方式(也顺便写了一篇破解手记,可惜这里不便发表),便直接用Reflector打开了RadTreeView.DLL,并直奔控件重载的渲染方法Render()。

反汇编得出如下代码:

 

 

 VB代码

 对应的IL汇编代码

 

Protected Overrides Sub Render(ByVal output As HtmlTextWriter)

      Me.licenseMessage = String.Empty

      If (Not Me.licenseMessage Is String.Empty) Then

            output.Write(Me.licenseMessage)

      Else

            Me.Page.VerifyRenderingInServerForm(Me)

            Dim text1 As String = String.Format("", Me.UniqueID, "trigger")

            Dim objArray1 As Object() = New Object() { String.Concat(Me.UniqueID, "_expanded"), String.Concat(Me.UniqueID, "_expanded"), Me.UniqueID, "trigger" }

            Dim text2 As String = String.Format("", objArray1)

            objArray1 = New Object() { String.Concat(Me.UniqueID, "_checked"), String.Concat(Me.UniqueID, "_checked"), Me.UniqueID, "trigger" }

            Dim text3 As String = String.Format("", objArray1)

            objArray1 = New Object() { String.Concat(Me.UniqueID, "_selected"), String.Concat(Me.UniqueID, "_selected"), Me.UniqueID, "trigger" }

            Dim text4 As String = String.Format("", objArray1)

            output.Write(text1)

            output.Write(text2)

            output.Write(text3)

            output.Write(text4)

      End If

End Sub  

.method family virtual instance void Render([System.Web]System.Web.UI.HtmlTextWriter output) cil managed

{

      // Code Size: 344 byte(s)

      .maxstack 5

      .locals (

            string text1,

            string text2,

            string text3,

            string text4,

            object[] objArray1)

      L_0000: ldarg.0

      L_0001: ldsfld string [mscorlib]System.String::Empty

      L_0006: stfld string WebControlLibrary1.WebCustomControl1::licenseMessage

      L_000b: ldarg.0

      L_000c: ldfld string WebControlLibrary1.WebCustomControl1::licenseMessage

      L_0011: ldsfld string [mscorlib]System.String::Empty

      L_0016: beq.s L_0029

      L_0018: ldarg.1

      L_0019: ldarg.0

     ……中间无关代码略  

      L_0150: ldarg.1

      L_0151: ldloc.3

      L_0152: callvirt instance void [System.Web]System.Web.UI.HtmlTextWriter::Write(string)

      L_0157: ret }

与RadTreeView.DLL的Render方法的反汇编代码相对照,在WebControlLibrary1中得出如下对应关系

 

                        VB                     

 对应的IL汇编代码

 Me.licenseMessage = String.Empty  

    L_0000: ldarg.0

      L_0001: ldsfld string [mscorlib]System.String::Empty

      L_0006: stfld string Telerik.WebControls.RadTreeView::licenseMessage

现在,可以添加IL代码了。打开Visual Studio .NET 2003 命令提示

 

键入ILDASM 打开RadTreeView.DLL

 

然后转储IL反汇编代码,保存RadTreeView.IL,附属文件也一并出现在文件夹中

 

用记事本打开RadTreeView.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........

         CD 62 12 05 0E 7C CD 6F 51 AF 2C 41 FD CC 65 44   // .b...|.oQ.,A..eD

         AC E3 CF 79 6A 19 49 C5 80 C3 FF 52 7C AC 91 1D   // ...yj.I....R|...

         9B E0 5F AD 28 47 CE F4 E7 E5 EC 87 9F C9 4B E4   // .._.(G........K.

         9E 31 C7 97 C2 B8 39 25 C4 ED F6 AA 83 FA 78 A3   // .1....9%......x.

         5A 47 C0 F4 7B 44 A8 F9 3F D1 44 A9 B7 96 BF 74   // ZG..{D..?.D....t

         9E 8D FC B3 99 82 11 52 A9 5C 7A 37 EB A3 82 B6   // .......R.\z7....

         9D A5 8B 7A 1C 87 DA 5C ED 0B 7A 72 BA B1 3F 12   // ...z...\..zr..?.

         52 C6 2F 50 DD 35 44 06 E6 F3 B0 4B AF F4 19 BD ) // R./P.5D....K.... 

查找Render方法,可见到其代码片断如下:

.method family hidebysig virtual instance void

            Render(class [System.Web]System.Web.UI.HtmlTextWriter output) cil managed

    {

      // 代码大小       313 (0x139)

      .maxstack  4

      .locals init (class Telerik.WebControls.RadTreeViewHtmlRenderer V_0,

               string V_1,

               string V_2,

               string V_3,

               string V_4)

      IL_0000:  ldarg.0

      IL_0001:  ldfld      string Telerik.WebControls.RadTreeView::licenseMessage

      IL_0006:  ldsfld     string [mscorlib]System.String::Empty

      IL_000b:  call       bool [mscorlib]System.String::op_Inequality(string,

                                                                       string)

      IL_0010:  brfalse.s  IL_001f

      ……中间无关代码略

      IL_0124:  callvirt   instance void [mscorlib]System.IO.TextWriter::Write(string)

      IL_0129:  ldarg.1

      IL_012a:  ldloc.3

      IL_012b:  callvirt   instance void [mscorlib]System.IO.TextWriter::Write(string)

      IL_0130:  ldarg.1

      IL_0131:  ldloc.s    V_4

      IL_0133:  callvirt   instance void [mscorlib]System.IO.TextWriter::Write(string)

      IL_0138:  ret

    } // end of method RadTreeView::Render 

将“仿真”的IL代码插入Render方法的最前面,见如下加粗代码。

.method family hidebysig virtual instance void

            Render(class [System.Web]System.Web.UI.HtmlTextWriter output) cil managed

    {

      // 代码大小       313 (0x139)

      .maxstack  4

      .locals init (class Telerik.WebControls.RadTreeViewHtmlRenderer V_0,

               string V_1,

               string V_2,

               string V_3,

               string V_4)

 

L_0000: ldarg.0

      L_0001: ldsfld string [mscorlib]System.String::Empty

      L_0006: stfld string Telerik.WebControls.RadTreeView::licenseMessage

 

      IL_0000:  ldarg.0

      IL_0001:  ldfld      string Telerik.WebControls.RadTreeView::licenseMessage

      IL_0006:  ldsfld     string [mscorlib]System.String::Empty

      IL_000b:  call       bool [mscorlib]System.String::op_Inequality(string,

                                                                       string)

      IL_0010:  brfalse.s  IL_001f

      ……中间无关代码略

      IL_0133:  callvirt   instance void [mscorlib]System.IO.TextWriter::Write(string)

      IL_0138:  ret

    } // end of method RadTreeView::Render 

 

保存RadTreeView.IL准备使用ilasm重新编译,为应对编译出现反复,用记事本再做一个批处理文件Myasm.bat保存在同一目录中,内容如下:

ilasm /dll /resource: RadTreeView.res /output: RadTreeView.dll RadTreeView.IL

在Visual Studio .NET 2003 命令提示行运行Myasm,几秒钟后,新的RadTreeView.dll出现了。

为检查添加的IL指令的正确性,用Reflector打开破解后的RadTreeView.dll,反编译Render方法为VB代码,可惜的一幕出现了,Me.licenseMessage = String.Empty

指令准确地出现在我们预定的位置上,可见“仿真”的IL代码是正确的。见下图:

 

进入Microsoft Visual   .NET 开发环境,将新的RadTreeView.dll添加到工具箱。仿照示例代码建立一测试页面WebForm1.aspx,将RadTreeView所需的资源TreeViewImages目录考入测试站点的虚拟目录中。

 

   

       

       

       

       

       

   

   

       

           

本文地址:http://com.8s8s.com/it/it8621.htm