• 标 题:Readbook 1.31破解心得 (3千字)
  • 作 者:冰毒
  • 时 间:2000-3-1 14:36:48
  • 链 接:http://bbs.pediy.com

这个程序的破解很费了一些时间.

1. 采用常规的方法BPX Getwindowtexta,SICE拦住后F12回到程序,查找输入的注册码,BPM(或BPR)找到的内存地址,发现程序将输入的注册码转换成16进制形式(比如12344321变成BC5C01). 用BPM设断,但程序频繁地被拦在无关的地方,很快迷失了方向
2. 拦截程序弹出的注册码无效的提示,返回程序,经过很久,找不出关键的跳转
3. 用Regmon和Filemon观察得知,程序不在注册表中做手脚,而是读readbook.ini文件,试用getprivateprofilestringa设断,拦住许多次,仍然找不到关键之处

单用动态跟踪看来比较困难,于是转向静态分析. 用W32dsm反汇编程序,寻找可疑的字符串,找到几个:
"NowDay"
"File"
"User"
"Register"
"RegisterEncryptMode"
猜测一下,"Nowday"应该是记载运行时的日期,因为未注册的版本在每天第一次使用时会'打扰'你一下. 注册成功时,在readbook.ini的[File]项目下会加上User和Register. "RegisterEncrytMode"应该是程序将注册码加密之后写入ini中.于是想到,既然注册码是以加密形式写入,那么程序运行时也必须再将其解码还原以做比较. 好,有办法了.
1. 手动在readbook.ini中[File]项下加上User=ABCD,Register=12344321
2. 在W32dsm中找"RegisterEncryptMode",共有两处,你会注意到两处的代码几乎是一样的.分别记下首行地址0041F6B7,00409A9F
3. BPX 0041F6B7,00409A9F (在TRW2000中你可直接如此设断,在SICE中可用Symbol loader载入程序,再设断)
4. 程序在00409A9F被拦住,

* Possible StringData Ref from Data Obj ->"RegisterEncryptMode"
                                  |
:00409A9F 6860E84500              push 0045E860
:00409AA4 57                      push edi
:00409AA5 8945FC                  mov dword ptr [ebp-04], eax
:00409AA8 C745F412320000          mov [ebp-0C], 00003212 <-很
:00409AAF C745E434120000          mov [ebp-1C], 00001234 <-有
:00409AB6 C745E888880000          mov [ebp-18], 00008888 <-意
:00409ABD C745F023230000          mov [ebp-10], 00002323 <-思
:00409AC4 E8A6AE0000              call 0041496F <-做什么?
:00409AC9 83C410                  add esp, 00000010
:00409ACC 85C0                    test eax, eax
:00409ACE 7524                    jne 00409AF4 <-试着改成je,不成功

5. 程序会提示你注册码错误,并删掉我们手动加上的User,Register.
没关系,重新再来一次

6. F10一直往下走,到了下一个条件跳转处

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409B34(C)
|
:00409B19 3975FC                  cmp dword ptr [ebp-04], esi
:00409B1C 741D                    je 00409B3B <-试改成jne

再查看Help菜单,Register选项没有了,About显示用户姓名ABCD. 终于给我找到要害处了. :)
好,再来一次,当光标停在00409B1C行时, ? esi 你就得到真正的注册码了. 实际上对于一个用户名而言,不只一个注册码,不信往下看.

:00409B1E 8B55EC                  mov edx, dword ptr [ebp-14]
:00409B21 8BC8                    mov ecx, eax
:00409B23 83E17F                  and ecx, 0000007F
:00409B26 03348A                  add esi, dword ptr [edx+4*ecx]
:00409B29 40                      inc eax
:00409B2A 3DFF0F0000              cmp eax, 00000FFF
:00409B2F A328034600              mov dword ptr [00460328], eax
:00409B34 72E3                    jb 00409B19

程序把你输入的注册码和4095(FFFh)个有效码相比,只要有一个相同就行.这样重名的人可以从作者处得到不同的注册码.

:00409B36 3975FC                  cmp dword ptr [ebp-04], esi <-最后一次机会
:00409B39 7547                    jne 00409B82 <-跳走就没戏了

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00409B1C(C)
|
:00409B3B 8B75F8                  mov esi, dword ptr [ebp-08]
:00409B3E C70500314B0001000000    mov dword ptr [004B3100], 00000001
:00409B48 FF761C                  push [esi+1C]


7. 用得到的注册码,注册程序即可.

特别声明: 这是个很好的程序,保护也做得不错.软件作者定的价格也相当低,不注册功能也没限制,只在每天第一次使用时给你个提醒.因此,如果大家使用这个软件的话,请尽量购买,支持和尊重作者的劳动.本人写这篇东西,只是做技术交流,所以我在文中没有给出任何有效的注册码.我本人也不用这个软件(因为在我的英文WIN95加挂Richwin的系统中,这个软件不能正常显示文本).