QQ登录

只需一步,快速开始

扫一扫,访问微社区

登录 | 注冊 | 找回密码

163 加中网–加拿大曼尼托巴中文门户网站 | 温尼伯华人论坛

 找回密码
 注冊

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 250|回复: 2
打印 上一主题 下一主题

[闲聊] .NET 程序破解实战

[复制链接]
跳转到指定楼层
1#
匿名  发表于 2002-11-17 14:26:39 回帖奖励 |倒序浏览 |阅读模式
    现在.NET的程序越来越多了,很多人开始关注如何破解.NET的程序。其实个人感觉,.NET程序的破解比传统的容易多了。只要没有被加密,一般的写过程序的人,都可以按照本文的步骤,破解.NET程序。 </P><P>首先,要准备几样东西: <BR>1,ILDasm,.NET的反汇编工具,.NET Framework SDK自带的,用于程序的反汇编; <BR>2,MSIL的参考书,比如Inside Microsoft IL之类,主要是在对IL不太熟练的情况下,用来查指令码。 <BR>3,Anakrino,.NET的反编译工具,可以把.NET的Assembly反编译成c#或者c++的代码。用于分析程序流程。下载地址: http://test.saurik.net/anakrino/ <BR>4,UltraEdit,二进制编辑器,用于搜索、修改.NET可执行程序。 </P><P>这次我们的目标是一个c#代码生成器,在这里下载: http://www.gavinjoyce.com/nTierGen/default.aspx 。安装了试用版之后,在 c:\program files\www.gavinjoyce.com\.net n-tier framework generator evaluation 1.2 里面找到 nTierGen.eval.1.2.exe 和 Microsoft.ApplicationBlocks.Data.DLL。后一个dll好像跟破解没有太大关系。OK,Let''s go! </P><P>第一步:分析定位代码。用Anakrino打开 nTierGen.eval.1.2.exe。在Atweb.CodeGet.Wizard名字空间下,有一个frmWizard。这就是程序的主窗口了。在主窗口里面,有一个事件响应方法叫做 btnNext_Click,在里面找到了这样的代码: <BR>  if (this.panel2.Visible) { <BR>     local2 = Helper.IsCaseStudy(this.proj.dbTree); <BR>     if (this.chkListTables.CheckedItems.Count > this.MAX_TABLES && !(local2)) <BR>       MessageBox.Show("This evaluation release is restricted to " + this.MAX_TABLES.ToString() + " tables. Extra tables have been removed."); <BR>     local3 = new TableCollection(); <BR>     local4 = 0; <BR>     while (local4 < this.chkListTables.Items.Count) { <BR>       local5 = (String) this.chkListTables.Items.get_Item(local4); <BR>       if (this.chkListTables.GetItemChecked(local4) && local3.Count < this.MAX_TABLES || local2) <BR>         local3.Add(this.proj.dbTree.Tables.Item(local5)); <BR>       this.proj.dbTree.Tables.Remove(this.proj.dbTree.Tables.Item(local5).ToString()); <BR>       local4++; <BR>     } <BR>     this.proj.dbTree.Tables = local3; <BR>     this.Panel2Init(); <BR>     this.HidePanels(); <BR>     this.panel3.Visible = true; <BR>     this.RefreshViewList(); <BR>     return; <BR>   }</P><P>可以看出,当用户选定了表之后,按Next按钮,他就检查选择的数量。如果>this.MAX_TABLES,就Show出一个MessageBox,接下来就只选择前this.MAX_TABLES个表。OK,目标就在这里了。 </P><P>第二步:制定策略。显然,这个MAX_TABLES是程序里面的一个常量,用于限制表的个数。我们只要把这个常量改得大一些,不就行了吗?好,试试看。 </P><P>  .class /*0200003F*/ public auto ansi beforefieldinit ''frmWizard'' <BR>          extends [''System.Windows.Forms''/* 23000002 */>''System.Windows.Forms''.''Form''/* 01000004 */ <BR>   { <BR>     .field /*04000098*/ private int32 ''MAX_TABLES'' <BR>     .field /*04000099*/ private bool ''ENCRYPT_TREE'' <BR>     .field /*0400009A*/ private string ''LICENSED_TO'' <BR>     .field /*0400009B*/ private string ''LICENSED_TO_COMPANY'' <BR> ..... <BR> </P><P>            instance void  .ctor() cil managed <BR>     // SIG: 20 00 01 <BR>     { <BR>       // Method begins at RVA 0xb0b8 <BR>       // Code size       218 (0xda) <BR>       .maxstack  5 <BR>       .locals /*11000049*/ init (string[> V_0) <BR>       IL_0000:  /* 02   |                  */ ldarg.0 <BR>       IL_0001:  /* 19   |                  */ ldc.i4.3 <BR>       IL_0002:  /* 7D   | (04)000098       */ stfld      int32 ''Atweb.CodeGen.Wizard''.''frmWizard''/* 0200003F */::''MAX_TABLES'' /* 04000098 */ <BR> <BR>在frmWizard的构造函数里面,IL_0001这个地方,ldc.i4.3,让MAX_TABLES=3。再看看IL的指令: <BR>ldc.i4 <int32> (0x20)  Load <int32> on the stack. <BR> ldc.i4.s <int8> (0x1F)  Load <int8> on the stack. <BR> ldc.i4.m1 (ldc.i4.M1) (0x15)  Load -1 on the stack. <BR> ldc.i4.0 (0x16)  Load 0. <BR> ldc.i4.1 (0x17)   Load 1. <BR> ldc.i4.2 (0x18)   Load 2. <BR> ldc.i4.3 (0x19)   Load 3. <BR> ldc.i4.4 (0x1A)   Load 4. <BR> ldc.i4.5 (0x1B)   Load 5. <BR> ldc.i4.6 (0x1C)   Load 6. <BR> ldc.i4.7 (0x1D)   Load 7. <BR> ldc.i4.8 (0x1E)   Load 8. (I should have listed these in reverse order so then we could imagine ourselves on Cape Canaveral.) <BR> ldc.i8 <int64> (0x21)  Load <int64> on the stack. <BR> ldc.r4 <float32> (0x22)  Load <float32> (single-precision) on the stack. <BR> ldc.r8 <float64> (0x23)  Load <float64> (double-precision) on the stack. ILAsm permits the use of integer parameters in both the ldc.r4 and ldc.r8 instructions; in such cases, the integers are interpreted as binary images of the floating-point numbers. <BR> </P><P>可以看出,IL只用了一个byte来给MAX_TABLE赋值,跟我们以往的x86 ASM有所不同。把ldc.i4.3改成ldc.i4.8,也就是把0x19改称0x1E,看看效果如何。用UltraEdit搜索出02 19 7D 98 00 00 04,然后把19改成1E,保存,运行,程序显示“最大8个表”等等,看来就着一个地方了。 <BR>从IL指令来看,一个byte最大赋值8,显然8个表还是太少了。怎么办? </P><P> <BR>       IL_0197:  /* 09   |                  */ ldloc.3 <BR>       IL_0198:  /* 6F   | (0A)000017       */ callvirt   instance int32 [''mscorlib''/* 23000001 */>''System.Collections''.''CollectionBase''/* 01000002 */::''get_Count''() /* 0A000017 */ <BR>       IL_019d:  /* 02   |                  */ ldarg.0 <BR>       IL_019e:  /* 7B   | (04)000098       */ ldfld      int32 ''Atweb.CodeGen.Wizard''.''frmWizard''/* 0200003F */::''MAX_TABLES'' /* 04000098 */ <BR>       IL_01a3:  /* 32   | 03               */ blt.s      IL_01a8 <BR>  <BR>       IL_01a5:  /* 08   |                  */ ldloc.2 <BR>       IL_01a6:  /* 2C   | 1D               */ brfalse.s  IL_01c5 <BR>  <BR>       IL_01a8:  /* 09   |                  */ ldloc.3 <BR>       IL_01a9:  /* 02   |                  */ ldarg.0 <BR>  </P><P>在IL_01a3这个地方,比较MAX_TABLE,如果小于则跳转。OK,如果我们在赋值的时候,给一个-1,然后把有符号数的比较改成无符号数的比较,不就可以支持最多256个表了吗?OK! </P><P>第五步:最后的修改。搜索出上次02 19 7D 98 00 00 04的地方,把19改成15,也就是变成ldc.i4.m1;再搜索出7B 98 00 00 04 32这个地方,把blt.s改成blt.un.s,也就是把32改成37,保存,运行,程序显示支持"-1"个表,实际上支持256个表,。。。。 </P><P>    最后总结:.NET程序修改过程中,很容易出执行引擎的错误,所以修改的地方越少越好。当然,熟练之后可以想怎么改就怎么改了。另外,熟悉c#语言,熟悉IL也非常有帮助。怎么样,想不想马上试试看?
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享
回复

使用道具

该用户从未签到

2#
发表于 2024-4-22 17:39:27 | 只看该作者
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2024-4-22 17:40:38 | 只看该作者
回复 支持 反对

使用道具 举报

发表回复
您需要登录后才可以回帖 登录 | 注冊

本版积分规则

    联系我们
  • 咨询电话:1.204.294.8528
  • 邮箱:163adv@gmail.com
  • QQ:179091654
    移动客户端:即将开放
    关注我们:
  • 扫描二维码加关注

快速回复 返回顶部 返回列表