• 标 题:怎样才能让软件成为自身的注册机-让软件自动输出注册码的一种方法 (10千字)
  • 作 者:lei_z_r
  • 时 间:2003-3-3 17:47:22
  • 链 接:http://bbs.pediy.com

怎样才能让软件成为自身的注册机-让软件自动输出注册码的一种方法

作  者:lzrlzr
信  箱:lzrlzr_crack@163.com
时  间:2003年3月3日
目标软件:试卷生成系统III
主程序: Dandelion.exe 文件大小:930304
下载网站:http://myprg.yeah.net
破解环境:Win98 第二版
破解工具:Peditor,hiew681,softice4.05

声明: 此文仅用于学习及交流,若要转载请保持文章完整。


  由于给一家公司作电脑培训考试,想出一份考试题,就从网上下载了一个试卷生成系统III,但这个软件要求注册,就随手把它破解了。这个软件破解挺简单,是明文比较,在softice中下bpx hmemcpy ,正确的注册码就可以从softice中跟踪得到,但由于我一直想写一篇软件自动输出注册码的的文章,刚好就拿它作例子了。
这个软件对注册码的判断有两次,可能是单机版和网络版两种版本的注册码不一样,如果注册码不正确,弹出一个请输入正确的注册码等等的提示窗口。注册成功后注册码保存在(试卷生成系统III(网络版)数据)文件目录中的SysDB08.DB数据库中。删文件除这个数据库文件后,就又变为未注册版本。

修改思想:
  在得到正确的注册码的地址以后,加入一段调用Messagebox的代码,把正确的注册码输出在Messagebox上。这是我以前的修改方法。(一般软件都用到了Messagebox函数,基本上不用手工引入函数)
  但在这个软件的主程序 Dandelion.exe的输入表(Import Table)中,竟没有发现Messagebox函数,那么它的注册码出错的窗口是怎样来的(这是我的第一反应),请看以下的关键代码的分析


======这一段是软件注册的关键代码

0167:0041F782  E8F9FCFFFF          CALL      0041F480 *********计算出正确的注册码的过程(1eb82h)。
0167:0041F787  8B45F8              MOV      EAX,[EBP-08]******EAX 中存放的是真正的注册码。(A)
0167:0041F78A  50                  PUSH      EAX
0167:0041F78B  8D55EC              LEA      EDX,[EBP-14]
0167:0041F78E  8B83DC020000        MOV      EAX,[EBX+000002DC]
0167:0041F794  E843A0FFFF          CALL      004197DC
0167:0041F799  8B55EC              MOV      EDX,[EBP-14]***EDX 中存放的是假注册码
0167:0041F79C  58                  POP      EAX************EAX 中存放的是真正的注册码。
0167:0041F79D  E8E619FEFF          CALL      00401188*******这是比较注册码是否正确的过程。
0167:0041F7A2  746C                JZ        0041F810*******跳走后,注册正确。
0167:0041F7A4  BA84FA4100          MOV      EDX,0041FA84
0167:0041F7A9  B8A4FA4100          MOV      EAX,0041FAA4
0167:0041F7AE  E8051AFEFF          CALL      004011B8
0167:0041F7B3  85C0                TEST      EAX,EAX
0167:0041F7B5  0F8544020000        JNZ      0041F9FF******如果不是网络版,跳走,出现错误窗口。
0167:0041F7BB  8D55FC              LEA      EDX,[EBP-04]
0167:0041F7BE  8B83CC020000        MOV      EAX,[EBX+000002CC]
0167:0041F7C4  E8B723FEFF          CALL      00401B80
0167:0041F7C9  8D45FC              LEA      EAX,[EBP-04]
0167:0041F7CC  50                  PUSH      EAX
0167:0041F7CD  8D55F4              LEA      EDX,[EBP-0C]
0167:0041F7D0  8B83E4020000        MOV      EAX,[EBX+000002E4]
0167:0041F7D6  E8A523FEFF          CALL      00401B80
0167:0041F7DB  8B55F4              MOV      EDX,[EBP-0C]
0167:0041F7DE  58                  POP      EAX
0167:0041F7DF  E88C19FEFF          CALL      00401170
0167:0041F7E4  8B45FC              MOV      EAX,[EBP-04]
0167:0041F7E7  8D55F8              LEA      EDX,[EBP-08]
0167:0041F7EA  E891FCFFFF          CALL      0041F480**********计算出正确的注册码的过程。
0167:0041F7EF  8B45F8              MOV      EAX,[EBP-08]******EAX 中存放的是真正的注册码。(B)
0167:0041F7F2  50                  PUSH      EAX
0167:0041F7F3  8D55EC              LEA      EDX,[EBP-14]
0167:0041F7F6  8B83DC020000        MOV      EAX,[EBX+000002DC]
0167:0041F7FC  E8DB9FFFFF          CALL      004197DC
0167:0041F801  8B55EC              MOV      EDX,[EBP-14]***EDX 中存放的是假注册码
0167:0041F804  58                  POP      EAX************EAX 中存放的是真正的注册码。
0167:0041F805  E87E19FEFF          CALL      00401188*******这是比较注册码是否正确的过程。
0167:0041F80A  0F85EF010000        JNZ      0041F9FF*******不跳走,注册正确。
=====================底下这一段是注册码正确以后的处理过程,就省略不讲了

0167:0041F810  8B83EC020000        MOV      EAX,[EBX+000002EC]
0167:0041F816  E819A0FFFF          CALL      00419834
......
......
0167:0041F9F1  E8625EFFFF          CALL      00415858
0167:0041F9F6  8BC3                MOV      EAX,EBX
0167:0041F9F8  E82B24FEFF          CALL      00401E28
0167:0041F9FD  EB15                JMP      0041FA14
=======================================================
跳到这里后,出现错误窗口。
这一段注册码不正确的处理过程,是我们分析的重点:

0167:0041F9FF  6A00                PUSH      00
0167:0041FA01  668B0D54FA4100      MOV      CX,[0041FA54]
0167:0041FA08  B201                MOV      DL,01
0167:0041FA0A  B880FC4100          MOV      EAX,0041FC80 **这是出现在窗口上的字符串。
0167:0041FA0F  E8445EFFFF          CALL      00415858******这里弹出错误窗口。**********(1)
0167:0041FA14  33C0                XOR      EAX,EAX
0167:0041FA16  5A                  POP      EDX
0167:0041FA17  59                  POP      ECX
跟进(1)后,来到这里:
0167:00415858  FF25E8DC4600        JMP      [0046DCE8]
0167:0041585E  8BC0                MOV      EAX,EAX

分析:

  注册码不正确后,跳到这里,出现错误窗口,本来以为这是一个Messagebox,在softice中下bpx Messagebox断点,竟然没有中断,后来在 (1)处跟进后,才发现这里是调用另外一个动态库(vcl40.bpl)中的一个函数,于是猜测这是一个可以输出各种窗口的函数,(后来试着改动了参数值以后,证明这个猜测是正确的)有了这个发现后,就想调用这个函数输出注册码。
  但首先得知道这个函数的原型和参数类型。分析这个函数的参数,共有四个,请看下面如何分析得到每一个参数的类型和值。

在0167:0041FA0F处向上看:

PUSH      00*************这是一个参数,猜测应是弹出窗口的父窗口的句柄。一般值应是 0
MOV      CX,[0041FA54]**这是第二个参数,跟踪后可知 [0041FA54]中的值是04,
             应该是弹出窗口的类型。
MOV      DL,01**********这是第三个参数,应该是窗口上的图标的类型,值01应该是代表错误的红图标。
MOV      EAX,0041FC80 **这是出现在窗口上的字符串。EAX中存放的是字符串的首地址。
CALL      00415858********这个是输出各种窗口的函数的调用。

把以上第二个参数,第三个参数值进行改变(加1或减1),从窗口界面的变化可以得到,
CX 是窗口按钮的类型,CX值不同,窗口上的按钮的多少和按钮名程就不同
DL 是窗口上的图型 DX值不同,窗口上的图形就不同。

分析结果:
把这个函数的调用参数用汇编语言的过程来表达(为了方便理解,我给这个函数命名为 Message)

Message PROTO hwnd:DWORD
CX 的值代表了弹出窗口的类型
DL 中的值是窗口上的图标的类型,01是代表错误的红图标,02是一个提示图标
EAX 中存放的是出现在窗口上的字符串的首地址

修改软件主程序:

  经过以上的分析,得到Message的函数原型。下来就是在那个地方调用这个Message。跟踪得知以上(A)和(B)处,注册码刚生成,EAX中存放的就是正确的注册码的首地址,那么就在(A)和(B)处加入自已的代码,以下是我修改后的代码,请注意和原来不同的地方
0167:0041F77F  8D55F8              LEA      EDX,[EBP-08]
0167:0041F782  E8F9FCFFFF          CALL      0041F480
0167:0041F787  8B45F8              MOV      EAX,[EBP-08]
0167:0041F78A  50                  PUSH      EAX
0167:0041F78B  6A00                PUSH      00************参数1
0167:0041F78D  66B90400            MOV      CX,0004*******参数2
0167:0041F791  90                  NOP
0167:0041F792  90                  NOP
0167:0041F793  90                  NOP
0167:0041F794  B201                MOV      DL,02*********参数3,02值是一个提示图标
0167:0041F796  90                  NOP
0167:0041F797  90                  NOP
0167:0041F798  90                  NOP
0167:0041F799  E8BA60FFFF          CALL      00415858********这就是输出注册码的窗口的函数的调用
0167:0041F79E  90                  NOP
0167:0041F79F  90                  NOP
0167:0041F7A0  90                  NOP
0167:0041F7A1  90                  NOP
0167:0041F7A2  90                  NOP
0167:0041F7A3  90                  NOP
0167:0041F7A4  BA84FA4100          MOV      EDX,0041FA84
0167:0041F7A9  B8A4FA4100          MOV      EAX,0041FAA4
0167:0041F7AE  E8051AFEFF          CALL      004011B8
0167:0041F7B3  85C0                TEST      EAX,EAX
0167:0041F7B5  90                  NOP
0167:0041F7B6  90                  NOP
0167:0041F7B7  90                  NOP
0167:0041F7B8  90                  NOP
0167:0041F7B9  90                  NOP
0167:0041F7BA  90                  NOP
0167:0041F7BB  8D55FC              LEA      EDX,[EBP-04]
0167:0041F7BE  8B83CC020000        MOV      EAX,[EBX+000002CC]
0167:0041F7C4  E8B723FEFF          CALL      00401B80
0167:0041F7C9  8D45FC              LEA      EAX,[EBP-04]
0167:0041F7CC  50                  PUSH      EAX
0167:0041F7CD  8D55F4              LEA      EDX,[EBP-0C]
0167:0041F7D0  8B83E4020000        MOV      EAX,[EBX+000002E4]
0167:0041F7D6  E8A523FEFF          CALL      00401B80
0167:0041F7DB  8B55F4              MOV      EDX,[EBP-0C]
0167:0041F7DE  58                  POP      EAX
0167:0041F7DF  E88C19FEFF          CALL      00401170
0167:0041F7E4  8B45FC              MOV      EAX,[EBP-04]
0167:0041F7E7  8D55F8              LEA      EDX,[EBP-08]
0167:0041F7EA  E891FCFFFF          CALL      0041F480
0167:0041F7EF  8B45F8              MOV      EAX,[EBP-08]
0167:0041F7F2  50                  PUSH      EAX
0167:0041F7F3  6A00                PUSH      00************参数1
0167:0041F7F5  66B90400            MOV      CX,0004*******参数2
0167:0041F7F9  B201                MOV      DL,02*********参数3,02值是一个提示图标
0167:0041F7FB  90                  NOP
0167:0041F7FC  E85760FFFF          CALL      00415858********这就是输出注册码的窗口的函数的调用
0167:0041F801  8B55EC              MOV      EDX,[EBP-14]
0167:0041F804  58                  POP      EAX
0167:0041F805  E87E19FEFF          CALL      00401188
0167:0041F80A  E9F0010000          JMP      0041F9FF*******不让软件注册
0167:0041F80F  90                  NOP
0167:0041F810  8B83EC020000        MOV      EAX,[EBX+000002EC]
0167:0041F816  E819A0FFFF          CALL      00419834

运行结果:
  修改后运行,在注册时输入学校名和姓名,输入假的注册码,弹出一个窗口(见图1),上面是真正的注册码,点确定后,又弹出一个窗口(见图2),上面是另外一个版本的注册码。至此,修改成功。

  一个软件的破解,有多种方法。这个软件也可以不这样麻烦的输出注册码,还有另外一种修改方法,直接将正确的注册码写入软件保存注册码的地方,就更方便了,第二种修改方法的教程请大家来写吧,我想告诉大家的就是如果破解时碰到困难,可以改变一下自已的分析思路,可能会有意想不到的收获。

另外,我在破解时在这个软件中发现这么一段文字,但没有看到软件中弹出这个窗口界面:

:0041F5BD 8BC7                    mov eax, edi
* Possible StringData Ref from Code Obj ->"恭喜你,你破解成功了。你是否觉得很容易呢?其实"
                                        ->"本系统的注册码并没有设计得多复杂,只要提醒使用"
                                        ->"者要支持国产软件而已。对于你的破解,我倒是想说"
                                        ->"一声:“感谢你”,如果没有你的破解,我的软件将"
                                        ->"流行不起来。" 
哈哈,原来如此。