• 标 题:简单算法---A Speeder V2.5破解的简要分析! 
  • 作 者:ShenGe
  • 时 间:2003/04/13 01:19pm
  • 链 接:http://bbs.pediy.com

破解软件:A Speeder V2.5版
下载网址:http://www8.pconline.com.cn/download/download.phtml?id=106208
破解难度:易
破解工具:TRW1.22
软件说明:一个可以显著提高你的Windows和Windows下面运行的所有应用程序的执行速度,让你的程序和游戏跑的更快的程序。

 该程序的算法比较简单,但是要跟踪到算法部分对我这样菜鸟来说有点麻烦。因为该软件在你输入注册码注册后它不会出现注册成功与否的对话框,而是通过修改程序界面来体现注册与否,所以会很容易跟进其它的程序段中。而且该程序应该是反反汇编的,因为我试图用WDasm反汇编,却出现非法操作。
我第1次破解时用BPX HMEMCPY断点竟然断不下来,只好用S搜索大法找到输入的注册码值在内存中的位置,然后用 BPM Address R下断一步步的跟出来的,好累!后来破解成功后又试了一下,竟然又可以用BPX HMEMCPY下断了,真是搞不懂!
以下部分是按照BPX HMEMCPY的断点操作流程和我输入的假码1234567进行分析的。

任意埴入注册码,我的为12345678,下BPX HMEMCPY,点OK,程序被拦断,BC *,PMODULE,然后按11下F12,再按F10,来到如下代码:
0167:00402DE7  CALL     0046DDB0
0167:00402DEC  DEC      DWORD [EBP-18]      <---程序中断于此
0167:00402DEF  LEA      EAX,[EBP-10]
0167:00402DF2  MOV      EDX,02
0167:00402DF7  CALL     0049D754
0167:00402DFC  DEC      DWORD [EBP-18]
0167:00402DFF  LEA      EAX,[EBP-0C]
0167:00402E02  MOV      EDX,02
0167:00402E07  CALL     0049D754
0167:00402E0C  DEC      DWORD [EBP-18]
0167:00402E0F  LEA      EAX,[EBP-08]
0167:00402E12  MOV      EDX,02
0167:00402E17  CALL     0049D754
0167:00402E1C  MOV      WORD [EBP-24],08
0167:00402E22  PUSH     BYTE +10
0167:00402E24  CMP      DWORD [EBP-04],BYTE +00
0167:00402E28  JZ       00402E2F
0167:00402E2A  MOV      ECX,[EBP-04]      <---取我们输入的注册码到ECX中
0167:00402E2D  JMP      SHORT 00402E34
0167:00402E2F  MOV      ECX,004B24CE
0167:00402E34  PUSH     ECX
0167:00402E35  PUSH     DWORD 004BBE78
0167:00402E3A  CALL     004933F4
0167:00402E3F  ADD      ESP,BYTE +0C
0167:00402E42  MOV      EAX,004BBE78
0167:00402E47  CALL     00401F90          <---关键比对的Call,跟进去看看
0167:00402E4C  TEST     AL,AL
0167:00402E4E  JZ       00402E77          <---关键判断
0167:00402E50  XOR      EDX,EDX
0167:00402E52  MOV      EAX,[EBX+0334]
0167:00402E58  CALL     00473654
0167:00402E5D  XOR      EDX,EDX
0167:00402E5F  MOV      EAX,[EBX+0338]
0167:00402E65  CALL     00473654
0167:00402E6A  XOR      EDX,EDX
0167:00402E6C  MOV      [004B2264],EDX
0167:00402E72  CALL     004022B4
0167:00402E77  DEC      DWORD [EBP-18]
0167:00402E7A  LEA      EAX,[EBP-04]
0167:00402E7D  MOV      EDX,02
0167:00402E82  CALL     0049D754
0167:00402E87  MOV      ECX,[EBP-34]
0167:00402E8A  MOV      [FS:00],ECX
0167:00402E91  POP      EBX
0167:00402E92  MOV      ESP,EBP
0167:00402E94  POP      EBP
0167:00402E95  RET    
我们跟进上面的那个关键Call,可看到如下代码:
0167:00401F90  PUSH     EBX
0167:00401F91  ADD      ESP,BYTE -20
0167:00401F94  XOR      EBX,EBX
0167:00401F96  MOV      EDX,ESP
0167:00401F98  MOVSX    ECX,BYTE [EAX]   <---EAX中为我们输入的注册码
0167:00401F9B  CMP      ECX,BYTE +41     <---是否大于字符“A“
0167:00401F9E  JNL      00401FA7
0167:00401FA0  ADD      ECX,BYTE -30     <---十六进制值转换为字符值
0167:00401FA3  MOV      [EDX],ECX        
0167:00401FA5  JMP      SHORT 00401FBE
0167:00401FA7  MOVSX    ECX,BYTE [EAX]
0167:00401FAA  CMP      ECX,BYTE +61     <---是否大于字符“a“  
0167:00401FAD  JNL      00401FB6
0167:00401FAF  ADD      ECX,BYTE -37   <---ECX=ECX-37,处理A-a之间的字符(不包括a)
0167:00401FB2  MOV      [EDX],ECX
0167:00401FB4  JMP      SHORT 00401FBE
0167:00401FB6  MOVSX    ECX,BYTE [EAX]
0167:00401FB9  ADD      ECX,BYTE -3D     <---ECX=ECX-3D,处理大于等于a的字符
0167:00401FBC  MOV      [EDX],ECX
0167:00401FBE  INC      EBX
0167:00401FBF  ADD      EDX,BYTE +04
0167:00401FC2  INC      EAX
0167:00401FC3  CMP      EBX,BYTE +08     <---输入的注册码位数不能小于8位
0167:00401FC6  JL       00401F98
0167:00401FC8  MOV      EBX,[ESP]        <---取注册码的第1位,为1    
0167:00401FCB  MOV      EAX,[ESP+08]     <---取注册码的第3位,为3      
0167:00401FCF  ADD      EAX,[ESP+0C]     <---[EBP+0C]为注册码的第4位,为4
0167:00401FD3  ADD      EBX,[ESP+04]     <---[EBP+04]为注册码的第2位,为2
0167:00401FD7  ADD      EBX,[004B2278]   <---[004B2278]中为17,结果为1A        
0167:00401FDD  ADD      EAX,[004B227C]   <---[004B2278]中为43,结果为4A
0167:00401FE3  IMUL     EBX,EAX          <---EBX=EBX*EAX=784
0167:00401FE6  MOV      EDX,[ESP+10]     <---[EBP+04]为注册码的第5位,为5
0167:00401FEA  MOV      ECX,3E           <---ECX=3E
0167:00401FEF  ADD      EDX,[004B2280]   <---[004B2280]中为39,结果为3E  
0167:00401FF5  IMUL     EBX,EDX          <---EBX=EBX*EDX=784*3E=1E100
0167:00401FF8  MOV      EAX,EBX
0167:00401FFA  CDQ    
0167:00401FFB  IDIV     ECX              
0167:00401FFD  CMP      EDX,[ESP+14]<--[ESP+14]为注册码的第6位,EDX=EAX mod ECX=4
0167:00402001  JZ       00402007         <---要是不跳就完了
0167:00402003  XOR      EAX,EAX          <---EAX=0
0167:00402005  JMP      SHORT 00402049  
0167:00402007  MOV      ECX,3E           <---ECX=3E
0167:0040200C  MOV      EAX,EBX          <---EAX=EBX=1E100
0167:0040200E  CDQ    
0167:0040200F  IDIV     ECX
0167:00402011  MOV      EBX,EAX          <---EBX=EAX/ECX=7C2
0167:00402013  MOV      EAX,EBX        
0167:00402015  MOV      ECX,3E
0167:0040201A  CDQ    
0167:0040201B  IDIV     ECX
0167:0040201D  CMP      EDX,[ESP+18]<--[ESP+18]为注册码的第7位,EDX=EAX mod ECX=2
0167:00402021  JZ       00402027         <---要是不跳还得玩完了  
0167:00402023  XOR      EAX,EAX          <---EAX=0
0167:00402025  JMP      SHORT 00402049
0167:00402027  MOV      ECX,3E
0167:0040202C  MOV      EAX,EBX          <---EAX=EBX=7C2
0167:0040202E  CDQ    
0167:0040202F  IDIV     ECX
0167:00402031  MOV      EBX,EAX          <---EBX=EAX/ECX=20
0167:00402033  MOV      EAX,EBX
0167:00402035  MOV      ECX,3E
0167:0040203A  CDQ    
0167:0040203B  IDIV     ECX
0167:0040203D  CMP      EDX,[ESP+1C]<--[ESP+18]为注册码第7位,EDX=EAX mod ECX=20
0167:00402041  JZ       00402047         <---最后一处判断
0167:00402043  XOR      EAX,EAX
0167:00402045  JMP      SHORT 00402049
0167:00402047  MOV      AL,01            <---置AL中的值为1,胜利女神!
0167:00402049  ADD      ESP,BYTE +20
0167:0040204C  POP      EBX
0167:0040204D  RET    
从上面的分析我们可得到我的正确注册码的后3位为42W。因为最后一次的EDX中值为20,而又因为61-3D=24>20,可知为大写字符,所以未转换前值应为37+20,对应的字符为W,这样就可得到正确的注册码:1234542W.其实从上面的分析可以看出,只要注册码的位数不小于8,而且只要前8位满足上面的算法即可,第8位以后可任意输。
该程序注册成功后将注册信息保存在注册表的
“HKEY_CURRENT_USER/Software/aspeeder”中,程序重启会取出再进行比对。