• 标 题:书香门第 V1.30 Build 1732 算法分析 + 无注册机 (18千字)
  • 作 者:RoBa
  • 时 间:2003-10-03 14:22:56
  • 链 接:http://bbs.pediy.com

书香门第 V1.30 Build 1732 

软件大小:  720 KB
软件语言:  简体中文
软件类别:  国产软件 / 共享版 / 电子阅读
应用平台:  Win9x/NT/2000/XP
界面预览:  
加入时间:  2003-09-30 09:47:24
下载次数:  12748
推荐等级:  ***

联 系 人:  gentlebreeze@vip.163.com  
开 发 商:  http://www.gentle-breeze.com/

软件介绍:
      《书香门第》是一款适合于真正读书迷的电子小说、文本阅读软件,它外表并不花哨,但对于长时间、大量阅读的读书迷,却最舒适、体贴、细致,因为它具有十二个鲜明特点:1. 多达27种各种质感的窗口背景、页面背景可供选择,总共超过700种背景组合,为读书迷提供最高舒适度和最大程度的视力保护。2. 强大、智能化的自动排版功能,并可以随意设定字体大小、颜色、行距、标题行。3. 极其高速的排版速度:目前主流机器上排版速度超过一万页/秒,所以通常你根本无法感觉到排版过程。
4. 高速的DirectDraw图形引擎,翻页寻迹流畅自如。5.附带的html转换、合成工具能够迅速依次将一批html文件转换且合并为一个大的文本文件,方便阅读。6.宽广的平台适用性:从486/win95到最新P4/XP都能从容应对。7.体贴的左手键操作,使你从此摆脱长期右手操作鼠标、键盘带来的疲劳。8.与页面字数成正比的自动翻页间隔,自然优于呆板的固定翻页间隔。9.可以选择使用窗口模式(寻迹方便)或全屏幕模式(阅读效果更好)。10.全书遍历/测试功能,保护你的计算机,节约能源。11.搜索功能方便读者在书中查找。12. 具有强于word和IE的汉字乱码纠错功能。

下载地址: http://www.skycn.com/soft/9090.html
 
输入一个EMAIL和一个注册码(必须是24位,见下),用常规方法很容易找到这里:

:00403A3B 6A20                    push 00000020
:00403A3D 57                      push edi      <--输入的EMAIL
:00403A3E 8BCD                    mov ecxebp
:00403A40 E881770100              call 0041B1C6 <--得到长度
:00403A45 8D9E00010000            lea ebxdword ptr [esi+00000100]
:00403A4B 6A20                    push 00000020
:00403A4D 68202C4500              push 00452C20 <--假码
:00403A52 8BCB                    mov ecxebx
:00403A54 A300204500              mov dword ptr [00452000], eax <--先把EMAIL长度存起来
:00403A59 E868770100              call 0041B1C6 <--得到长度
:00403A5E 83F818                  cmp eax, 00000018
:00403A61 0F85C0000000            jne 00403B27  <--长度必须为18h
:00403A67 A100204500              mov eaxdword ptr [00452000] <--读出EMAIL长度
:00403A6C 83F804                  cmp eax, 00000004
:00403A6F 0F8CB2000000            jl 00403B27   <--EMAIL长度不小于4
:00403A75 8364241000              and dword ptr [esp+10], 00000000
:00403A7A EB05                    jmp 00403A81

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A9F(C)
|
:00403A7C A100204500              mov eaxdword ptr [00452000]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403A7A(U)
|
:00403A81 50                      push eax
:00403A82 0FAF442414              imul eaxdword ptr [esp+14]
:00403A87 05402C4500              add eax, 00452C40
:00403A8C 57                      push edi
:00403A8D 50                      push eax
:00403A8E E8BD570000              call 00409250 <--把[EDI]处的内存写入[eax]
:00403A93 83C40C                  add esp, 0000000C
:00403A96 FF442410                inc [esp+10]
:00403A9A 837C241040              cmp dword ptr [esp+10], 00000040
:00403A9F 7CDB                    jl 00403A7C <--把EMAIL重写40次??作者在和我兜圈子?
:00403AA1 BF20244500              mov edi, 00452420

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403ABF(C)
|
:00403AA6 6A20                    push 00000020
:00403AA8 68202C4500              push 00452C20
:00403AAD 57                      push edi
:00403AAE E89D570000              call 00409250
:00403AB3 83C720                  add edi, 00000020
:00403AB6 83C40C                  add esp, 0000000C
:00403AB9 81FF202C4500            cmp edi, 00452C20
:00403ABF 7CE5                    jl 00403AA6 <--又把假码重写40次 *_*
:00403AC1 33FF                    xor ediedi
:00403AC3 57                      push edi
:00403AC4 57                      push edi
:00403AC5 6801150000              push 00001501
:00403ACA FF761C                  push [esi+1C]

* Reference To: USER32.SendMessageA, Ord:0214h
                                  |
:00403ACD FF15F0544200            Call dword ptr [004254F0] 
:00403AD3 80BEC000000000          cmp byte ptr [esi+000000C0], 00 <--重要标志
:00403ADA 742F                    je 00403B0B <--这里修改为JNE就成功了

* Possible StringData Ref from Data Obj ->"     ---------  祝贺你!  ---------- "
                                        ->"    

你已经成为了《书香门第》注册用户!"
                                  |
:00403ADC 6828D74200              push 0042D728
:00403AE1 893DC83E4500            mov dword ptr [00453EC8], edi
:00403AE7 E8AC220000              call 00405D98

看上去似乎没什么时候难的,很经典的判断,一个CALL,然后CMP,JE,可是跟进CALL一看,却是系统的USER32.DLL,
百思不得其解,其它地方也找不到什么判断.怎么办呢??考虑N分钟后决定用BPM试一下.不是比较[ESI+C0]处是否为0吗,如果判断注册的话肯定要向这里写上0或者其它什么东西.我们就看看程序什么时候在这里写了东西.

下指令: BPM ESI+C0 中断在下面:

:00403B4D 817C240401150000        cmp dword ptr [esp+04], 00001501
:00403B55 56                      push esi
:00403B56 8BF1                    mov esiecx
:00403B58 750B                    jne 00403B65
:00403B5A E81D000000              call 00403B7C <--很明显是关键的CALL
:00403B5F 8886C0000000            mov byte ptr [esi+000000C0], al <--呵呵,中断在这里

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403B58(C)
|
:00403B65 FF742410                push [esp+10]
:00403B69 8BCE                    mov ecxesi
:00403B6B FF742410                push [esp+10]
:00403B6F FF742410                push [esp+10]
:00403B73 E8B7540100              call 0041902F
:00403B78 5E                      pop esi
:00403B79 C20C00                  ret 000C 

跟进403B5A处的关键CALL:

* Referenced by a CALL at Addresses:
|:004017E2   , :00402135   , :004030B9   , :00403B5A   , :00404DA0   
|
:00403B7C 55                      push ebp
:00403B7D 8BEC                    mov ebpesp
:00403B7F 81EC00010000            sub esp, 00000100
:00403B85 56                      push esi
:00403B86 6A20                    push 00000020
:00403B88 E8DE5B0000              call 0040976B
:00403B8D 6A40                    push 00000040
:00403B8F BE20234500              mov esi, 00452320
:00403B94 99                      cdq
:00403B95 59                      pop ecx
:00403B96 F7F9                    idiv ecx
:00403B98 C1E205                  shl edx, 05
:00403B9B 81C220244500            add edx, 00452420
:00403BA1 52                      push edx
:00403BA2 56                      push esi
:00403BA3 E8A8560000              call 00409250
:00403BA8 68FF000000              push 000000FF
:00403BAD 8D8500FFFFFF            lea eaxdword ptr [ebp+FFFFFF00]
:00403BB3 6A00                    push 00000000
:00403BB5 50                      push eax
:00403BB6 E8555A0000              call 00409610
:00403BBB 83C418                  add esp, 00000018
:00403BBE FF3500204500            push dword ptr [00452000]
:00403BC4 E8A25B0000              call 0040976B
:00403BC9 6A40                    push 00000040
:00403BCB 99                      cdq
:00403BCC 59                      pop ecx
:00403BCD F7F9                    idiv ecx
:00403BCF 8D8500FFFFFF            lea eaxdword ptr [ebp+FFFFFF00]
:00403BD5 0FAF1500204500          imul edxdword ptr [00452000]
:00403BDC 81C2402C4500            add edx, 00452C40
:00403BE2 52                      push edx
:00403BE3 50                      push eax
:00403BE4 E867560000              call 00409250
:00403BE9 6A0C                    push 0000000C
:00403BEB 56                      push esi
:00403BEC 68A0224500              push 004522A0
:00403BF1 E85A560000              call 00409250
:00403BF6 6A0C                    push 0000000C
:00403BF8 682C234500              push 0045232C
:00403BFD 6820224500              push 00452220
:00403C02 E849560000              call 00409250
:00403C07 A100204500              mov eaxdword ptr [00452000]
:00403C0C 80252C22450000          and byte ptr [0045222C], 00
:00403C13 8025AC22450000          and byte ptr [004522AC], 00
:00403C1A 83C424                  add esp, 00000024
:00403C1D 33D2                    xor edxedx
:00403C1F 85C0                    test eaxeax
:00403C21 7E2E                    jle 00403C51
:00403C23 53                      push ebx
:00403C24 57                      push edi
:00403C25 8D58FF                  lea ebxdword ptr [eax-01]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C4D(C)
|
:00403C28 8DBC1500FFFFFF          lea edidword ptr [ebp+edx-00000100]
:00403C2F 8A0F                    mov clbyte ptr [edi] <-依次取EMAIL的字符
:00403C31 80F940                  cmp cl, 40 
:00403C34 7405                    je 00403C3B <--是否为'@'
:00403C36 80F92E                  cmp cl, 2E
:00403C39 750F                    jne 00403C4A<--是否为'.'

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C34(C)
|
:00403C3B 3BD3                    cmp edxebx
:00403C3D 7D09                    jge 00403C48
:00403C3F 8BCB                    mov ecxebx
:00403C41 8D7701                  lea esidword ptr [edi+01]
:00403C44 2BCA                    sub ecxedx
:00403C46 F3                      repz
:00403C47 A4                      movsb

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C3D(C)
|
:00403C48 48                      dec eax
:00403C49 4B                      dec ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C39(C)
|
:00403C4A 42                      inc edx
:00403C4B 3BD0                    cmp edxeax
:00403C4D 7CD9                    jl 00403C28 <--上面的一段是对EMAIL的处理,去掉@,在后面补齐等
:00403C4F 5F                      pop edi
:00403C50 5B                      pop ebx

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C21(C)
|
:00403C51 83F80C                  cmp eax, 0000000C
:00403C54 5E                      pop esi
:00403C55 7D18                    jge 00403C6F
:00403C57 6A0C                    push 0000000C
:00403C59 59                      pop ecx
:00403C5A 2BC8                    sub ecxeax
:00403C5C 8D840500FFFFFF          lea eaxdword ptr [ebp+eax-00000100]
:00403C63 51                      push ecx
:00403C64 6A30                    push 00000030
:00403C66 50                      push eax
:00403C67 E8A4590000              call 00409610
:00403C6C 83C40C                  add esp, 0000000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403C55(C)
|
:00403C6F 80A50CFFFFFF00          and byte ptr [ebp+FFFFFF0C], 00
:00403C76 E847000000              call 00403CC2 <--关键的CALL
:00403C7B 6A0C                    push 0000000C
:00403C7D 8D8500FFFFFF            lea eaxdword ptr [ebp+FFFFFF00]
:00403C83 68A0234500              push 004523A0
:00403C88 50                      push eax
:00403C89 E8D2600000              call 00409D60 <--这里就是比较了
:00403C8E 83C40C                  add esp, 0000000C
:00403C91 85C0                    test eaxeax
:00403C93 751B                    jne 00403CB0
:00403C95 2005FB1C4500            and byte ptr [00451CFB], al
:00403C9B 2005FA1C4500            and byte ptr [00451CFA], al
:00403CA1 2005F91C4500            and byte ptr [00451CF9], al
:00403CA7 2005F81C4500            and byte ptr [00451CF8], al
:00403CAD 40                      inc eax
:00403CAE C9                      leave
:00403CAF C3                      ret

进入403C89处的CALL:

* Referenced by a CALL at Addresses:
|:00403C76   , :004044A5   
|
:00403CC2 6A0C                    push 0000000C
:00403CC4 E802000000              call 00403CCB <--进入
:00403CC9 59                      pop ecx
:00403CCA C3                      ret

* Referenced by a CALL at Address:
|:00403CC4   
|
:00403CCB 56                      push esi
:00403CCC 8B742408                mov esidword ptr [esp+08]
:00403CD0 33C9                    xor ecxecx
:00403CD2 57                      push edi
:00403CD3 85F6                    test esiesi
:00403CD5 7E20                    jle 00403CF7

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403CF5(C)  <--第一处循环计算
|
:00403CD7 8D0431                  lea eaxdword ptr [ecx+esi]
:00403CDA 6A09                    push 00000009
:00403CDC 99                      cdq
:00403CDD 5F                      pop edi
:00403CDE F7FF                    idiv edi
:00403CE0 B008                    mov al, 08
:00403CE2 2AC2                    sub aldl
:00403CE4 88144D20234500          mov byte ptr [2*ecx+00452320], dl
:00403CEB 88044D21234500          mov byte ptr [2*ecx+00452321], al
:00403CF2 41                      inc ecx
:00403CF3 3BCE                    cmp ecxesi
:00403CF5 7CE0                    jl 00403CD7 <--上面的计算挺热闹,但结果都是常数,所以只要知道结果就行了 :)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403CD5(C)
|
:00403CF7 8024752023450000        and byte ptr [2*esi+00452320], 00
:00403CFF 53                      push ebx
:00403D00 55                      push ebp
:00403D01 8DBE20234500            lea edidword ptr [esi+00452320]
:00403D07 56                      push esi
:00403D08 BD20214500              mov ebp, 00452120
:00403D0D 57                      push edi
:00403D0E 55                      push ebp
:00403D0F E83C550000              call 00409250
:00403D14 BB20234500              mov ebx, 00452320
:00403D19 56                      push esi
:00403D1A 53                      push ebx
:00403D1B 57                      push edi
:00403D1C E82F550000              call 00409250
:00403D21 56                      push esi
:00403D22 55                      push ebp
:00403D23 53                      push ebx
:00403D24 E827550000              call 00409250 <--频繁调用这个CALL(上面提到过),目的是把上面的计算结果前半段和后半段对调一下
:00403D29 83C424                  add esp, 00000024
:00403D2C 33DB                    xor ebxebx
:00403D2E 85F6                    test esiesi
:00403D30 7E51                    jle 00403D83

计算至此后内存中的情况:[00452320]
__________________________________________________________________

016F:00452320    00 08 01 07 02 06 03 05-04 04 05 03 03 05 04 04
016F:00452330    05 03 06 02 07 01 08 00-00 00 00 00 00 00 00 00
__________________________________________________________________

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D81(C) <--第二处循环计算
|
:00403D32 8AC3                    mov albl
:00403D34 8A8BA0224500            mov clbyte ptr [ebx+004522A0] <-依次取出假码前半段的字符ch1
:00403D3A FEC0                    inc al
:00403D3C 8A9320224500            mov dlbyte ptr [ebx+00452220] <-依次取出假码后半段的字符ch2
:00403D42 F6EB                    imul bl <-ch1=ch1*循环变量N (由0递增)
:00403D44 8D3C1B                  lea edidword ptr [ebx+ebx]
:00403D47 FEC0                    inc al
:00403D49 240F                    and al, 0F
:00403D4B 2A8F20234500            sub clbyte ptr [edi+00452320]<-ch1=ch1-从[452320]处依次取的值
:00403D51 2A9721234500            sub dlbyte ptr [edi+00452321]<-ch2=ch2-从[452320]处仿效取的值
:00403D57 A218214500              mov byte ptr [00452118], al
:00403D5C 80E941                  sub cl, 41 <-ch1=ch1-41
:00403D5F 80EA41                  sub dl, 41 <-ch2=ch2-41
:00403D62 32C8                    xor clal <-ch1=ch1 xor 循环变量N
:00403D64 32D0                    xor dlal <-ch2=ch2 xor 循环变量N
:00403D66 888BA0224500            mov byte ptr [ebx+004522A0], cl
:00403D6C 889320224500            mov byte ptr [ebx+00452220], dl <-把结果写在[4522A0]
:00403D72 43                      inc ebx
:00403D73 888F20214500            mov byte ptr [edi+00452120], cl
:00403D79 3BDE                    cmp ebxesi
:00403D7B 889721214500            mov byte ptr [edi+00452121], dl <-再写在[452120]
:00403D81 7CAF                    jl 00403D32

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403D30(C)
|
:00403D83 56                      push esi
:00403D84 55                      push ebp
:00403D85 6820224500              push 00452220
:00403D8A E8C1540000              call 00409250
:00403D8F 8DBE20214500            lea edidword ptr [esi+00452120]
:00403D95 56                      push esi
:00403D96 BBA0224500              mov ebx, 004522A0
:00403D9B 57                      push edi
:00403D9C 53                      push ebx
:00403D9D E8AE540000              call 00409250
:00403DA2 56                      push esi
:00403DA3 53                      push ebx
:00403DA4 55                      push ebp
:00403DA5 E8A6540000              call 00409250
:00403DAA 56                      push esi
:00403DAB 6820224500              push 00452220
:00403DB0 57                      push edi
:00403DB1 E89A540000              call 00409250 <--又是同样的方法把前半段ch1和后半段ch2再调换
:00403DB6 83C430                  add esp, 00000030
:00403DB9 33C0                    xor eaxeax
:00403DBB 85F6                    test esiesi
:00403DBD 5D                      pop ebp
:00403DBE 5B                      pop ebx
:00403DBF 7E1C                    jle 00403DDD

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403DDB(C) <--第三处循环计算
|
:00403DC1 8A0C4521214500          mov clbyte ptr [2*eax+00452121] <--从[452120]处每次取两个值
:00403DC8 C0E104                  shl cl, 04                        即第二次计算的结果,把后一值
:00403DCB 0A0C4520214500          or clbyte ptr [2*eax+00452120]  左移四位后与前值进行OR运算,
:00403DD2 40                      inc eax                           结果写在[4523A0]
:00403DD3 3BC6                    cmp eaxesi
:00403DD5 88889F234500            mov byte ptr [eax+0045239F], cl
:00403DDB 7CE4                    jl 00403DC1

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403DBF(C)
|
:00403DDD 80A6A023450000          and byte ptr [esi+004523A0], 00
:00403DE4 5F                      pop edi
:00403DE5 5E                      pop esi
:00403DE6 C3                      ret

进行比较的那个CALL我就不写了(因为这篇文章太长了),但它好像只比较前四位,也就是说只要你的EMAIL前四位与[4523A0]处的结果一致就可以.可我随意填的假码经反算后根本不是可显示字符,要想写出注册机必须把算法逆回去,我想了好半天也不知道这个算法怎样逆运算,看着清清楚楚的代码就是写不出注册机,痛苦中.....

哪位大哥帮我分析一下,我的数学太烂了...

标 题:终于把注册机写出来了,现在破一个软件不写注册机的话很不爽..... (2千字)
发信人:RoBa
时 间:2003-10-09 13:02:30
详细信息:

程序判断注册的思路:

1.先将EMAIL中的'@','.'字符去掉,如果小于12个字符就在后面补'0'.然后把前六位和后六位颠倒过来.

2.取注册码(24位)按下表计算: (假设输入的是ABCDEFGHIJKLMNOPQRSTUVWX)

+----+---+---+---+---+---+---+---+---+---+---+---+---+
|假码| A | B | C | D | E | F | G | H | I | J | K | L |
|Num | 0 | 1 | 2 | 3 | 4 | 5 | 3 | 4 | 5 | 6 | 7 | 8 |
+----+---+---+---+---+---+---+---+---+---+---+---+---+
|假码| M | N | O | P | Q | R | S | T | U | V | W | X |
|Num | 8 | 7 | 6 | 5 | 4 | 3 | 5 | 4 | 3 | 2 | 1 | 0 |
+----+---+---+---+---+---+---+---+---+---+---+---+---+
|Nxor| 1 | 3 | 7 | D | 5 | F | B | 9 | 9 | B | F | 5 |
+----+---+---+---+---+---+---+---+---+---+---+---+---+

其中第N列的Nxor值计算方法是((N-1)*N+1) mod 10h

判断时将每列上一格里的(注册码-Num-41h) xor 该格对应列的Nxor值,记结果为S1,用同样方法算出该列下一格的值S2,计算(S2 SHR 4) OR S1. 12列的结果组成的字串如果和EMAIL经处理后的字串一致就成功.

因为程序将注册码反算,所以注册机要求它的逆运算.逆运算的关键是如何把EMAIL中的一个值拆分成S1和S2,因为这个逆运算产生的结果不惟一,但要保证计算出的注册码是可显示字符.不妨把一个两位的十六进制值拆成高位和低位.如字母'R'=52h,可拆成S1=2,S2=5,这样计算出来的注册码在'A'-'X'之间,完全符合要求.

注册机: (Borland Pascal 7.0)

Program CrackZbook;
var fmail,mail,code,temp:string;
    p,p1,s1,s2,s :integer;
    Num:array[1..24] of integer;
    Nxor:array[1..12] of integer;
begin
     Num[1]:=0; Num[2]:=1; Num[3]:=2; Num[4]:=3;
     Num[5]:=4; Num[6]:=5; Num[7]:=3; Num[8]:=4;
     Num[9]:=5; Num[10]:=6; Num[11]:=7; Num[12]:=8;
     Num[13]:=8; Num[14]:=7; Num[15]:=6; Num[16]:=5;
     Num[17]:=4; Num[18]:=3; Num[19]:=5; Num[20]:=4;
     Num[21]:=3; Num[22]:=2; Num[23]:=1; Num[24]:=0;
     Nxor[1]:=1;Nxor[2]:=3;Nxor[3]:=7;Nxor[4]:=13;
     Nxor[5]:=5;Nxor[6]:=15;Nxor[7]:=11;Nxor[8]:=9;
     Nxor[9]:=9;Nxor[10]:=11;Nxor[11]:=15;Nxor[12]:=5; //初始化计算表
     p1:=1;
     repeat
           write('Please input your Email:');
           readln(fmail);
     until length(fmail)>=4;
     for p:=1 to length(fmail) do
     if (fmail[p]<>'.') and (fmail[p]<>'@') then
     begin
          mail[p1]:=fmail[p];
          inc(p1);
     end;
     for p:=p1 to 12 do mail[p]:='0';
     for p:=1 to 6 do temp[p]:=mail[p];
     for p:=7 to 12 do mail[p-6]:=mail[p];
     for p:=7 to 12 do mail[p]:=temp[p-6];  //对EMAIL的处理
     for p:=1 to 12 do
     begin
          s:=ord(mail[p]);
          s1:=s mod 16;
          s2:=s div 16;
          s1:=s1 xor Nxor[p];
          s2:=s2 xor Nxor[p];
          s1:=s1+$41+Num[p];
          s2:=s2+$41+Num[p+12];
          code[p]:=chr(s1);
          code[p+12]:=chr(s2);
     end;
     for p:=1 to 24 do write(code[p]);
     writeln;
     writeln('Crack by RoBa     Thank you');
end.

一个可用的注册码:

EMAIL: RoBa
CODE : BEJQJUMKQQWNKHKTKPTTQPNG