• 标 题:梦想图片屏幕保护V2.6破解简要分析
  • 作 者: ShenGe
  • 时 间:2003/05/12 07:36am
  • 链 接:http://bbs.pediy.com

破解软件:梦想图片屏幕保护V2.6
软件语言:  中文
软件类别:  国内软件 / 共享版 /
应用平台:  Win9x/NT/2000/XP
界面预览:  无
软件下载:  http://count.skycn.com/softdown.php?id=6912&url=http://on165-down.skycn.net/down/dreamssc.zip
破解工具:TRW1.22
作者声明:初学破解,仅作学习交流之用,失误之处敬请大侠赐教。

软件说明:梦想图片屏幕保护是一个简易出色的图片屏幕保护制作工具,用户只须简单的设置四个步骤,数分钟内就可创建出色的Windows 屏幕保护。本软件轻松易用,功能强大,非常适用于制作具有优秀效果的屏幕保护。软件特点:1.程序操作简便,美观精巧,支持换肤功能;2.支持添加Bmp、Jpg和Gif格式图片,添加Mp3、Wav和Mid格式歌曲,可添加多张图片和多首歌曲;3.可自定义屏保显示的动态文字和静态标题;4.屏幕保护的背景、轮廓都可以定制或选择;5.创建的屏幕保护具有32大类82种特殊图片切换效果,7大类22种字体显示效果。
未注册最多只能添加7张图片来创建屏幕保护,注册后无图片数量限制。


唉,又碰上了一个VB的,还是反汇编的,只好动态跟踪,真是头痛,反汇编的怎么去除哇,那位大侠要是知道烦请赐教。填入用户名:ShenGe和假码:12345-67890,为什么假码是这种形式呢,往后看就
知道了,下万能断点BPX HMEMCPY,注册,程序被中断,BC *,PMODULE,来到如下代码:
0167:00468DE6  CALL     `MSVBVM50!rtcRightTrimVar`  
0167:00468DEC  MOV      EBX,[EBX+0300]     <---程序中断于此
0167:00468DF2  PUSH     ESI
0167:00468DF3  MOV      DWORD [EBP+FFFFFAF4],0040F348
0167:00468DFD  MOV      DWORD [EBP+FFFFFAEC],8008
0167:00468E07  CALL     EBX
0167:00468E09  MOV      [EBP+FFFFFF74],EAX
0167:00468E0F  LEA      EAX,[EBP+FFFFFF6C]
0167:00468E15  LEA      ECX,[EBP+FFFFFF5C]
0167:00468E1B  PUSH     EAX
0167:00468E1C  PUSH     ECX
.........(略去)
按F10跟下去,注意各寄存器值的变化,可看到以下代码:
0167:00468F26  PUSH     DWORD A0
0167:00468F2B  PUSH     DWORD 004108C0
0167:00468F30  PUSH     EBX
0167:00468F31  PUSH     EAX
0167:00468F32  CALL     `MSVBVM50!__vbaHresultCheckObj`
0167:00468F38  MOV      ECX,[EBP-44]    <---[EBP-44]中为输入的假码
0167:00468F3B  MOV      EBX,[0048239C]
0167:00468F41  PUSH     ECX
0167:00468F42  CALL     EBX             <---此Call计算假码的长度,返回值在EAX中        
0167:00468F44  MOV      EDX,EAX
0167:00468F46  MOV      EAX,[EBP-48]    <---[EBP-48]中为固定字串"4BE43-BI3G8"
0167:00468F49  PUSH     EAX
0167:00468F4A  MOV      [EBP+FFFFF800],EDX
0167:00468F50  CALL     EBX             <---同上Call,求字串长度
0167:00468F52  MOV      ECX,[EBP+FFFFF800] <---[EBP+FFFFF800]中为字串长度
0167:00468F58  XOR      EBX,EBX
0167:00468F5A  CMP      ECX,EAX         <---比较假码长度与固定字串长度是否相等  
0167:00468F5C  LEA      EDX,[EBP-48]
0167:00468F5F  LEA      EAX,[EBP-44]
0167:00468F62  PUSH     EDX
0167:00468F63  SETL     BL              <---若位数相等则BL=0
0167:00468F66  PUSH     EAX
0167:00468F67  PUSH     BYTE +02
0167:00468F69  NEG      EBX             <---EBX=0-EBX
0167:00468F6B  CALL     `MSVBVM50!__vbaFreeStrList`
0167:00468F71  ADD      ESP,BYTE +0C
0167:00468F74  LEA      ECX,[EBP-50]
0167:00468F77  LEA      EDX,[EBP-4C]
0167:00468F7A  PUSH     ECX
0167:00468F7B  PUSH     EDX
0167:00468F7C  PUSH     BYTE +02
0167:00468F7E  CALL     `MSVBVM50!__vbaFreeObjList`
0167:00468F84  ADD      ESP,BYTE +0C
0167:00468F87  CMP      BX,DI           <---关键比较1
0167:00468F8A  JNZ      NEAR 0046A35C   <---位数不相等则跳,那就没戏了
0167:00468F90  PUSH     ESI
0167:00468F91  CALL     NEAR [EBP+FFFFF808]
0167:00468F97  PUSH     EAX
0167:00468F98  LEA      EAX,[EBP-4C]
0167:00468F9B  PUSH     EAX
0167:00468F9C  CALL     `MSVBVM50!__vbaObjSet`
0167:00468FA2  MOV      EBX,EAX
0167:00468FA4  LEA      EDX,[EBP-44]
0167:00468FA7  PUSH     EDX
0167:00468FA8  PUSH     EBX
0167:00468FA9  MOV      ECX,[EBX]
0167:00468FAB  CALL     NEAR [ECX+A0]
0167:00468FB1  CMP      EAX,EDI
0167:00468FB3  JNL      00468FC7
0167:00468FB5  PUSH     DWORD A0
0167:00468FBA  PUSH     DWORD 004108C0
0167:00468FBF  PUSH     EBX
0167:00468FC0  PUSH     EAX
0167:00468FC1  CALL     `MSVBVM50!__vbaHresultCheckObj`
0167:00468FC7  MOV      EAX,[EBP-44]      <---[EBP-44]中为我输入的用户名    
0167:00468FCA  PUSH     EAX            
0167:00468FCB  CALL     `MSVBVM50!__vbaLenBstr` <---求用户名的长度
0167:00468FD1  MOV      ECX,EAX           <---ECX=EAX=用户名的长度
0167:00468FD3  CALL     `MSVBVM50!__vbaI2I4`
0167:00468FD9  LEA      ECX,[EBP-44]
0167:00468FDC  MOV      [EBP+FFFFF85C],EAX
0167:00468FE2  MOV      DWORD [EBP-20],01 <---[EBP-20]置值为1
0167:00468FE9  CALL     `MSVBVM50!__vbaFreeStr`
0167:00468FEF  LEA      ECX,[EBP-4C]
0167:00468FF2  CALL     `MSVBVM50!__vbaFreeObj`
0167:00468FF8  MOV      EBX,[00482648]
0167:00468FFE  MOV      EDI,[0048248C]
--------------第一个大循环----------------------
0167:00469004  MOV      CX,[EBP+FFFFF85C] <---[EBP+FFFFF85C]中为用户名长度
0167:0046900B  CMP      [EBP-20],CX       <---比较是否取完用户名
0167:0046900F  JG       NEAR 0046917B
0167:00469015  PUSH     ESI
0167:00469016  CALL     NEAR [EBP+FFFFF808]
0167:0046901C  LEA      EDX,[EBP-4C]
0167:0046901F  PUSH     EAX
0167:00469020  PUSH     EDX
0167:00469021  CALL     `MSVBVM50!__vbaObjSet`
0167:00469027  MOV      EAX,[EBP-4C]
0167:0046902A  LEA      EDX,[EBP-64]
0167:0046902D  MOVSX    ECX,WORD [EBP-20] <---ECX=[EBP-20]
0167:00469031  MOV      [EBP-5C],EAX
0167:00469034  LEA      EAX,[EBP-74]
0167:00469037  PUSH     EAX
0167:00469038  PUSH     ECX
0167:00469039  LEA      EAX,[EBP+FFFFFF7C] <---[EBP+FFFFFF7C]中注册码位数
0167:0046903F  PUSH     EDX
0167:00469040  PUSH     EAX
0167:00469041  MOV      DWORD [EBP-6C],01
0167:00469048  MOV      DWORD [EBP-74],02
0167:0046904F  MOV      DWORD [EBP-4C],00
0167:00469056  MOV      DWORD [EBP-64],09
0167:0046905D  CALL     EDI
0167:0046905F  LEA      ECX,[EBP+FFFFFF7C]
0167:00469065  PUSH     ECX
0167:00469066  CALL     `MSVBVM50!__vbaStrVarMove`
0167:0046906C  MOV      EDX,EAX      <---EAX中为上面Call调用的返回值,为用户名第1个字符
0167:0046906E  LEA      ECX,[EBP-44]
0167:00469071  CALL     EBX
0167:00469073  MOV      EAX,[ESI+38]
0167:00469076  LEA      ECX,[EBP-44]
0167:00469079  PUSH     ECX
0167:0046907A  PUSH     EAX
0167:0046907B  MOV      EDX,[EAX]
0167:0046907D  CALL     NEAR [EDX+1C]
0167:00469080  TEST     EAX,EAX
0167:00469082  JNL      00469096
0167:00469084  MOV      EDX,[ESI+38]
0167:00469087  PUSH     BYTE +1C
0167:00469089  PUSH     DWORD 00411460
0167:0046908E  PUSH     EDX
0167:0046908F  PUSH     EAX
0167:00469090  CALL     `MSVBVM50!__vbaHresultCheckObj`
0167:00469096  LEA      ECX,[EBP-44]
0167:00469099  CALL     `MSVBVM50!__vbaFreeStr`
0167:0046909F  LEA      ECX,[EBP-4C]
0167:004690A2  CALL     `MSVBVM50!__vbaFreeObj`
0167:004690A8  LEA      EAX,[EBP+FFFFFF7C]
0167:004690AE  LEA      ECX,[EBP-74]
0167:004690B1  PUSH     EAX
0167:004690B2  LEA      EDX,[EBP-64]
0167:004690B5  PUSH     ECX
0167:004690B6  PUSH     EDX
0167:004690B7  PUSH     BYTE +03
0167:004690B9  CALL     `MSVBVM50!__vbaFreeVarList`
0167:004690BF  ADD      ESP,BYTE +10
0167:004690C2  PUSH     ESI
0167:004690C3  CALL     NEAR [EBP+FFFFF804]
0167:004690C9  PUSH     EAX
0167:004690CA  LEA      EAX,[EBP-4C]
0167:004690CD  PUSH     EAX
0167:004690CE  CALL     `MSVBVM50!__vbaObjSet`
0167:004690D4  MOV      EAX,[EBP-4C]
0167:004690D7  LEA      ECX,[EBP-64]
0167:004690DA  PUSH     BYTE +05
0167:004690DC  LEA      EDX,[EBP-74]
0167:004690DF  PUSH     ECX
0167:004690E0  PUSH     EDX
0167:004690E1  MOV      DWORD [EBP-4C],00
0167:004690E8  MOV      [EBP-5C],EAX
0167:004690EB  MOV      DWORD [EBP-64],09
0167:004690F2  CALL     `MSVBVM50!rtcLeftCharVar`
0167:004690F8  LEA      EAX,[EBP-74]
0167:004690FB  PUSH     EAX
0167:004690FC  CALL     `MSVBVM50!__vbaStrVarMove`
0167:00469102  MOV      EDX,EAX
0167:00469104  LEA      ECX,[EBP-44]
0167:00469107  CALL     EBX
0167:00469109  MOV      EAX,[ESI+38]
0167:0046910C  LEA      EDX,[EBP-48]
0167:0046910F  PUSH     EDX
0167:00469110  LEA      EDX,[EBP-44]
0167:00469113  MOV      ECX,[EAX]
0167:00469115  PUSH     EDX
0167:00469116  PUSH     EAX
0167:00469117  CALL     NEAR [ECX+20]    <---根据字符值计算得到一串值
0167:0046911A  TEST     EAX,EAX
0167:0046911C  JNL      00469130
0167:0046911E  MOV      ECX,[ESI+38]
0167:00469121  PUSH     BYTE +20
0167:00469123  PUSH     DWORD 00411460
0167:00469128  PUSH     ECX
0167:00469129  PUSH     EAX
0167:0046912A  CALL     `MSVBVM50!__vbaHresultCheckObj`
0167:00469130  MOV      EDX,[EBP-48]    <---[EBP-48]中为根据字符计算得到的值
0167:00469133  LEA      ECX,[EBP-30]
0167:00469136  MOV      DWORD [EBP-48],00
0167:0046913D  CALL     EBX
0167:0046913F  LEA      ECX,[EBP-44]
0167:00469142  CALL     `MSVBVM50!__vbaFreeStr`
0167:00469148  LEA      ECX,[EBP-4C]
0167:0046914B  CALL     `MSVBVM50!__vbaFreeObj`
0167:00469151  LEA      EDX,[EBP-74]
0167:00469154  LEA      EAX,[EBP-64]
0167:00469157  PUSH     EDX
0167:00469158  PUSH     EAX
0167:00469159  PUSH     BYTE +02
0167:0046915B  CALL     `MSVBVM50!__vbaFreeVarList`
0167:00469161  MOV      EAX,01         <---EAX=1
0167:00469166  ADD      ESP,BYTE +0C  
0167:00469169  ADD      AX,[EBP-20]    <---计数器加1
0167:0046916D  JO       NEAR 0046B040  
0167:00469173  MOV      [EBP-20],EAX  
0167:00469176  JMP      00469004
-------------第一个大循环结束---------------------
我的用户名为6位,所以程序在此循环6次,得到6组字符
? N i ? Q
W b ) W f
P x @ P 7
2 i ; 2 l
& A 3 & E
P x @ P 7
这些是怎么算出来的呢,有兴趣的话跟进上面的那个Call进去看看,我跟了一下,功力不够
不能详细的分析出来,所以不写了。好像是字符值分别与固定串的前五位"4 B E 3 4"计算然后查表得到
在那个Call里面看到的表如下:
8 x 3 p 7 B e a
b c d f g h i j
k l m n o q r s
t u v w y z A C
D E F G H I J K
L M N O P Q R S
T U V W X Y Z .
1 2 4 6 5 9 0 -
` # / \ ! @ $ <
> & * ( ) [ ] {
} ' ; : , ? = +
后面还有一行记不清了,我是用手抄的太乱。谁知道TRW中如何将寄存器中的表值抓图抓下来

这些字串干什么用呢,接着往后看....
0167:0046917B  MOV      EDX,[EBP-30]      <---用户名字符取完后跳到这
0167:0046917E  LEA      ECX,[EBP-1C]
0167:00469181  CALL     `MSVBVM50!__vbaStrCopy`
0167:00469187  MOV      ECX,[EBP-1C]      <---[EBP-1C]中为最后1个字符运算得到的字串
0167:0046918A  PUSH     ECX
0167:0046918B  CALL     `MSVBVM50!__vbaLenBstr`
0167:00469191  MOV      ESI,EAX
0167:00469193  PUSH     BYTE +00
0167:00469195  MOV      EDX,ESI
0167:00469197  LEA      EAX,[EBP-18]
0167:0046919A  DEC      EDX
0167:0046919B  MOV      [EBP-24],ESI
0167:0046919E  JO       NEAR 0046B040
0167:004691A4  PUSH     EDX
0167:004691A5  PUSH     BYTE +01
0167:004691A7  PUSH     BYTE +00
0167:004691A9  PUSH     EAX
0167:004691AA  PUSH     BYTE +01
0167:004691AC  PUSH     BYTE +00
0167:004691AE  CALL     `MSVBVM50!__vbaRedim`
0167:004691B4  MOV      ECX,ESI
0167:004691B6  ADD      ESP,BYTE +1C
0167:004691B9  DEC      ECX
0167:004691BA  JO       NEAR 0046B040
0167:004691C0  CALL     `MSVBVM50!__vbaI2I4`
0167:004691C6  MOV      [EBP+FFFFF854],EAX
0167:004691CC  XOR      ESI,ESI      <---ESI=0  
----------------第2个大循环-------------------
0167:004691CE  CMP      SI,[EBP+FFFFF854] <---[EBP+FFFFF854]中为字串长度
0167:004691D5  JG       NEAR 004692BB         比较是否取完字串
0167:004691DB  MOV      AX,SI
0167:004691DE  LEA      ECX,[EBP-1C]      <---ECX=[EBP-1C]为最后一个字符运算得到的字串
0167:004691E1  INC      AX
0167:004691E3  MOV      [EBP+FFFFFAF4],ECX
0167:004691E9  JO       NEAR 0046B040
0167:004691EF  LEA      EDX,[EBP-64]
0167:004691F2  MOV      DWORD [EBP-5C],01
0167:004691F9  MOVSX    ECX,AX
0167:004691FC  PUSH     EDX
0167:004691FD  LEA      EDX,[EBP+FFFFFAEC]
0167:00469203  PUSH     ECX
0167:00469204  LEA      EAX,[EBP-74]
0167:00469207  PUSH     EDX
0167:00469208  PUSH     EAX
0167:00469209  MOV      DWORD [EBP-64],02
0167:00469210  MOV      DWORD [EBP+FFFFFAEC],4008
0167:0046921A  CALL     EDI
0167:0046921C  MOV      EAX,[EBP-18]
0167:0046921F  TEST     EAX,EAX
0167:00469221  JZ       00469252
0167:00469223  CMP      WORD [EAX],BYTE +01
0167:00469227  JNZ      00469252
0167:00469229  MOV      EDX,[EAX+14]
0167:0046922C  MOVSX    ECX,SI
0167:0046922F  SUB      ECX,EDX
0167:00469231  MOV      EDX,[EAX+10]
0167:00469234  CMP      ECX,EDX
0167:00469236  MOV      [EBP+FFFFF878],ECX
0167:0046923C  JC       0046924A
0167:0046923E  CALL     `MSVBVM50!__vbaGenerateBoundsError`
0167:00469244  MOV      ECX,[EBP+FFFFF878]
0167:0046924A  MOV      [EBP+FFFFF7FC],ECX
0167:00469250  JMP      SHORT 0046925E
0167:00469252  CALL     `MSVBVM50!__vbaGenerateBoundsError`
0167:00469258  MOV      [EBP+FFFFF7FC],EAX
0167:0046925E  LEA      ECX,[EBP-74]
0167:00469261  LEA      EDX,[EBP-44]
0167:00469264  PUSH     ECX
0167:00469265  PUSH     EDX
0167:00469266  CALL     `MSVBVM50!__vbaStrVarVal`
0167:0046926C  PUSH     EAX   <---EAX中为上面的Call的返回值为字串第1个字符
0167:0046926D  CALL     `MSVBVM50!rtcAnsivalueBstr`
0167:00469273  MOV      ECX,EAX  <---ECX=EAX=字符的Hex值
0167:00469275  CALL     `MSVBVM50!__vbaUI1I2`
0167:0046927B  MOV      ECX,[EBP-18]
0167:0046927E  MOV      EDX,[ECX+0C]
0167:00469281  MOV      ECX,[EBP+FFFFF7FC]
0167:00469287  MOV      [EDX+ECX],AL   <---将字符的值存到[EDX+ECX]中
0167:0046928A  LEA      ECX,[EBP-44]
0167:0046928D  CALL     `MSVBVM50!__vbaFreeStr`
0167:00469293  LEA      EDX,[EBP-74]
0167:00469296  LEA      EAX,[EBP-64]
0167:00469299  PUSH     EDX
0167:0046929A  PUSH     EAX
0167:0046929B  PUSH     BYTE +02
0167:0046929D  CALL     `MSVBVM50!__vbaFreeVarList`
0167:004692A3  MOV      EAX,01    <---EAX=1
0167:004692A8  ADD      ESP,BYTE +0C
0167:004692AB  ADD      AX,SI     <---计数器加1
0167:004692AE  JO       NEAR 0046B040
0167:004692B4  MOV      ESI,EAX
0167:004692B6  JMP      004691CE
---------------第2个大循环结束--------------------
上面这段程序其实就是把双字字串转换为单字字串存到[EDX]起的地址处

0167:004692BB  MOV      ECX,[EBP-24]
0167:004692BE  DEC      ECX
0167:004692BF  JO       NEAR 0046B040
0167:004692C5  CALL     `MSVBVM50!__vbaI2I4`
0167:004692CB  MOV      [EBP+FFFFF84C],EAX
0167:004692D1  XOR      ESI,ESI
---------------第3个大循环--------------------
0167:004692D3  CMP      SI,[EBP+FFFFF84C]   <---[EBP+FFFFF84C]中为转换后的字串长度
0167:004692DA  MOV      [EBP-20],ESI             比较是否取完字串
0167:004692DD  JG       NEAR 004693C0
0167:004692E3  MOV      ECX,[EBP-18]
0167:004692E6  LEA      EDX,[EBP-40]
0167:004692E9  PUSH     ECX
0167:004692EA  PUSH     EDX
0167:004692EB  CALL     `MSVBVM50!__vbaAryLock`
0167:004692F1  MOV      ECX,[EBP-40]
0167:004692F4  TEST     ECX,ECX
0167:004692F6  JZ       0046931E
0167:004692F8  CMP      WORD [ECX],BYTE +01
0167:004692FC  JNZ      0046931E
0167:004692FE  MOVSX    ESI,WORD [EBP-20]
0167:00469302  MOV      EDX,[ECX+14]
0167:00469305  MOV      EAX,[ECX+10]
0167:00469308  SUB      ESI,EDX
0167:0046930A  CMP      ESI,EAX
0167:0046930C  JC       00469317
0167:0046930E  CALL     `MSVBVM50!__vbaGenerateBoundsError`
0167:00469314  MOV      ECX,[EBP-40]
0167:00469317  MOV      EAX,ESI
0167:00469319  MOV      ESI,[EBP-20]
0167:0046931C  JMP      SHORT 00469327
0167:0046931E  CALL     `MSVBVM50!__vbaGenerateBoundsError`
0167:00469324  MOV      ECX,[EBP-40]
0167:00469327  MOV      ECX,[ECX+0C]
0167:0046932A  LEA      EDX,[EBP+FFFFFAEC]
0167:00469330  ADD      ECX,EAX
0167:00469332  LEA      EAX,[EBP-64]
0167:00469335  PUSH     EDX
0167:00469336  PUSH     EAX
0167:00469337  MOV      [EBP+FFFFFAF4],ECX
0167:0046933D  MOV      DWORD [EBP+FFFFFAEC],4011
0167:00469347  CALL     `MSVBVM50!rtcHexVarFromVar` <---这个Call应该是取字符的Hex值吧
0167:0046934D  LEA      ECX,[EBP-40]
0167:00469350  PUSH     ECX
0167:00469351  CALL     `MSVBVM50!__vbaAryUnlock`
0167:00469357  LEA      EDX,[EBP-64]
0167:0046935A  PUSH     EDX
0167:0046935B  CALL     `MSVBVM50!__vbaStrVarMove`  
0167:00469361  MOV      EDX,EAX      <---EAX中为字符的Hex值,为双字形式
0167:00469363  LEA      ECX,[EBP-3C]
0167:00469366  CALL     EBX
0167:00469368  LEA      ECX,[EBP-64]
0167:0046936B  CALL     `MSVBVM50!__vbaFreeVar`
0167:00469371  MOV      EAX,[EBP-3C]
0167:00469374  PUSH     EAX
0167:00469375  CALL     `MSVBVM50!__vbaLenBstr`
0167:0046937B  CMP      EAX,BYTE +01
0167:0046937E  JNZ      00469396
0167:00469380  MOV      ECX,[EBP-3C]
0167:00469383  PUSH     DWORD 0040F4B8
0167:00469388  PUSH     ECX
0167:00469389  CALL     `MSVBVM50!__vbaStrCat`
0167:0046938F  MOV      EDX,EAX
0167:00469391  LEA      ECX,[EBP-3C]
0167:00469394  CALL     EBX
0167:00469396  MOV      EDX,[EBP-2C]
0167:00469399  MOV      EAX,[EBP-3C]
0167:0046939C  PUSH     EDX
0167:0046939D  PUSH     EAX
0167:0046939E  CALL     `MSVBVM50!__vbaStrCat` <此Call将转换后的字串的Hex值连在一
0167:004693A4  MOV      EDX,EAX                 起组成一个双字字串,返回值在EAX中
0167:004693A6  LEA      ECX,[EBP-2C]
0167:004693A9  CALL     EBX
0167:004693AB  MOV      EAX,01      <---EAX=01
0167:004693B0  ADD      AX,SI       <---计数器加1
0167:004693B3  JO       NEAR 0046B040
0167:004693B9  MOV      ESI,EAX
0167:004693BB  JMP      004692D3
---------------第3个大循环结束--------------------
真是服了作者了,这样来考验Cracker的耐心,上面这段循环将转换后的字串"Px@P7"用
它们的Hex值连成一个双字字串"5 0 7 8 4 0 5 0 3 7"

0167:004693C0  MOV      ECX,[EBP-2C]
0167:004693C3  PUSH     ECX
0167:004693C4  CALL     `MSVBVM50!__vbaLenBstr`  <--求转换后的双字字串长度
0167:004693CA  MOV      ECX,EAX
0167:004693CC  CALL     `MSVBVM50!__vbaI2I4`
0167:004693D2  MOV      ESI,[0048260C]
0167:004693D8  MOV      [EBP+FFFFF844],EAX
0167:004693DE  MOV      DWORD [EBP-20],01
0167:004693E5  MOV      EAX,[EBP-20]
---------------第4个大循环--------------------
0167:004693E8  CMP      AX,[EBP+FFFFF844]  <--[EBP+FFFFF844]中为字串长度
0167:004693EF  JG       NEAR 00469617          比较是否取完字串
0167:004693F5  CWD    
0167:004693F7  MOV      CX,03            <---CX=03
0167:004693FB  IDIV     CX
0167:004693FE  TEST     DX,DX            <---其实就是对字串的第3 6 9位采取不同的处理
0167:00469401  JNZ      00469468            
0167:00469403  MOV      EDX,[EBP-28]
0167:00469406  LEA      EAX,[EBP-2C]
0167:00469409  MOV      [EBP+FFFFFAD4],EDX
0167:0046940F  LEA      ECX,[EBP-64]
0167:00469412  MOVSX    EDX,WORD [EBP-20]
0167:00469416  MOV      [EBP+FFFFFAF4],EAX
0167:0046941C  PUSH     ECX
0167:0046941D  LEA      EAX,[EBP+FFFFFAEC]
0167:00469423  PUSH     EDX
0167:00469424  LEA      ECX,[EBP-74]
0167:00469427  PUSH     EAX
0167:00469428  PUSH     ECX
0167:00469429  MOV      DWORD [EBP+FFFFFACC],08
0167:00469433  MOV      DWORD [EBP-5C],01
0167:0046943A  MOV      DWORD [EBP-64],02
0167:00469441  MOV      DWORD [EBP+FFFFFAEC],4008
0167:0046944B  CALL     EDI
0167:0046944D  LEA      EDX,[EBP-74]
0167:00469450  LEA      EAX,[EBP-44]
0167:00469453  PUSH     EDX
0167:00469454  PUSH     EAX
0167:00469455  CALL     `MSVBVM50!__vbaStrVarVal` <--按位取字串中的每位
0167:0046945B  PUSH     EAX          
0167:0046945C  CALL     `MSVBVM50!rtcAnsivalueBstr`<--求每个字符的Hex值
0167:00469462  ADD      AX,12           <---AX=AX+12 对第3 6 9位的Hex加12
0167:00469466  JMP      SHORT 004694E1
0167:00469468  MOV      AX,[EBP-20]
0167:0046946C  MOV      CX,07           <---CX=7
0167:00469470  CWD    
0167:00469472  IDIV     CX
0167:00469475  TEST     DX,DX           <---对字串的第7位采取不同的处理
0167:00469478  JNZ      NEAR 00469541
0167:0046947E  MOV      EDX,[EBP-28]
0167:00469481  LEA      EAX,[EBP-2C]
0167:00469484  MOV      [EBP+FFFFFAD4],EDX
0167:0046948A  LEA      ECX,[EBP-64]
0167:0046948D  MOVSX    EDX,WORD [EBP-20]
0167:00469491  MOV      [EBP+FFFFFAF4],EAX
0167:00469497  PUSH     ECX
0167:00469498  LEA      EAX,[EBP+FFFFFAEC]
0167:0046949E  PUSH     EDX
0167:0046949F  LEA      ECX,[EBP-74]
0167:004694A2  PUSH     EAX
0167:004694A3  PUSH     ECX
0167:004694A4  MOV      DWORD [EBP+FFFFFACC],08
0167:004694AE  MOV      DWORD [EBP-5C],01
0167:004694B5  MOV      DWORD [EBP-64],02
0167:004694BC  MOV      DWORD [EBP+FFFFFAEC],4008
0167:004694C6  CALL     EDI
0167:004694C8  LEA      EDX,[EBP-74]
0167:004694CB  LEA      EAX,[EBP-44]
0167:004694CE  PUSH     EDX
0167:004694CF  PUSH     EAX
0167:004694D0  CALL     `MSVBVM50!__vbaStrVarVal`
0167:004694D6  PUSH     EAX
0167:004694D7  CALL     `MSVBVM50!rtcAnsivalueBstr`
0167:004694DD  ADD      AX,14           <---AX=AX+14 对字串的第7位的Hex值加14
0167:004694E1  JO       NEAR 0046B040
0167:004694E7  MOVSX    ECX,AX
0167:004694EA  LEA      EDX,[EBP+FFFFFF7C]
0167:004694F0  PUSH     ECX
0167:004694F1  PUSH     EDX
0167:004694F2  CALL     `MSVBVM50!rtcVarBstrFromAnsi`
0167:004694F8  LEA      EAX,[EBP+FFFFFACC]
0167:004694FE  LEA      ECX,[EBP+FFFFFF7C]
0167:00469504  PUSH     EAX
0167:00469505  LEA      EDX,[EBP+FFFFFF6C]
0167:0046950B  PUSH     ECX
0167:0046950C  PUSH     EDX
0167:0046950D  CALL     ESI
0167:0046950F  PUSH     EAX
0167:00469510  CALL     `MSVBVM50!__vbaStrVarMove`
0167:00469516  MOV      EDX,EAX
0167:00469518  LEA      ECX,[EBP-28]
0167:0046951B  CALL     EBX
0167:0046951D  LEA      ECX,[EBP-44]
0167:00469520  CALL     `MSVBVM50!__vbaFreeStr`
0167:00469526  LEA      EAX,[EBP+FFFFFF6C]
0167:0046952C  LEA      ECX,[EBP+FFFFFF7C]
0167:00469532  PUSH     EAX
0167:00469533  LEA      EDX,[EBP-74]
0167:00469536  PUSH     ECX
0167:00469537  LEA      EAX,[EBP-64]
0167:0046953A  PUSH     EDX
0167:0046953B  PUSH     EAX
0167:0046953C  JMP      004695F5
0167:00469541  MOV      ECX,[EBP-28]
0167:00469544  LEA      EDX,[EBP-2C]
0167:00469547  MOV      [EBP+FFFFFAD4],ECX
0167:0046954D  LEA      EAX,[EBP-64]
0167:00469550  MOVSX    ECX,WORD [EBP-20]
0167:00469554  MOV      [EBP+FFFFFAF4],EDX
0167:0046955A  PUSH     EAX
0167:0046955B  LEA      EDX,[EBP+FFFFFAEC]
0167:00469561  PUSH     ECX
0167:00469562  LEA      EAX,[EBP-74]
0167:00469565  PUSH     EDX
0167:00469566  PUSH     EAX
0167:00469567  MOV      DWORD [EBP+FFFFFACC],08
0167:00469571  MOV      DWORD [EBP-5C],01
0167:00469578  MOV      DWORD [EBP-64],02
0167:0046957F  MOV      DWORD [EBP+FFFFFAEC],4008
0167:00469589  CALL     EDI
0167:0046958B  LEA      ECX,[EBP-74]
0167:0046958E  LEA      EDX,[EBP-44]
0167:00469591  PUSH     ECX
0167:00469592  PUSH     EDX
0167:00469593  CALL     `MSVBVM50!__vbaStrVarVal`
0167:00469599  PUSH     EAX
0167:0046959A  CALL     `MSVBVM50!rtcAnsivalueBstr`
0167:004695A0  MOVSX    EAX,AX
0167:004695A3  LEA      ECX,[EBP+FFFFFF7C]
0167:004695A9  PUSH     EAX
0167:004695AA  PUSH     ECX
0167:004695AB  CALL     `MSVBVM50!rtcVarBstrFromAnsi`
0167:004695B1  LEA      EDX,[EBP+FFFFFACC]
0167:004695B7  LEA      EAX,[EBP+FFFFFF7C]
0167:004695BD  PUSH     EDX
0167:004695BE  LEA      ECX,[EBP+FFFFFF6C]
0167:004695C4  PUSH     EAX
0167:004695C5  PUSH     ECX
0167:004695C6  CALL     ESI
0167:004695C8  PUSH     EAX
0167:004695C9  CALL     `MSVBVM50!__vbaStrVarMove`
0167:004695CF  MOV      EDX,EAX           <---此时D EDX可看到连结在一起的新字串
0167:004695D1  LEA      ECX,[EBP-28]
0167:004695D4  CALL     EBX
0167:004695D6  LEA      ECX,[EBP-44]
0167:004695D9  CALL     `MSVBVM50!__vbaFreeStr`
0167:004695DF  LEA      EDX,[EBP+FFFFFF6C]
0167:004695E5  LEA      EAX,[EBP+FFFFFF7C]
0167:004695EB  PUSH     EDX
0167:004695EC  LEA      ECX,[EBP-74]
0167:004695EF  PUSH     EAX
0167:004695F0  LEA      EDX,[EBP-64]
0167:004695F3  PUSH     ECX
0167:004695F4  PUSH     EDX
0167:004695F5  PUSH     BYTE +04
0167:004695F7  CALL     `MSVBVM50!__vbaFreeVarList`
0167:004695FD  MOV      EAX,01     <---EAX=1
0167:00469602  ADD      ESP,BYTE +14
0167:00469605  ADD      AX,[EBP-20] <---计数器加1
0167:00469609  JO       NEAR 0046B040
0167:0046960F  MOV      [EBP-20],EAX
0167:00469612  JMP      004693E8
---------------第4个大循环结束--------------------
上面的循环对第3循环后的字串"5 0 7 8 4 0 5 0 3 7"再进行处理,
即对第3 6 9位Hex值加12,第7位Hex值加14,其余位不变,组成新的字串为
"5 0 I 8 4 B I 0 E 7"

0167:00469617  MOV      EAX,[EBP-28]
0167:0046961A  PUSH     EAX
0167:0046961B  CALL     `MSVBVM50!__vbaLenBstr` <---求字串长度
0167:00469621  CMP      EAX,BYTE +05            
0167:00469624  JNG      NEAR 00469730
0167:0046962A  MOV      ECX,[EBP-38]
0167:0046962D  LEA      EDX,[EBP-28]
0167:00469630  LEA      EAX,[EBP-64]
0167:00469633  MOV      [EBP+FFFFFAD4],ECX
0167:00469639  MOV      [EBP+FFFFFAF4],EDX
0167:0046963F  PUSH     EAX
0167:00469640  LEA      ECX,[EBP+FFFFFAEC]
0167:00469646  PUSH     BYTE +01
0167:00469648  LEA      EDX,[EBP-74]
0167:0046964B  PUSH     ECX
0167:0046964C  PUSH     EDX
0167:0046964D  MOV      DWORD [EBP+FFFFFACC],08
0167:00469657  MOV      DWORD [EBP-5C],05
0167:0046965E  MOV      DWORD [EBP-64],02
0167:00469665  MOV      DWORD [EBP+FFFFFAEC],4008
0167:0046966F  CALL     EDI
0167:00469671  LEA      EAX,[EBP+FFFFFACC]
0167:00469677  LEA      ECX,[EBP-74]
0167:0046967A  PUSH     EAX
0167:0046967B  LEA      EDX,[EBP+FFFFFF7C]
0167:00469681  PUSH     ECX
0167:00469682  PUSH     EDX
0167:00469683  MOV      DWORD [EBP+FFFFFAC4],0041144C <--0041144C中的为"-"
0167:0046968D  MOV      DWORD [EBP+FFFFFABC],08
0167:00469697  CALL     ESI
0167:00469699  PUSH     EAX
0167:0046969A  LEA      EAX,[EBP+FFFFFABC]
0167:004696A0  LEA      ECX,[EBP+FFFFFF6C]
0167:004696A6  PUSH     EAX
0167:004696A7  PUSH     ECX
0167:004696A8  CALL     ESI
0167:004696AA  PUSH     EAX
0167:004696AB  CALL     `MSVBVM50!__vbaStrVarMove`
0167:004696B1  MOV      EDX,EAX
0167:004696B3  LEA      ECX,[EBP-38]
0167:004696B6  CALL     EBX
0167:004696B8  LEA      EDX,[EBP+FFFFFF6C]
0167:004696BE  LEA      EAX,[EBP+FFFFFF7C]
0167:004696C4  PUSH     EDX
0167:004696C5  LEA      ECX,[EBP-74]
0167:004696C8  PUSH     EAX
0167:004696C9  LEA      EDX,[EBP-64]
0167:004696CC  PUSH     ECX
0167:004696CD  PUSH     EDX
0167:004696CE  PUSH     BYTE +04
0167:004696D0  CALL     `MSVBVM50!__vbaFreeVarList`
0167:004696D6  MOV      ECX,[EBP-28]
0167:004696D9  ADD      ESP,BYTE +14
0167:004696DC  LEA      EAX,[EBP-28]
0167:004696DF  MOV      DWORD [EBP+FFFFFAEC],4008
0167:004696E9  PUSH     ECX
0167:004696EA  MOV      [EBP+FFFFFAF4],EAX
0167:004696F0  CALL     `MSVBVM50!__vbaLenBstr`
0167:004696F6  SUB      EAX,BYTE +05
0167:004696F9  LEA      EDX,[EBP+FFFFFAEC]
0167:004696FF  JO       NEAR 0046B040
0167:00469705  PUSH     EAX
0167:00469706  LEA      EAX,[EBP-64]
0167:00469709  PUSH     EDX
0167:0046970A  PUSH     EAX
0167:0046970B  CALL     `MSVBVM50!rtcRightCharVar`
0167:00469711  LEA      ECX,[EBP-64]
0167:00469714  PUSH     ECX
0167:00469715  CALL     `MSVBVM50!__vbaStrVarMove`
0167:0046971B  MOV      EDX,EAX         <---D EAX可看到注册码的前半部分
0167:0046971D  LEA      ECX,[EBP-28]        字串"5 0 I 8 4 -"
0167:00469720  CALL     EBX
0167:00469722  LEA      ECX,[EBP-64]
0167:00469725  CALL     `MSVBVM50!__vbaFreeVar`
0167:0046972B  JMP      00469617    <--00469617代码中没有这行啦,可一运行就有了,怎么实现的?
0167:00469730  MOV      EDX,[EBP-38]    <---注册码的前半部分"50I84-"
0167:00469733  MOV      EAX,[EBP-28]    <---注册码的前半部分"BI0E7"
0167:00469736  PUSH     EDX
0167:00469737  PUSH     EAX
0167:00469738  CALL     `MSVBVM50!__vbaStrCat`   <---连接字串
0167:0046973E  MOV      EDX,EAX         <---D EDX即可看到正确的注册码
0167:00469740  LEA      ECX,[EBP-38]
0167:00469743  CALL     EBX
0167:00469745  PUSH     DWORD 2710
0167:0046974A  CALL     004203B0
0167:0046974F  MOV      ECX,[EBP+08]
后面还有好多操作,大概是解除未注册最多只能添加7张图片来创建屏幕保护的限制,才执行到注册成功与注册失败对话框,我看不太懂,就不贴出来了。写得好累,不写了,反正注册码已经跟出来了,各位如果有兴趣的话自己跟一下看看吧!

多说两句,这个软件破得真是辛苦,因为没学过VB,所以其中许多Call调用一下子没能看明白,上面还有许多没注释,其实是自己不知道该如何说明。还有第1个大循环中的0167:00469117  CALL NEAR [ECX+20],跟进去看得一头雾水,还请各位大侠跟一下看看,以解小弟心头之惑。唉!真的要好好学学VB了。
注册码其实只与用户名的最后一位有关,它是根据用户名的最后一位与固定串"4BE43-BI3G8"的前5位运算再加以转换得到注册码。我的注册码只要用户名最后一位为"e"应该都可以用。
我得到的为:
用户名:ShenGe 注册码:50I84-BI0E7

---------------------------------ShenGe------------------------------------

贴个笑话,轻松一下吧!
孔子的补习班

话说,很久很久以前,有位老兄名叫孔子开了中国史上最大的补习班,影响后世深远,补习班制度完备,对补习费有详细规定:
十五志而学:要进补习班,要交十五两作为报名费。
三十而立:交三十两的人,只能站着听课。
四十不惑:交四十两,老师上课会讲到让你没有问题为止。
五十知天命:交五十两,还可以知道明天小考的命题。
六十耳顺:交六十两除了上述优待之外,老师还会讲得让你听得很舒服。
七十从心所欲:交七十两的话,上课时随便你要站着、坐着、趴着、滚来滚去,都不会管你。