• 标 题:星光之夜 -- Starry Night 共享版算法分析
  • 作 者:lianzi2000
  • 时 间:2003/07/27 03:24pm
  • 链 接:http://bbs.pediy.com

【破解声明】本文纯系技术性讨论,任何人因使用本文信息造成的一切后果,作者概不负责。

【软件名称】Starry Night Digital Download v4.05-- 星光之夜电子下载最新版

【软件简介】这是一款美丽而实用的星图软件, 根据实时天文资料计算并显示指定时间的星空景象,
           甚至包括人造卫星的位置和运动情况! 自动识别所有星座, 视野达到20,000光年。包含
           约35,000 颗各类星球及170多个深层空间物体,如星系、星云和星团等的详细资料。在
           功能上相当于Backyard版,可以制作自己的电影和星际图片,并可从livesky.com 下载
           最新的天文资料。但为了减小体积,便于下载,省略了很多星球的资料。可以用backyard
           版本的updater进行升级,配备完整的.pdf使用手册,是广大天文爱好者的必备工具。

【软件大小】56.2MB

【下载地址】www.starrynight.com

【应用平台】Windows 98/ME/2000/XP

【软件限制】15天时间限制。在网上登记下载时,会要求填写email 地址,随后就会给你发送一个试用
           注册码,可免费使用15天。
           
【破解工具】OllyDbg 1.09d

【分析过程】用PEid和FI3.01均显示没有壳,但不能确定是何种语言写成。如果注册码失败,会有消息框
           显示失败信息,如成功则进入主界面。试用注册码的形式是:yt4-383b-7669-71c1-5824,
           所以试炼码设置为yr1-2345-6789-abcd-ef00.用OD载入后,现直接运行,利用临时注册码
           进入主界面,然后下CreateWindowExA断点,再从help菜单中选择软件注册。在显示注册对话
           框的时候会被OD拦住,记下编辑框控件的句柄。输入试炼码后,回OD下GetWindowsTextA断点,
           但没能拦住(这年头,用这种方法来获得输入的东东好像不多了)。重新来过,这次在我们的
           老朋友CallWindowProc函数上下条件断点([esp+8]==编辑框句柄) && ([esp+C]==WM_GETTEXT),
           拦截成功,记下存放输入的内存地址,待函数返回后,在该处下内存断点,然后运行程序直至
           访问输入的信息,便来到以下代码:

入口处:

Arg1 = 00000002
Arg2 = 00C4BB78 ASCII "yr1-2345-6789-abcd-ef00"
Arg3 = 00C4BC78 ASCII "lianzi2000"
Arg4 = 00CB97F8
Arg5 = 00CB97FC
Arg6 = 00000000
Arg7 = 00000079
Arg8 = 00000034
................................................

005B330F  |> 8B4D 0C        /MOV ECX,DWORD PTR SS:[EBP+C]        ****试炼码
005B3312  |. 0FBE0431       |MOVSX EAX,BYTE PTR DS:[ECX+ESI]     ****esi是索引
005B3316  |. 8945 8C        |MOV DWORD PTR SS:[EBP-74],EAX       ****取一个字符放入暂存处
005B3319  |. B0 01          |MOV AL,1
005B331B  |. 837D 8C 00     |CMP DWORD PTR SS:[EBP-74],0
005B331F  |. 7C 0B          |JL SHORT starryni.005B332C
005B3321  |. 817D 8C 000100>|CMP DWORD PTR SS:[EBP-74],100       ****看是否在0-0x100范围内
005B3328  |. 7D 02          |JGE SHORT starryni.005B332C
005B332A  |. 30C0           |XOR AL,AL
005B332C  |> 84C0           |TEST AL,AL
005B332E  |. 74 04          |JE SHORT starryni.005B3334
005B3330  |. 31C0           |XOR EAX,EAX
005B3332  |. EB 1B          |JMP SHORT starryni.005B334F
005B3334  |> 6A 01          |PUSH 1
005B3336  |. E8 D5690800    |CALL starryni.00639D10              ****tls相关
005B333B  |. 59             |POP ECX
005B333C  |. 8B90 BC010000  |MOV EDX,DWORD PTR DS:[EAX+1BC]        
005B3342  |. 8B5A 08        |MOV EBX,DWORD PTR DS:[EDX+8]        ****ebx 是个字符类型表
005B3345  |. 8B45 8C        |MOV EAX,DWORD PTR SS:[EBP-74]       ****暂存处的字符
005B3348  |. 0FB70443       |MOVZX EAX,WORD PTR DS:[EBX+EAX*2]
005B334C  |. 83E0 09        |AND EAX,9                           ****如果字母或数字,
005B334F  |> 85C0           |TEST EAX,EAX                        ****EAX就不会为0
005B3351  |. 75 09          |JNZ SHORT starryni.005B335C
005B3353  |. 8B45 0C        |MOV EAX,DWORD PTR SS:[EBP+C]
005B3356  |. 803C30 2D      |CMP BYTE PTR DS:[EAX+ESI],2D        ****如果是特殊符号,就检查是否连字号
005B335A  |. 75 17          |JNZ SHORT starryni.005B3373         ****别的字符一概忽略
005B335C  |> 8B45 0C        |MOV EAX,DWORD PTR SS:[EBP+C]
005B335F  |. 0FB61430       |MOVZX EDX,BYTE PTR DS:[EAX+ESI]
005B3363  |. 8B45 90        |MOV EAX,DWORD PTR SS:[EBP-70]
005B3366  |. 885405 9C      |MOV BYTE PTR SS:[EBP+EAX-64],DL
005B336A  |. FF45 90        |INC DWORD PTR SS:[EBP-70]           ****[ebp-70] 是长度计数
005B336D  |. 837D 90 17     |CMP DWORD PTR SS:[EBP-70],17        ****这里表明正确的长度应该是0x17
005B3371  |. 7D 16          |JGE SHORT starryni.005B3389
005B3373  |> 46             |INC ESI
005B3374  |> 8B7D 0C         MOV EDI,DWORD PTR SS:[EBP+C]
005B3377  |. 31C0           |XOR EAX,EAX
005B3379  |. 83C9 FF        |OR ECX,FFFFFFFF
005B337C  |. F2:AE          |REPNE SCAS BYTE PTR ES:[EDI]
005B337E  |. BA FEFFFFFF    |MOV EDX,-2
005B3383  |. 29CA           |SUB EDX,ECX
005B3385  |. 39D6           |CMP ESI,EDX
005B3387  |.^72 86          \JB SHORT starryni.005B330F

以上代码整理输入的注册码,忽略除数字和字母以及连字号之外的一切字符。

005B3389  |> C645 B3 00     MOV BYTE PTR SS:[EBP-4D],0          
005B338D  |. 8D45 9C        LEA EAX,DWORD PTR SS:[EBP-64]        ****整理后的注册码
005B3390  |. 50             PUSH EAX
005B3391  |. FF75 0C        PUSH DWORD PTR SS:[EBP+C]            
005B3394  |. E8 373D0800    CALL starryni.006370D0               ****拷贝覆盖原注册码
005B3399  |. 59             POP ECX
005B339A  |. 59             POP ECX
005B339B  |. FF75 0C        PUSH DWORD PTR SS:[EBP+C]            ****注册码
005B339E  |. E8 A1080000    CALL starryni.005B3C44               ****这个函数把注册码中的字母全变成小写
005B33A3  |. 59             POP ECX
005B33A4  |. 8B4D 0C        MOV ECX,DWORD PTR SS:[EBP+C]         ****注册码
005B33A7  |. 0FB641 01      MOVZX EAX,BYTE PTR DS:[ECX+1]        ****取第二个字符
005B33AB  |. 8945 98        MOV DWORD PTR SS:[EBP-68],EAX        ****存入[ebp-68]处
005B33AE  |. 807D 08 01     CMP BYTE PTR SS:[EBP+8],1            
005B33B2  |. 75 04          JNZ SHORT starryni.005B33B8
005B33B4  |. C645 97 00     MOV BYTE PTR SS:[EBP-69],0
005B33B8  |> 807D 98 63     CMP BYTE PTR SS:[EBP-68],63        
005B33BC  |. 75 04          JNZ SHORT starryni.005B33C2
005B33BE  |. C645 97 00     MOV BYTE PTR SS:[EBP-69],0
005B33C2  |> 8B7D 0C        MOV EDI,DWORD PTR SS:[EBP+C]        
005B33C5  |. 31C0           XOR EAX,EAX
005B33C7  |. 83C9 FF        OR ECX,FFFFFFFF
005B33CA  |. F2:AE          REPNE SCAS BYTE PTR ES:[EDI]
005B33CC  |. B8 FEFFFFFF    MOV EAX,-2
005B33D1  |. 29C8           SUB EAX,ECX
005B33D3  |. 83F8 17        CMP EAX,17
005B33D6  |. 73 0B          JNB SHORT starryni.005B33E3        
005B33D8  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B33DB  |. C600 05        MOV BYTE PTR DS:[EAX],5
005B33DE  |. E9 FC010000    JMP starryni.005B35DF

005B33E3  |> 8B7D 0C        MOV EDI,DWORD PTR SS:[EBP+C]         ****注册码
005B33E6  |. 31C0           XOR EAX,EAX
005B33E8  |. 83C9 FF        OR ECX,FFFFFFFF
005B33EB  |. F2:AE          REPNE SCAS BYTE PTR ES:[EDI]
005B33ED  |. B8 FEFFFFFF    MOV EAX,-2
005B33F2  |. 29C8           SUB EAX,ECX
005B33F4  |. 83F8 17        CMP EAX,17                           ****长度检查
005B33F7  |. 76 07          JBE SHORT starryni.005B3400
005B33F9  |. 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]         ****如果大于0x17,则在此截断,只取0x17个字符
005B33FC  |. C640 17 00     MOV BYTE PTR DS:[EAX+17],0
005B3400  |> 8B7D 10        MOV EDI,DWORD PTR SS:[EBP+10]        ****名字
005B3403  |. 31C0           XOR EAX,EAX
005B3405  |. 83C9 FF        OR ECX,FFFFFFFF
005B3408  |. F2:AE          REPNE SCAS BYTE PTR ES:[EDI]         ****长度检查
005B340A  |. B8 FEFFFFFF    MOV EAX,-2
005B340F  |. 29C8           SUB EAX,ECX
005B3411  |. 807D 97 00     CMP BYTE PTR SS:[EBP-69],0
005B3415  |. 74 10          JE SHORT starryni.005B3427
005B3417  |. 83F8 02        CMP EAX,2
005B341A  |. 7D 0B          JGE SHORT starryni.005B3427          
005B341C  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]        ****如果长度小于2就失败
005B341F  |. C600 06        MOV BYTE PTR DS:[EAX],6
005B3422  |. E9 B8010000    JMP starryni.005B35DF
005B3427  |> C645 CC 00     MOV BYTE PTR SS:[EBP-34],0
005B342B  |. 6A 03          PUSH 3                               ****立即数指明子串长度
005B342D  |. FF75 0C        PUSH DWORD PTR SS:[EBP+C]            ****注册码
005B3430  |. 8D45 CC        LEA EAX,DWORD PTR SS:[EBP-34]        ****存放返回字符串的缓冲区
005B3433  |. 50             PUSH EAX
005B3434  |. E8 273D0800    CALL starryni.00637160               ****该函数从一个字符串的左端取子串      
005B3439  |. 83C4 0C        ADD ESP,0C                           ****所以这里取注册码第一部分3个字符的子串
005B343C  |. 6A 04          PUSH 4
005B343E  |. 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]
005B3441  |. 83C0 04        ADD EAX,4
005B3444  |. 50             PUSH EAX
005B3445  |. 8D45 CC        LEA EAX,DWORD PTR SS:[EBP-34]
005B3448  |. 50             PUSH EAX
005B3449  |. E8 123D0800    CALL starryni.00637160               ****第二部分4个字符
005B344E  |. 83C4 0C        ADD ESP,0C
005B3451  |. 6A 04          PUSH 4
005B3453  |. 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]
005B3456  |. 83C0 09        ADD EAX,9
005B3459  |. 50             PUSH EAX
005B345A  |. 8D45 CC        LEA EAX,DWORD PTR SS:[EBP-34]
005B345D  |. 50             PUSH EAX
005B345E  |. E8 FD3C0800    CALL starryni.00637160               ****第三部分4个字符
005B3463  |. 83C4 0C        ADD ESP,0C
005B3466  |. 6A 04          PUSH 4
005B3468  |. 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]
005B346B  |. 83C0 0E        ADD EAX,0E
005B346E  |. 50             PUSH EAX
005B346F  |. 8D45 CC        LEA EAX,DWORD PTR SS:[EBP-34]
005B3472  |. 50             PUSH EAX
005B3473  |. E8 E83C0800    CALL starryni.00637160               ****第4部分4个字符
005B3478  |. 83C4 0C        ADD ESP,0C                              

以上代码把注册码的第1,2,3,4部分连接起来,去掉连字号,形成yr123456789abcd, 在[ebp-34]处。


005B347B  |. 8D45 CF        LEA EAX,DWORD PTR SS:[EBP-31]       ****这里eax指向"23456789abcd"
005B347E  |. 50             PUSH EAX                            
005B347F  |. E8 83010000    CALL starryni.005B3607              ****这个函数根据一个表把上述字符串重新排序

            005B3616  MOV EDI,DWORD PTR SS:[EBP+8]
            005B3619  XOR EAX,EAX
            005B361B  OR ECX,FFFFFFFF
            005B361E  REPNE SCAS BYTE PTR ES:[EDI]
            005B3620  MOV EAX,-2
            005B3625  SUB EAX,ECX
            005B3627  CMP EAX,0C                             ****长度检查:应该有0xC个字符
            005B362A  JE SHORT starryni.005B362E
            005B362C  JMP SHORT starryni.005B3663
            005B362E  XOR ESI,ESI                            ****esi作为索引
            005B3630  JMP SHORT starryni.005B3646
            005B3632  /MOVSX EBX,WORD PTR DS:[ESI*2+729CA8]  ****从位于[729CA8]的表中得到新索引
            005B363A  |MOV EAX,DWORD PTR SS:[EBP+8]          
            005B363D  |MOVZX EDX,BYTE PTR DS:[EAX+EBX]       ****从原字符串中取出新索引对应的字符
            005B3641  |MOV BYTE PTR SS:[EBP+ESI-1C],DL       ****放在临时缓冲区的原索引对应位置
            005B3645  |INC ESI
            005B3646   CMP ESI,0C
            005B3649  \JL SHORT starryni.005B3632
            005B364B  MOV BYTE PTR SS:[EBP-10],0            
            005B364F  MOV EAX,DWORD PTR SS:[EBP+8]          
            005B3652  MOV BYTE PTR DS:[EAX],0                
            005B3655  LEA EAX,DWORD PTR SS:[EBP-1C]          
            005B3658  PUSH EAX
            005B3659  PUSH DWORD PTR SS:[EBP+8]              
            005B365C  CALL starryni.00637130                 ****用重排过的字符串代替原字符串  
           
            [729CA8]表的内容如下:
            0B 00 02 00 06 00 08 00 04 00 07 00 0A 00 01 00 03 00 09 00 00 00 05 00
            所以"23456789abcd"重排后变成"d48a69c35b27"

005B3484  |. 59             POP ECX
005B3485  |. 8D45 CC        LEA EAX,DWORD PTR SS:[EBP-34]     ****字符串现已变成"yr1d48a69c35b27"
005B3488  |. 50             PUSH EAX                          ****作为参数压入堆栈
005B3489  |. E8 CE020000    CALL starryni.005B375C            ****关键call,计算检查和

            005B375C   PUSH EBP
            005B375D   MOV EBP,ESP
            005B375F   PUSH EBX
            005B3760   PUSH ESI
            005B3761   PUSH EDI
            005B3762   SUB ESP,24
            005B3765  >MOV DWORD PTR SS:[EBP-30],-32EB       ****这里有一个常数
            005B376C   PUSH 1E                               ****立即数指明所需字符串的长度
            005B376E   LEA EAX,DWORD PTR SS:[EBP-2C]         ****存放返回结果的缓冲区
            005B3771   PUSH EAX                              
            005B3772   PUSH DWORD PTR SS:[EBP+8]             ****"yr1d48a69c35b27"
            005B3775   CALL starryni.005B37BD                ****这个函数复制并连接字符串直到达到指定长度
            005B377A   ADD ESP,0C
            005B377D   TEST AL,AL                            ****返回非零表示成功
            005B377F   JNZ SHORT starryni.005B3788
            005B3781   MOV EAX,-11CD
            005B3786   JMP SHORT starryni.005B37B5
            005B3788   LEA EDI,DWORD PTR SS:[EBP-2C]         ****已经连接的字符串:
            005B378B   XOR EAX,EAX                           ****"yr1d48a69c35b27yr1d48a69c35b27"
            005B378D   OR ECX,FFFFFFFF
            005B3790   REPNE SCAS BYTE PTR ES:[EDI]
            005B3792   MOV ESI,-2
            005B3797   SUB ESI,ECX                           ****长度0x1E
            005B3799   XOR EBX,EBX                           ****ebx为索引index
            005B379B   JMP SHORT starryni.005B37AE
            005B379D   /MOVZX ECX,BYTE PTR SS:[EBP+EBX-2C]   ****ecx = ch
            005B37A2   |MOV EDX,EBX                          ****edx = index
            005B37A4   |IMUL EDX,ECX                         ****edx = index*ch
            005B37A7   |IMUL EDX,ECX                         ****edx = index*ch*ch = index*ch**2
            005B37AA   |ADD DWORD PTR SS:[EBP-30],EDX        ****结果加到常数-32EB上
            005B37AD   |INC EBX
            005B37AE    CMP EBX,ESI
            005B37B0   \JL SHORT starryni.005B379D
            005B37B2   MOV EAX,DWORD PTR SS:[EBP-30]         ****返回最后结果
            005B37B5   LEA ESP,DWORD PTR SS:[EBP-C]
            005B37B8   POP EDI
            005B37B9   POP ESI
            005B37BA   POP EBX
            005B37BB   POP EBP
            005B37BC   RETN
           
            这个过程的工作是把字符串首尾相连达到30个字符(0x1E),然后计算检查和:
            checksum = sum(index*ch**2)-0x32EB

005B348E  |. 59             POP ECX
005B348F  |. 0FB7C0         MOVZX EAX,AX                      ****抛弃检查和的高位字
005B3492  |. 8D55 C0        LEA EDX,DWORD PTR SS:[EBP-40]
005B3495  |. 52             PUSH EDX
005B3496  |. 0FB7C0         MOVZX EAX,AX
005B3499  |. 50             PUSH EAX
005B349A  |. E8 40040000    CALL starryni.005B38DF            ****这个函数将检查和的低位字转成字符串行式
005B349F  |. 59             POP ECX
005B34A0  |. 59             POP ECX
005B34A1  |. C645 B4 00     MOV BYTE PTR SS:[EBP-4C],0
005B34A5  |. 6A 04          PUSH 4
005B34A7  |. 8B7D 0C        MOV EDI,DWORD PTR SS:[EBP+C]      ****这是原来输入的原始形式的注册码
005B34AA  |. 31C0           XOR EAX,EAX
005B34AC  |. 83C9 FF        OR ECX,FFFFFFFF
005B34AF  |. F2:AE          REPNE SCAS BYTE PTR ES:[EDI]
005B34B1  |. BA FEFFFFFF    MOV EDX,-2
005B34B6  |. 29CA           SUB EDX,ECX                       ****取长度
005B34B8  |. 83C2 FC        ADD EDX,-4                        **** -4
005B34BB  |. 0355 0C        ADD EDX,DWORD PTR SS:[EBP+C]      ****edx 指向最后4个字符,即第5部分
005B34BE  |. 52             PUSH EDX                          
005B34BF  |. 8D45 B4        LEA EAX,DWORD PTR SS:[EBP-4C]
005B34C2  |. 50             PUSH EAX
005B34C3  |. E8 983C0800    CALL starryni.00637160            ****取出最后4个字符
005B34C8  |. 83C4 0C        ADD ESP,0C
005B34CB  |. 8D45 C0        LEA EAX,DWORD PTR SS:[EBP-40]     ****检查和字符串
005B34CE  |. 50             PUSH EAX
005B34CF  |. 8D45 B4        LEA EAX,DWORD PTR SS:[EBP-4C]     ****注册码最后部分字符串
005B34D2  |. 50             PUSH EAX
005B34D3  |. E8 C83C0800    CALL starryni.006371A0            ****比较看是否相等
005B34D8  |. 59             POP ECX
005B34D9  |. 59             POP ECX
005B34DA  |. 85C0           TEST EAX,EAX                      ****返回0表示相等
005B34DC  |. 74 0B          JE SHORT starryni.005B34E9
005B34DE  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B34E1  |. C600 08        MOV BYTE PTR DS:[EAX],8
005B34E4  |. E9 F6000000    JMP starryni.005B35DF
005B34E9  |> 8D7D CC        LEA EDI,DWORD PTR SS:[EBP-34]    
005B34EC  |. 31C0           XOR EAX,EAX
005B34EE  |. 83C9 FF        OR ECX,FFFFFFFF
005B34F1  |. F2:AE          REPNE SCAS BYTE PTR ES:[EDI]
005B34F3  |. BB FEFFFFFF    MOV EBX,-2
005B34F8  |. 29CB           SUB EBX,ECX
005B34FA  |. 807D 97 00     CMP BYTE PTR SS:[EBP-69],0        ****不明标志
005B34FE  |. 74 29          JE SHORT starryni.005B3529
005B3500  |. FF75 10        PUSH DWORD PTR SS:[EBP+10]        ****名字
005B3503  |. E8 ED010000    CALL starryni.005B36F5            ****关键call,计算名字检查和

            005B36F5  PUSH EBP
            005B36F6  MOV EBP,ESP
            005B36F8  PUSH EBX
            005B36F9  PUSH ESI
            005B36FA  PUSH EDI
            005B36FB  SUB ESP,24
            005B36FE  MOV DWORD PTR SS:[EBP-30],75BCD15      ****常数
            005B3705  PUSH 1E                                
            005B3707  LEA EAX,DWORD PTR SS:[EBP-2C]          
            005B370A  PUSH EAX                              
            005B370B  PUSH DWORD PTR SS:[EBP+8]                
            005B370E  CALL starryni.005B37BD                 ****这个函数见过了,就是串联字符串达到0x1E
            005B3713  ADD ESP,0C
            005B3716  TEST AL,AL
            005B3718  JNZ SHORT starryni.005B3721
            005B371A  MOV EAX,4455EE33                       ****奇怪的返回值表示失败
            005B371F  JMP SHORT starryni.005B3754
            005B3721  LEA EDI,DWORD PTR SS:[EBP-2C]          ****注册名字相连而成的长度为1E的串
            005B3724  XOR EAX,EAX
            005B3726  OR ECX,FFFFFFFF
            005B3729  REPNE SCAS BYTE PTR ES:[EDI]
            005B372B  MOV ESI,-2
            005B3730  SUB ESI,ECX
            005B3732  XOR EBX,EBX                            ****ebx是索引index
            005B3734  JMP SHORT starryni.005B374D
            005B3736  /MOVZX ECX,BYTE PTR SS:[EBP+EBX-2C]    ****ecx = ch
            005B373B  |MOV EDX,EBX                           ****edx = index
            005B373D  |IMUL EDX,EBX                          ****edx = index**2
            005B3740  |IMUL EDX,EBX                          ****edx = index**3
            005B3743  |IMUL EDX,ECX                          ****edx = index**3*ch
            005B3746  |IMUL EDX,ECX                          ****edx = index**3*ch**2
            005B3749  |ADD DWORD PTR SS:[EBP-30],EDX         ****加到常数75BCD15上
            005B374C  |INC EBX
            005B374D   CMP EBX,ESI
            005B374F  \JL SHORT starryni.005B3736
            005B3751  MOV EAX,DWORD PTR SS:[EBP-30]
            005B3754  LEA ESP,DWORD PTR SS:[EBP-C]
            005B3757  POP EDI
            005B3758  POP ESI
            005B3759  POP EBX
            005B375A  POP EBP
            005B375B  RETN
           
            这个过程计算名字的检查和,同样先把名字串联达到0x1E长度,然后计算:
            checksum = sum(index**3*ch**2) + 0x75BCD15

005B3508  |. 59             POP ECX
005B3509  |. 89C6           MOV ESI,EAX                        ****名字的检查和
005B350B  |. 8D53 F8        LEA EDX,DWORD PTR DS:[EBX-8]      
005B350E  |. 8D4D CC        LEA ECX,DWORD PTR SS:[EBP-34]      ****注册码前4部分相连并重排后的字符串
005B3511  |. 01CA           ADD EDX,ECX                        ****edx指向该字符串的后面8个字符
005B3513  |. 52             PUSH EDX                          
005B3514  |. E8 6A040000    CALL starryni.005B3983             ****转换成16进制数码
005B3519  |. 59             POP ECX
005B351A  |. 39F0           CMP EAX,ESI                        ****结果与名字的检查和比较
005B351C  |. 74 0B          JE SHORT starryni.005B3529         ****必须相等,否则失败
005B351E  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B3521  |. C600 04        MOV BYTE PTR DS:[EAX],4
005B3524  |. E9 B6000000    JMP starryni.005B35DF
005B3529  |> 8D45 CF        LEA EAX,DWORD PTR SS:[EBP-31]      ****重排后注册码的第2部分
005B352C  |. 50             PUSH EAX                          
005B352D  |. E8 FF030000    CALL starryni.005B3931             ****转换成16进制数
005B3532  |. 59             POP ECX
005B3533  |. 0FB7C0         MOVZX EAX,AX                       只保留低位字


005B3536  |. 89C3           MOV EBX,EAX
005B3538  |. E8 2E010000    CALL starryni.005B366B             ****这个函数没有搞懂。看上去十分复杂,很多层次
                                                              ****子程序调用,但与名字及注册码均无关,最后返回
005B353D  |. 89DA           MOV EDX,EBX                        ****0x135A
005B353F  |. 29C2           SUB EDX,EAX                        ****第2部分的值减去这个135A
005B3541  |. 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]
005B3544  |. 8910           MOV DWORD PTR DS:[EAX],EDX         ****如果结果小于0就会失败
005B3546  |. 0FBE45 98      MOVSX EAX,BYTE PTR SS:[EBP-68]     ****这里是注册码第二个字符,可能决定注册的版本
005B354A  |. 83E8 63        SUB EAX,63                        
005B354D  |. 74 26          JE SHORT starryni.005B3575
005B354F  |. 83E8 0B        SUB EAX,0B
005B3552  |. 74 56          JE SHORT starryni.005B35AA
005B3554  |. 83E8 04        SUB EAX,4
005B3557  |. 74 3B          JE SHORT starryni.005B3594
005B3559  |. 83E8 02        SUB EAX,2
005B355C  |. 74 07          JE SHORT starryni.005B3565
005B355E  |. 83E8 01        SUB EAX,1
005B3561  |. 74 47          JE SHORT starryni.005B35AA
005B3563  |. EB 4D          JMP SHORT starryni.005B35B2
005B3565  |> 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]      ****'t',注册15天试用版
005B3568  |. 8338 00        CMP DWORD PTR DS:[EAX],0
005B356B  |. 7C 2F          JL SHORT starryni.005B359C
005B356D  |. 837D 1C 28     CMP DWORD PTR SS:[EBP+1C],28
005B3571  |. 7E 47          JLE SHORT starryni.005B35BA
005B3573  |. EB 27          JMP SHORT starryni.005B359C
005B3575  |> 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]      ****'c',不明用处
005B3578  |. 8338 00        CMP DWORD PTR DS:[EAX],0
005B357B  |. 7C 1F          JL SHORT starryni.005B359C
005B357D  |. 837D 1C 14     CMP DWORD PTR SS:[EBP+1C],14
005B3581  |. 7E 02          JLE SHORT starryni.005B3585
005B3583  |. EB 17          JMP SHORT starryni.005B359C
005B3585  |> BA 14000000    MOV EDX,14
005B358A  |. 2B55 1C        SUB EDX,DWORD PTR SS:[EBP+1C]
005B358D  |. 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]
005B3590  |. 8910           MOV DWORD PTR DS:[EAX],EDX
005B3592  |. EB 26          JMP SHORT starryni.005B35BA
005B3594  |> 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]      ****'r',好像是正式的backyard版
005B3597  |. 8338 00        CMP DWORD PTR DS:[EAX],0
005B359A  |. 7D 1E          JGE SHORT starryni.005B35BA
005B359C  |> 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B359F  |. C600 03        MOV BYTE PTR DS:[EAX],3
005B35A2  |. 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]
005B35A5  |. 8320 00        AND DWORD PTR DS:[EAX],0
005B35A8  |. EB 35          JMP SHORT starryni.005B35DF
005B35AA  |> 8B45 14        MOV EAX,DWORD PTR SS:[EBP+14]      ****'n'和'u',没看出有什么特别
005B35AD  |. 8320 00        AND DWORD PTR DS:[EAX],0
005B35B0  |. EB 08          JMP SHORT starryni.005B35BA
005B35B2  |> 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]            ;  Default case of switch 005B354A
005B35B5  |. C600 07        MOV BYTE PTR DS:[EAX],7
005B35B8  |. EB 25          JMP SHORT starryni.005B35DF
005B35BA  |> 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]             ;  original code
005B35BD  |. 0FB610         MOVZX EDX,BYTE PTR DS:[EAX]
005B35C0  |. 3A55 20        CMP DL,BYTE PTR SS:[EBP+20]        ****第1个字符必须是'y'
005B35C3  |. 74 08          JE SHORT starryni.005B35CD
005B35C5  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B35C8  |. C600 09        MOV BYTE PTR DS:[EAX],9
005B35CB  |. EB 12          JMP SHORT starryni.005B35DF
005B35CD  |> 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]
005B35D0  |. 0FB650 02      MOVZX EDX,BYTE PTR DS:[EAX+2]      
005B35D4  |. 3A55 24        CMP DL,BYTE PTR SS:[EBP+24]        ****第3个字符必须是'4'
005B35D7  |. 74 0A          JE SHORT starryni.005B35E3
005B35D9  |. 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B35DC  |. C600 0A        MOV BYTE PTR DS:[EAX],0A
005B35DF  |> 30C0           XOR AL,AL                              
005B35E1  |. EB 1C          JMP SHORT starryni.005B35FF
005B35E3  |> 807D 98 74     CMP BYTE PTR SS:[EBP-68],74            
005B35E7  |. 74 06          JE SHORT starryni.005B35EF
005B35E9  |. 807D 98 63     CMP BYTE PTR SS:[EBP-68],63            
005B35ED  |. 75 08          JNZ SHORT starryni.005B35F7
005B35EF  |> 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B35F2  |. C600 01        MOV BYTE PTR DS:[EAX],1
005B35F5  |. EB 06          JMP SHORT starryni.005B35FD
005B35F7  |> 8B45 18        MOV EAX,DWORD PTR SS:[EBP+18]
005B35FA  |. C600 00        MOV BYTE PTR DS:[EAX],0
005B35FD  |> B0 01          MOV AL,1
005B35FF  |> 8D65 F4        LEA ESP,DWORD PTR SS:[EBP-C]
005B3602  |. 5F             POP EDI
005B3603  |. 5E             POP ESI
005B3604  |. 5B             POP EBX
005B3605  |. 5D             POP EBP
005B3606  \. C3             RETN

【分析总结】可用以下步骤生成注册码:
           1 将名字剔除一切特殊字符(包括空格)后,重复拷贝至0x1E个字符长;
           2 计算名字串的32-bit检查和 checksum = sum(index**3*ch**2)+0x75BCD15
           3 将检查和数字转换成字符串(8个字符)
           4 在该字符串头上加上"yx4ssss",其中'x'可以是t,r,n,u或c;s可以是任何16进制数字
             但不能小于0x135A
           5 将所得字符串复制、连接,正好达到0x1E个字符,计算检查和:
             checksum = sum(index*ch**2)-32EB
           6 所的检查和的低位字转换成字符串形式,这4个字符构成注册码的最后4位
           7 由名字检查和生成的字符串(长度8)加上前面的任意4个16进制数字构成一个12字符长的串,
             按照下面的顺序重新排列:
             10,7,1,8,4,11,2,5,3,9,6,0
             重排后的字符串构成注册码的第2,3和4部分。
           8 第一部分就是"yx4",其中'x'可以是t,r,n,u或c

【版权信息】本文版权属作者lianzi2000所有,转载请保持完整