软件: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,我查了一下它的引入函数表,好像没有.不知哪位大虾能解释
一下? 多谢了.