欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

winxp总管破解笔记(一) (8千字)

winxp总管破解笔记(一) (8千字)

好久没写东西了,找不到好的题材,现在有了,一个.NET的程序----WINXP总管,让我们有幸目睹微软的杰作.NET框架程序的破解:)
目标软件:WINXP总管
编程语言:VB.NET
破解工具:ILDASM,WINHEX

背景知识介绍:首先,我们遇到的是一个全新的东西,.NET框架,这个东西是什么呢,他怎么工作的,如果你用WIN32DASM反汇编一下这个程序,你会看到莫名其妙的代码,因为它不再是我们传统意义上的汇编代码了,它是.NET的核心也就是MSIL语言,IL全称是INTERMEDIATE LANGUAGE,也就是一种中间语言,类似PCODE,但这回所有的编程语言包括VB,VC,C#全都编译成MSIL然后再利用.NET框架的JIT实时转译成本地机的可执行代码,从而实现了平台无关性,于是我们要破解这类程序就要找到一种类似PCODE反编译器的东西,很幸运的是微软大叔为我们提供了全套超强绿色套装:)对我们最有用的就是ILDASM(这些东西在.NET FRAMEWORK SDK中提供)
好了基本的东西知道了一点,现在开始就要了解这种语言了,当然微软的MSDN有所有你想知道的东西,所以我这里就不罗索了,你可以去看看他的教程,我就来讲讲具体的破解,这才是我等感兴趣的:)
首先用ILDASM把源程序载入,很快我们得到了反编译的代码,你看到的是一种树状的结构图:

很清晰的结构,完全采用类的结构,通过名字我们判断MyClsRegister这个类就是关键所在,而他的几个方法也是一看就明白做什么用的,关键就在它们里面代码的含义,就是msil语言究竟是怎么样的。我们从Registered入手,这个最象那么回事:)
所有的misl语言都基于CLR(公共语言运行库),CLR 是.NET 框架应用程序的执行引擎,它有别于传统的CPU结构,传统的CPU执行依赖于寄存器和堆栈,而CLR只使用堆栈,所以你所看到的MSIL语言都是下面的形式:
ld....
ld....
语句(call,比较。。)
实际上类似于
push
push
call
也就是说全都是这样的函数,方法调用

.method public static void  Registered() cil managed  //方法的名称
{
  // Code size      90 (0x5a)  //代码的大小
  .maxstack  4  //最大的堆栈数
  .locals init (string V_0, //参数
          string V_1)
  IL_0000:  nop
  IL_0001:  call      string WinXP_Manager.MyClsOther/MyClsRegister::GetRegCodeValue()//这个方法在前面有描述是注册表"date"键值
  IL_0006:  stloc.0    //st=store这句是要保存上面返回值到loc.0,loc.0是本地的一个参数
  IL_0007:  call      string WinXP_Manager.MyClsOther/MyClsRegister::GetRegCodeWord()//这个方法在前面有描述是注册表"name"键值
  IL_000c:  stloc.1    //类似上面,存到loc.1里面
  IL_000d:  ldloc.0    //取出loc.0,推到堆栈里
  IL_000e:  ldstr      ""  //取字符串,这里是空串
  IL_0013:  ldc.i4.0  //取一个0,推入堆栈
  IL_0014:  call      int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
                                                                                                              string,
                                                                                                              bool)//可以看出上面三个参数是用来给这个比较call的,目的显然是判断是不是空串,返回值入栈
  IL_0019:  ldc.i4.0  //推一个0入栈
  IL_001a:  ceq        //比较看是不是空的啦,是推送 1,否则推送 0 
  IL_001c:  ldloc.1    //和上面类似来判断另一个是不是空
  IL_001d:  ldstr      ""
  IL_0022:  ldc.i4.0
  IL_0023:  call      int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
                                                                                                              string,
                                                                                                              bool)
  IL_0028:  ldc.i4.0 
  IL_0029:  ceq     
  IL_002b:  or        //把ceq后的两个堆栈的值或一下
  IL_002c:  brfalse.s  IL_0036 //如果是0,则跳到36行继续
  IL_002e:  ldc.i4.0  //否则推一个0  <----------将来修改这里推1进去
  IL_002f:  stsfld    bool WinXP_Manager.publicVarFun::IsRegistered//存到这个参数里(这个参数就是用来判断注册与否的)
  IL_0034:  br.s      IL_0057//跳出去
  IL_0036:  nop
  IL_0037:  ldloc.0    //取出date
  IL_0038:  ldloc.1    //取出name
  IL_0039:  call      string WinXP_Manager.MyClsOther/MyClsRegister::FromHDSNGetRegisterCode(string)//另一方法里用于算注册码
  IL_003e:  ldc.i4.0 
  IL_003f:  call      int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
                                                                                                              string,
                                                                                                              bool)//比较拉
  IL_0044:  ldc.i4.0
  IL_0045:  beq.s      IL_004f  //判断相等就说明注册了
  IL_0047:  ldc.i4.0  //不等就推0  <-----------------这里改成1:)
  IL_0048:  stsfld    bool WinXP_Manager.publicVarFun::IsRegistered
  IL_004d:  br.s      IL_0056
  IL_004f:  nop
  IL_0050:  ldc.i4.1  //相等推1
  IL_0051:  stsfld    bool WinXP_Manager.publicVarFun::IsRegistered
  IL_0056:  nop
  IL_0057:  nop
  IL_0058:  nop
  IL_0059:  ret
} // end of method MyClsRegister::Registered

很简单把,接下来我们就要改了,怎么做,首先要知道这些代码怎么用16进制表示在文件里的,把显示字节打开,再来看看这段代码
.method public static void  Registered() cil managed
// SIG: 00 00 01
{
  // Method begins at RVA 0x9370c
  // Code size      90 (0x5a)
  .maxstack  4
  .locals init (string V_0,
          string V_1)
  IL_0000:  /* 00  |                  */ nop
  IL_0001:  /* 28  | (06)000056      */ call      string WinXP_Manager.MyClsOther/MyClsRegister::GetRegCodeValue()
  IL_0006:  /* 0A  |                  */ stloc.0
  IL_0007:  /* 28  | (06)000057      */ call      string WinXP_Manager.MyClsOther/MyClsRegister::GetRegCodeWord()
  IL_000c:  /* 0B  |                  */ stloc.1
  IL_000d:  /* 06  |                  */ ldloc.0
  IL_000e:  /* 72  | (70)000B80      */ ldstr      ""
  IL_0013:  /* 16  |                  */ ldc.i4.0
  IL_0014:  /* 28  | (0A)000083      */ call
来看看这段,他的16进制表示是这样的
00 28 56 00 00 06 0a 28 57 00 00 06 0b 06 72 80 0b 00 70 16 28 83 00 00 0a
看出来了吧:)                                                                                                         
  IL_0019:  /* 16  |                  */ ldc.i4.0
  IL_001a:  /* FE01 |                  */ ceq
  IL_001c:  /* 07  |                  */ ldloc.1
  IL_001d:  /* 72  | (70)000B80      */ ldstr      ""
  IL_0022:  /* 16  |                  */ ldc.i4.0
  IL_0023:  /* 28  | (0A)000083      */ call      int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
                                                                                                                                            string,
                                                                                                                                            bool)
  IL_0028:  /* 16  |                  */ ldc.i4.0
  IL_0029:  /* FE01 |                  */ ceq
  IL_002b:  /* 60  |                  */ or
  IL_002c:  /* 2C  | 08              */ brfalse.s  IL_0036
  IL_002e:  /* 16  |                  */ ldc.i4.0  //这里改成17
  IL_002f:  /* 80  | (04)000007      */ stsfld    bool WinXP_Manager.publicVarFun::IsRegistered
  IL_0034:  /* 2B  | 21              */ br.s      IL_0057
  IL_0036:  /* 00  |                  */ nop
  IL_0037:  /* 06  |                  */ ldloc.0
  IL_0038:  /* 07  |                  */ ldloc.1
  IL_0039:  /* 28  | (06)000059      */ call      string WinXP_Manager.MyClsOther/MyClsRegister::FromHDSNGetRegisterCode(string)
  IL_003e:  /* 16  |                  */ ldc.i4.0
  IL_003f:  /* 28  | (0A)000083      */ call      int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StringType::StrCmp(string,
                                                                                                                                            string,
                                                                                                                                            bool)
  IL_0044:  /* 16  |                  */ ldc.i4.0   
  IL_0045:  /* 2E  | 08              */ beq.s      IL_004f
  IL_0047:  /* 16  |                  */ ldc.i4.0  //这里改成17
  IL_0048:  /* 80  | (04)000007      */ stsfld    bool WinXP_Manager.publicVarFun::IsRegistered
  IL_004d:  /* 2B  | 07              */ br.s      IL_0056
  IL_004f:  /* 00  |                  */ nop
  IL_0050:  /* 17  |                  */ ldc.i4.1
  IL_0051:  /* 80  | (04)000007      */ stsfld    bool WinXP_Manager.publicVarFun::IsRegistered
  IL_0056:  /* 00  |                  */ nop
  IL_0057:  /* 00  |                  */ nop
  IL_0058:  /* 00  |                  */ nop
  IL_0059:  /* 2A  |                  */ ret
} // end of method MyClsRegister::Registered
完成了,等我的下一篇文章研究一下注册算法:)


注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功