• 标 题:关于readbook1.42中的注册校验问题 (10千字)
  • 作 者:庄周梦蝶
  • 时 间:2002-1-21 14:15:32
  • 链 接:http://bbs.pediy.com

软件:Readbook 1.42
下载:随处可下
工具:SOFTICE4.05,WD32ASM.
    此软件的阅读功能确实不错,如果你喜欢看书的话可选它.相信有很多人都跟过了,难度只是一般.
因为我这几天想玩<<幽城>>,安装一看,天啊! 要2.5G的硬盘,可我那台破机整个硬盘才4.3G,只好用
PQMAGIC痛苦的东挪西凑.后来无意中用READBOOK打开README,噫? 居然说我的注册码不对,这可是我以
前跟出来的啊! 再重新输一次,还是不对? 想一想我刚才改了C盘的空间(我的READBOOK装在C盘中),莫非
它是用硬盘的空间来加入注册运算的,可我又不想再TRACE一次,因为它存放注册码的地址老在内存中变
来变去,很容易跟丢,你可跟一次试试,呵呵! 想到它是在程序起动时跳出检查框的,可能在程序开始就进
行注册校验,而它的注册信息全放在READBOOK.INI中,所以就下bpx getprivateprofilestringa do
"d *(esp+8)",如果下: bpx getprivateprofilestringa if(*(esp+8)=='User')do "d *(esp+8)"
SOFTICE不能中断,哪位高手能否解释一下? 还是SOFTICE的条件中断不好使?
    F5要按好多次,每次中断后看看数据窗里面是否有"User"这个词出现.有的话就按F12跳回READBOOK
的领空,接着就来到如下的代码:
* Possible StringData Ref from Data Obj ->"User"
                                  |
:0040A001 68A0484600              push 004648A0
:0040A006 57                      push edi
:0040A007 E8A0D30000              call 004173AC  ---->此CALL读Readbook.Ini
                                                      的User名
:0040A00C 83C41C                  add esp, 0000001C
:0040A00F 389D44FFFFFF            cmp byte ptr [ebp+FFFFFF44], bl
:0040A015 756D                    jne 0040A084
:0040A017 391DA4974B00            cmp dword ptr [004B97A4], ebx
:0040A01D 0F85DF010000            jne 0040A202
:0040A023 8D45EC                  lea eax, dword ptr [ebp-14]
:0040A026 50                      push eax
:0040A027 E84CBE0200              call 00435E78
:0040A02C 8B00                    mov eax, dword ptr [eax]
:0040A02E 53                      push ebx
:0040A02F 8D4DFC                  lea ecx, dword ptr [ebp-04]
:0040A032 8945FC                  mov dword ptr [ebp-04], eax
:0040A035 E851BE0200              call 00435E8B
:0040A03A 8B700C                  mov esi, dword ptr [eax+0C]

* Possible StringData Ref from Data Obj ->"NowDay"
                                  |
:0040A03D 6888474600              push 00464788
:0040A042 57                      push edi
:0040A043 E807D40000              call 0041744F
:0040A048 59                      pop ecx
:0040A049 3BF0                    cmp esi, eax
:0040A04B 59                      pop ecx
:0040A04C 0F84B0010000            je 0040A202
:0040A052 A14C5E4B00              mov eax, dword ptr [004B5E4C]
:0040A057 3BC3                    cmp eax, ebx
:0040A059 0F84A3010000            je 0040A202
:0040A05F C6802803000001          mov byte ptr [eax+00000328], 01
:0040A066 A14C5E4B00              mov eax, dword ptr [004B5E4C]
:0040A06B 53                      push ebx

* Possible Ref to Menu: MenuID_0080, Item: "s?A)ReadBook..."
                                  |
:0040A06C 6840E10000              push 0000E140
:0040A071 6811010000              push 00000111
:0040A076 FF701C                  push [eax+1C]

* Reference To: USER32.PostMessageA, Ord:01DEh
                                  |
:0040A079 FF1528264500            Call dword ptr [00452628]
:0040A07F E97E010000              jmp 0040A202

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A015(C)
|
:0040A084 8D8544FFFFFF            lea eax, dword ptr [ebp+FFFFFF44]
:0040A08A 50                      push eax
:0040A08B E8E6A30200              call 00434476
:0040A090 8B854CFFFFFF            mov eax, dword ptr [ebp+FFFFFF4C]  此处为USER的ASCII
                                                                码共16个,不足用20补足.
:0040A096 8B8D48FFFFFF            mov ecx, dword ptr [ebp+FFFFFF48]  EAX=8--12,ECX=
                                                                    4--8位,ESI=1--4位.
:0040A09C 8BB544FFFFFF            mov esi, dword ptr [ebp+FFFFFF44] 
:0040A0A2 03C8                    add ecx, eax
:0040A0A4 038D50FFFFFF            add ecx, dword ptr [ebp+FFFFFF50]-->此地址为USER的
                                                              最后4个(一般为20202020).
:0040A0AA 69F631750000            imul esi, 00007531------>应为IMUL ESI,ESI,7531
:0040A0B0 69C931750000            imul ecx, 00007531------>应为IMUL ECX,ECX,7531
                                                          只取低32位.

* Possible StringData Ref from Data Obj ->"BIN_OR_TEXT"
                                  |
:0040A0B6 C704240C434600          mov dword ptr [esp], 0046430C
:0040A0BD 68B5000000              push 000000B5
:0040A0C2 53                      push ebx
:0040A0C3 2BF1                    sub esi, ecx-------------->得最后的运算值.

* Reference To: KERNEL32.FindResourceA, Ord:00A3h
                                  |
:0040A0C5 FF1534224500            Call dword ptr [00452234]
:0040A0CB 50                      push eax
:0040A0CC 53                      push ebx

* Reference To: KERNEL32.LoadResource, Ord:01C7h
                                  |
:0040A0CD FF153C224500            Call dword ptr [0045223C]

* Possible StringData Ref from Data Obj ->"Register"
                                  |
:0040A0D3 6894484600              push 00464894
:0040A0D8 57                      push edi
:0040A0D9 8945EC                  mov dword ptr [ebp-14], eax
:0040A0DC E8EDD20000              call 004173CE---->此CALL读READBOOK.INI中注册码(经过
                                              变换后的码),放在EAX中.

* Possible StringData Ref from Data Obj ->"RegisterEncryptMode"
                                  |
:0040A0E1 6880484600              push 00464880
:0040A0E6 57                      push edi
:0040A0E7 8945F8                  mov dword ptr [ebp-08], eax
:0040A0EA C745F012320000          mov [ebp-10], 00003212
:0040A0F1 C745E434120000          mov [ebp-1C], 00001234
:0040A0F8 C745E888880000          mov [ebp-18], 00008888
:0040A0FF C745F423230000          mov [ebp-0C], 00002323
:0040A106 E8C3D20000              call 004173CE
:0040A10B 83C410                  add esp, 00000010
:0040A10E 85C0                    test eax, eax
:0040A110 7524                    jne 0040A136
:0040A112 8D45F4                  lea eax, dword ptr [ebp-0C]
:0040A115 50                      push eax
:0040A116 8D45E8                  lea eax, dword ptr [ebp-18]
:0040A119 50                      push eax
:0040A11A 8D45E4                  lea eax, dword ptr [ebp-1C]
:0040A11D 50                      push eax
:0040A11E 8D45F0                  lea eax, dword ptr [ebp-10]
:0040A121 50                      push eax

* Possible StringData Ref from Data Obj ->"C:\"
                                  |
:0040A122 6860474600              push 00464760

* Reference To: KERNEL32.GetDiskFreeSpaceA, Ord:0100h
                                  |
:0040A127 FF15F8214500            Call dword ptr [004521F8]--->注意此CALL,它调用C盘的
                                      磁盘空间(此空间不知怎么取的? 似与真的不相符).
:0040A12D 8B45F4                  mov eax, dword ptr [ebp-0C]-->取出的第1个值.
:0040A130 0FAF45F0                imul eax, dword ptr [ebp-10]->与第2个值相乘(我的为40)
:0040A134 EB19                    jmp 0040A14F

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A110(C)
|
:0040A136 8D45C4                  lea eax, dword ptr [ebp-3C]
:0040A139 C745C420000000          mov [ebp-3C], 00000020
:0040A140 50                      push eax

* Reference To: KERNEL32.GlobalMemoryStatus, Ord:018Dh
                                  |
:0040A141 FF15F0214500            Call dword ptr [004521F0]
:0040A147 8B45D0                  mov eax, dword ptr [ebp-30]
:0040A14A 05CCEDFFFF              add eax, FFFFEDCC

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A134(U)
|
:0040A14F F7D0                    not eax  --------------------->相乘后的积取反.
:0040A151 3145F8                  xor dword ptr [ebp-08], eax -->[EBP-08]里放的为READ
                                            BOOK.INI中的变换后的注册码.
:0040A154 33C0                    xor eax, eax
:0040A156 A3FC644600              mov dword ptr [004664FC], eax

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A176(C)
|
:0040A15B 3975F8                  cmp dword ptr [ebp-08], esi--->ESI中为我们注册名运算
                                                                后得到的值. 
:0040A15E 741D                    je 0040A17D---->就是上面的两个值要等,要不就GAMEOVER了.
:0040A160 8B55EC                  mov edx, dword ptr [ebp-14]
:0040A163 8BC8                    mov ecx, eax
:0040A165 83E17F                  and ecx, 0000007F
:0040A168 03348A                  add esi, dword ptr [edx+4*ecx]
:0040A16B 40                      inc eax
:0040A16C 3DFF0F0000              cmp eax, 00000FFF
:0040A171 A3FC644600              mov dword ptr [004664FC], eax
:0040A176 72E3                    jb 0040A15B
:0040A178 3975F8                  cmp dword ptr [ebp-08], esi
:0040A17B 7547                    jne 0040A1C4

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040A15E(C)
|
:0040A17D 8B75FC                  mov esi, dword ptr [ebp-04]
:0040A180 C705A4974B0001000000    mov dword ptr [004B97A4], 00000001-->此为注册标志.
:0040A18A FF761C                  push [esi+1C]

* Reference To: USER32.GetMenu, Ord:011Ch
                                  |
:0040A18D FF1598254500            Call dword ptr [00452598]
:0040A193 50                      push eax
:0040A194 E881270300              call 0043C91A
:0040A199 53                      push ebx

上面的代码比较简单,校验过程过表述如下:
  1.从READBOOK.INI中读出注册名(例如: sender)
    程序在内存中补足16个: 73 65 6E 64 65 72 00 20 20 20 20 20 20 20 20 20
                          ~~~~~~~~~~~~~~~~~
                        (s  e  n  d  e  r)
    算法: 20007265+20202020+20202020=A
          A=A*0x7315
          B=646E6573*0x7315,两值都取低32位.
          B=B-A 注册名运算后的值.
  2.读取磁盘空间.
    在40A12D处移入EAX中的值假如为D.则D=D*0x40
    经查API函数GETDISKFREESPACEA为磁盘剩余空间的函数.返加堆栈[EBP-C]中为C盘总的簇数?
    [EBP-10](即0X40)中为每簇的扇区数? 但顺序好像不对,请高手指点一下.
    将所得的积取反: E=NOT D
  3.比较.
    P=E X0R C(由READBOOK.INI中读出的注册码的16进制值).
    由第1步中运算所得的B是否等于P? 相等就通过注册校验.
  4.问题:
    由于以前看到论坛上不知哪位大虾说同名下有很多注册码,可是依此处的校验法来看,好像不太
可能,还有就是GETDISKFREESPACEA函数,由上面的代码来看,传递给它的参数: C:\,3212,1234,
8888,2323是读取某一扇区上值还是读取的其它? 再看了一下作者的注册方式,好像不是用的硬盘空
间,那就应该读的是写入某一扇区的上固定值.另外这个函数只能在2GB的分区的空间下用,如果
超过2G,只能用GETDISKFREESPACEEX,我查了一下它的引入函数表,好像没有.不知哪位大虾能解释
一下? 多谢了.