题目:注册“豪杰视频通Hero Video Convert v2.0”
软件功能:支持直接从DVD光盘转为VCD格式的视频文件;支持目前常见的视频格式的相互转化,支持格式包括MPGE1,MPEG2,MPEG4,AVI,DAT,VOB,RM等;支持把以上视频格式转化为GIF动画;可以播放和转化同时进行;支持最新的超线程技术(Hyper-Thread)。
工具:softice
 
引子:没有想到在2003电脑爱好者光盘上包括大部分豪杰的东西,今天连续作战搞定这一系列东西。注册码算法思路基本一样,但是具体每个软件都有不同的注册码生成算法。下面开始分析。启动程序,输入用户名和注册码。比如wanggang, 1111-2222-3333-4444。打开SOFTICE,下断点bpx getwindowtexta,F5退出,点击确定被拦住。按1次F12来到下面代码处:
:00402480 83EC40                  sub esp, 00000040
:00402483 8B0D38CC4000            mov ecx, dword ptr [0040CC38]
:00402489 56                      push esi
* Reference To: USER32.GetWindowTextA, Ord:015Eh
                                  |
:0040248A 8B3598914000            mov esi, dword ptr [00409198]
:00402490 8D442404                lea eax, dword ptr [esp+04]
:00402494 6A08                    push 00000008
:00402496 50                      push eax
:00402497 51                      push ecx
:00402498 FFD6                    call esi        //读取注册码第一段
:0040249A A134CC4000              mov eax, dword ptr [0040CC34]  //我们停在这里。
:0040249F 8D542409                lea edx, dword ptr [esp+09]
:004024A3 6A08                    push 00000008
:004024A5 52                      push edx
:004024A6 50                      push eax
:004024A7 FFD6                    call esi       //读取注册码第二段
:004024A9 8B1540CC4000            mov edx, dword ptr [0040CC40]
:004024AF 8D4C240E                lea ecx, dword ptr [esp+0E]
:004024B3 6A08                    push 00000008
:004024B5 51                      push ecx
:004024B6 52                      push edx
:004024B7 FFD6                    call esi       //读取注册码第三段
:004024B9 8B0D3CCC4000            mov ecx, dword ptr [0040CC3C]
:004024BF 8D442413                lea eax, dword ptr [esp+13]
:004024C3 6A08                    push 00000008
:004024C5 50                      push eax
:004024C6 51                      push ecx
:004024C7 FFD6                    call esi       //读取注册码第四段
:004024C9 8B1530CC4000            mov edx, dword ptr [0040CC30]
:004024CF 6800010000              push 00000100
:004024D4 B02D                    mov al, 2D
:004024D6 6880CD4000              push 0040CD80
:004024DB 52                      push edx
:004024DC 8844241E                mov byte ptr [esp+1E], al  //下面三行每隔4位插入"-"号
:004024E0 88442419                mov byte ptr [esp+19], al
:004024E4 88442414                mov byte ptr [esp+14], al
:004024E8 C644242300              mov [esp+23], 00
:004024ED FFD6                    call esi       //读取用户名。
:004024EF A158C74000              mov eax, dword ptr [0040C758]
:004024F4 5E                      pop esi
:004024F5 85C0                    test eax, eax
:004024F7 740E                    je 00402507
:004024F9 8D4C2400                lea ecx, dword ptr [esp]
:004024FD 51                      push ecx
:004024FE 6880CD4000              push 0040CD80
:00402503 FFD0                    call eax           //跟入这个CALL。计算注册码的地方。EAX值为100010A0。
:00402505 EB0F                    jmp 00402516
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004024F7(C)
|
:00402507 8D542400                lea edx, dword ptr [esp]
:0040250B 52                      push edx
:0040250C 6880CD4000              push 0040CD80
:00402511 E8DA140000              call 004039F0
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00402505(U)
|
:00402516 33C9                    xor ecx, ecx
:00402518 8D542400                lea edx, dword ptr [esp]
:0040251C 85C0                    test eax, eax
:0040251E 0F95C1                  setne cl          //注册码正确则置CL 为1。
:00402521 52                      push edx
:00402522 6880CD4000              push 0040CD80
:00402527 890D40F84000            mov dword ptr [0040F840], ecx
:0040252D E82E000000              call 00402560
:00402532 8B4C244C                mov ecx, dword ptr [esp+4C]
:00402536 8B1564CD4000            mov edx, dword ptr [0040CD64]
:0040253C 83C408                  add esp, 00000008
:0040253F 8D442400                lea eax, dword ptr [esp]
:00402543 50                      push eax
:00402544 68E0234000              push 004023E0
:00402549 51                      push ecx
* Possible Reference to Dialog: DialogID_0069 
                                  |
:0040254A 6A69                    push 00000069
:0040254C 52                      push edx
* Reference To: USER32.DialogBoxParamA, Ord:0093h
                                  |
:0040254D FF15C4914000            Call dword ptr [004091C4]      //成功信息。
:00402553 A140F84000              mov eax, dword ptr [0040F840]
:00402558 83C440                  add esp, 00000040
:0040255B C3                      ret
============================================================
下面分析:00402503处的函数:
:100010A0 83EC20                  sub esp, 00000020
:100010A3 33C0                    xor eax, eax
:100010A5 B908000000              mov ecx, 00000008
:100010AA 53                      push ebx
:100010AB 56                      push esi
:100010AC 57                      push edi
:100010AD 8D7C240C                lea edi, dword ptr [esp+0C]
:100010B1 F3                      repz
:100010B2 AB                      stosd
:100010B3 8B442430                mov eax, dword ptr [esp+30]
:100010B7 33FF                    xor edi, edi
:100010B9 50                      push eax
:100010BA E8E1010000              call 100012A0                 //用户名变换后,把用户名每4位累加起来。
:100010BF 89442410                mov dword ptr [esp+10], eax
:100010C3 83C404                  add esp, 00000004
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100010E9(C)
|
:100010C6 8D743C0C                lea esi, dword ptr [esp+edi+0C]  //变换后的用户名地址送ESI。
:100010CA 0FBE06                  movsx eax, byte ptr [esi]        //逐位取出送EAX。
:100010CD 83F841                  cmp eax, 00000041
:100010D0 7C08                    jl 100010DA
:100010D2 83F85A                  cmp eax, 0000005A
:100010D5 7F03                    jg 100010DA
:100010D7 83C020                  add eax, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:100010D0(C), :100010D5(C)
|
:100010DA 50                      push eax
:100010DB 47                      inc edi
:100010DC E88F040000              call 10001570                //对变换后的用户名进一步变换。
:100010E1 83C404                  add esp, 00000004
:100010E4 8806                    mov byte ptr [esi], al
:100010E6 83FF04                  cmp edi, 00000004
:100010E9 7CDB                    jl 100010C6
:100010EB 33C9                    xor ecx, ecx
:100010ED 8B742434                mov esi, dword ptr [esp+34]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001113(C)
|
:100010F1 0FBE040E                movsx eax, byte ptr [esi+ecx]
:100010F5 83F841                  cmp eax, 00000041
:100010F8 7C08                    jl 10001102
:100010FA 83F85A                  cmp eax, 0000005A
:100010FD 7F03                    jg 10001102
:100010FF 83C020                  add eax, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:100010F8(C), :100010FD(C)
|
:10001102 0FBE540C0C              movsx edx, byte ptr [esp+ecx+0C]  //第一段真码字符依次送EDX。
:10001107 3BD0                    cmp edx, eax                      //比较
:10001109 0F8540010000            jne 1000124F
:1000110F 41                      inc ecx
:10001110 83F904                  cmp ecx, 00000004
:10001113 7CDC                    jl 100010F1                        //未完则继续。
:10001115 8B44240C                mov eax, dword ptr [esp+0C]    //EAX=第一段注册码
:10001119 8D0C80                  lea ecx, dword ptr [eax+4*eax] //ECX=5*EAX
:1000111C 8D0489                  lea eax, dword ptr [ecx+4*ecx] //EAX=5*ECX
:1000111F 8B4C240C                mov ecx, dword ptr [esp+0C]    //ECX=第一段注册码。
:10001123 8BD1                    mov edx, ecx  
:10001125 33DB                    xor ebx, ebx
:10001127 C1E105                  shl ecx, 05     //ECX左移5次
:1000112A 03CA                    add ecx, edx    //ECX=ECX+EDX
:1000112C 33C1                    xor eax, ecx    //EAX=EAX与ECX异或。
:1000112E 89442410                mov dword ptr [esp+10], eax  //保存结果。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001155(C)
|
:10001132 8D7C1C10                lea edi, dword ptr [esp+ebx+10]  //下面把得到的第二段注册码码变换为1-9或者a-z之间的字符。
:10001136 8A07                    mov al, byte ptr [edi]  
:10001138 50                      push eax
:10001139 53                      push ebx
:1000113A 43                      inc ebx
:1000113B E840010000              call 10001280     //变换函数。
:10001140 83C408                  add esp, 00000008
:10001143 33C9                    xor ecx, ecx
:10001145 8AC8                    mov cl, al
:10001147 51                      push ecx
:10001148 E823040000              call 10001570     //变换函数
:1000114D 83C404                  add esp, 00000004
:10001150 8807                    mov byte ptr [edi], al
:10001152 83FB04                  cmp ebx, 00000004
:10001155 7CDB                    jl 10001132
:10001157 33C9                    xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000117C(C)
|
:10001159 0FBE440E05              movsx eax, byte ptr [esi+ecx+05]  //取假码。
:1000115E 83F841                  cmp eax, 00000041
:10001161 7C08                    jl 1000116B
:10001163 83F85A                  cmp eax, 0000005A
:10001166 7F03                    jg 1000116B
:10001168 83C020                  add eax, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001161(C), :10001166(C)
|
:1000116B 0FBE540C10              movsx edx, byte ptr [esp+ecx+10] //取真码。
:10001170 3BD0                    cmp edx, eax                     //比较。
:10001172 0F85E2000000            jne 1000125A
:10001178 41                      inc ecx
:10001179 83F904                  cmp ecx, 00000004
:1000117C 7CDB                    jl 10001159                      //循环。
:1000117E 8B442410                mov eax, dword ptr [esp+10] //EAX=第二段注册码。
:10001182 8B4C240C                mov ecx, dword ptr [esp+0C] //ECX=第一段注册码
:10001186 3344240C                xor eax, dword ptr [esp+0C] //EAX与第一段注册码异或
:1000118A 8BD1                    mov edx, ecx     
:1000118C 0FAF44240C              imul eax, dword ptr [esp+0C]    //EAX=EAX*第一段注册码
:10001191 03442410                add eax, dword ptr [esp+10]     //EAX=EAX+第二段注册码。
:10001195 8D0C49                  lea ecx, dword ptr [ecx+2*ecx]  //ECX=3*ECX
:10001198 C1E103                  shl ecx, 03       //ECX左移3次。
:1000119B 33DB                    xor ebx, ebx
:1000119D 2BCA                    sub ecx, edx      //ECX与EDX异或,送ECX。
:1000119F 33C1                    xor eax, ecx      //EAX与ECX异或,送EAX。
:100011A1 89442414                mov dword ptr [esp+14], eax    //结果保存。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100011BB(C)
|
:100011A5 8D7C1C14                lea edi, dword ptr [esp+ebx+14] //下面对得到第三段进行变换。
:100011A9 43                      inc ebx
:100011AA 0FBE07                  movsx eax, byte ptr [edi]
:100011AD 50                      push eax
:100011AE E8BD030000              call 10001570      //变换函数。
:100011B3 83C404                  add esp, 00000004
:100011B6 8807                    mov byte ptr [edi], al
:100011B8 83FB04                  cmp ebx, 00000004
:100011BB 7CE8                    jl 100011A5
:100011BD 33C9                    xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:100011E2(C)
|
:100011BF 0FBE440E0A              movsx eax, byte ptr [esi+ecx+0A] //取假码
:100011C4 83F841                  cmp eax, 00000041
:100011C7 7C08                    jl 100011D1
:100011C9 83F85A                  cmp eax, 0000005A
:100011CC 7F03                    jg 100011D1
:100011CE 83C020                  add eax, 00000020
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:100011C7(C), :100011CC(C)
|
:100011D1 0FBE540C14              movsx edx, byte ptr [esp+ecx+14] //取真码
:100011D6 3BD0                    cmp edx, eax                     //比较。
:100011D8 0F8587000000            jne 10001265
:100011DE 41                      inc ecx
:100011DF 83F904                  cmp ecx, 00000004
:100011E2 7CDB                    jl 100011BF                       //未完继续。
:100011E4 8B4C2410                mov ecx, dword ptr [esp+10]  //ECX=第二段注册码。
:100011E8 8B442414                mov eax, dword ptr [esp+14]  //EAX=第三段注册码。
:100011EC 41                      inc ecx                      //ECX加1。
:100011ED 0FAF4C240C              imul ecx, dword ptr [esp+0C]  //ECX=ECX*第一段注册码
:100011F2 33FF                    xor edi, edi
:100011F4 8D1489                  lea edx, dword ptr [ecx+4*ecx] //EDX=5*ECX。
:100011F7 8D0C91                  lea ecx, dword ptr [ecx+4*edx] //ECX=4*EDX+ECX。
:100011FA 8D1440                  lea edx, dword ptr [eax+2*eax] //EDX=3*EAX。
:100011FD 8D1CD2                  lea ebx, dword ptr [edx+8*edx] //EBX=9*EDX
:10001200 03CB                    add ecx, ebx                   //ECX=ECX+EBX。
:10001202 894C2418                mov dword ptr [esp+18], ecx     //保存结果。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000121C(C)
|
:10001206 8D5C3C18                lea ebx, dword ptr [esp+edi+18]  //下面对得到的第四段进行变换。
:1000120A 47                      inc edi
:1000120B 0FBE03                  movsx eax, byte ptr [ebx]
:1000120E 50                      push eax
:1000120F E85C030000              call 10001570                    //变换函数
:10001214 83C404                  add esp, 00000004
:10001217 8803                    mov byte ptr [ebx], al
:10001219 83FF04                  cmp edi, 00000004
:1000121C 7CE8                    jl 10001206                      //未完继续。
:1000121E 33C9                    xor ecx, ecx
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1000123F(C)
|
:10001220 0FBE440E0F              movsx eax, byte ptr [esi+ecx+0F]  //取假码。
:10001225 83F841                  cmp eax, 00000041
:10001228 7C08                    jl 10001232
:1000122A 83F85A                  cmp eax, 0000005A
:1000122D 7F03                    jg 10001232
:1000122F 83C020                  add eax, 00000020

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:10001228(C), :1000122D(C)
|
:10001232 0FBE540C18              movsx edx, byte ptr [esp+ecx+18]  //取真码。
:10001237 3BD0                    cmp edx, eax                      //比较。
:10001239 7535                    jne 10001270
:1000123B 41                      inc ecx
:1000123C 83F904                  cmp ecx, 00000004
:1000123F 7CDF                    jl 10001220                       //未完则继续。
:10001241 B801000000              mov eax, 00000001       //如果正确则EAX=1。
:10001246 5F                      pop edi
:10001247 5E                      pop esi
:10001248 5B                      pop ebx
:10001249 83C420                  add esp, 00000020
:1000124C C20800                  ret 0008
============================================================
后记:大部分的豪杰软件都一个模式下来的。所以相对比较简单。为了节省篇幅,把里面的几个函数内容分析略掉,请参考其他豪杰破文即可。感谢您的阅读!


结论:
用户名:wanggang
注册码:7zq3-59m4-rha2-7155


qduwg@163.com
qduwg

2006/1/28晚