Screen Demo Maker 3.0 註冊演算法分析

看雪資料發表於2003-07-15

目標軟體:  Screen Demo Maker 3.0 (漢化版)

軟體大小:  1.15 MB

軟體性質:  共享軟體

應用平臺:  Win9x/NT/2000/XP

下載地址:  http://antivirus.pchome.net/php/download2.php?sid=14825&url=/multimedia/videocap/SD3Setup0616.exe&svr=4  

軟體介紹:

Screen Demo Maker是一個螢幕動畫錄製軟體,大多被破解者用來作破解動畫過程的軟體,它可以記錄你的螢幕上的任何動作及滑鼠的移動過程,並支援聲音的錄製,同時使用了較高的壓縮率。
採用了特殊的壓縮演算法,並可以自由選擇可以選擇壓縮率,在正常的操作情況下,每分鐘的生成的檔案,大小在64-128Kbps左右(800x600x32bits)。生成的檔案可用軟體附帶的SDPlayer播放。
新版本增加了網路傳送功能和螢幕抓圖功能。
本漢化版已經將幫助檔案漢化,和解決了以前版本安裝後無法使用播放器的問題。

使用工具:  Fi、AspackDie、W32dasm、Filemon、WinHex、OllyDbg

破解過程:  

在序列號框中隨意輸入,點 註冊 後彈出對話方塊“無效的註冊編碼!”。
用 Fi 偵測,發現其用 ASPack 加殼,用 AspackDie 脫掉,在用 W32dasm 反彙編,在串式參考中找到“無效的註冊編碼!”,來到如下程式碼。

* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00406B2F(C), :00406B42(C)
|
:00406B62 6A00                    push 00000000
:00406B64 6A00                    push 00000000

* Possible StringData Ref from Data Obj ->"無效的註冊編碼!"
                                 |
:00406B66 68A8F34100              push 0041F3A8
:00406B6B 8BCE                    mov ecx, esi

它由兩個地方跳轉來,分別檢視。

:00406B17 E806D30000              Call 00413E22
:00406B1C 8B7E64                  mov edi, dword ptr [esi+64]
:00406B1F 8D5E64                  lea ebx, dword ptr [esi+64]
:00406B22 83C9FF                  or ecx, FFFFFFFF
:00406B25 33C0                    xor eax, eax
:00406B27 F2                      repnz
:00406B28 AE                      scasb
:00406B29 F7D1                    not ecx
:00406B2B 49                      dec ecx
:00406B2C 83F906                  cmp ecx, 00000006
:00406B2F 7531                    jne 00406B62  ---------------> 與 6 比較,不等就跳 "無效的註冊編碼!"
:00406B31 8B7E68                  mov edi, dword ptr [esi+68]
:00406B34 8D5668                  lea edx, dword ptr [esi+68]
:00406B37 83C9FF                  or ecx, FFFFFFFF
:00406B3A F2                      repnz
:00406B3B AE                      scasb
:00406B3C F7D1                    not ecx
:00406B3E 49                      dec ecx
:00406B3F 83F909                  cmp ecx, 00000009
:00406B42 751E                    jne 00406B62  ---------------> 與 9 比較,不等就跳 "無效的註冊編碼!"
:00406B44 6A0A                    push 0000000A
:00406B46 8BCA                    mov ecx, edx

因為註冊碼由兩部分組成,猜想可能是判斷兩部分各自的長度,再在第一部分隨便輸入 6 個字元,第二部分輸入 9 個字元,點 註冊 ,果然不在彈出對話方塊了!(居然蒙對了 :) )可再看看軟體,還是未註冊,接著用 Filemon 監視,在點下 註冊 後,發現其對C:\WINDOWS\system32\stpk.obj 進行操作,看來是將輸入的註冊碼儲存到 stpk.obj 中了,用 WinHex 開啟這個檔案,裡面果然有剛才輸入的註冊碼。接著請出OllyDbg,裝載程式,進行動態跟蹤,在其字元參考中搜尋 stpk.obj ,發現兩處,均下斷。按 F9 執行程式,在 0040643B 處中斷。現對其程式碼分析如下:

00406410  /$ 81EC DC030000  SUB ESP,3DC
00406416  |. 55             PUSH EBP
00406417  |. 56             PUSH ESI
00406418  |. 57             PUSH EDI
00406419  |. 8D4424 58      LEA EAX,DWORD PTR SS:[ESP+58]
0040641D  |. 8BF9           MOV EDI,ECX
0040641F  |. 68 90010000    PUSH 190                                 ; /BufSize = 190 (400.)
00406424  |. 50             PUSH EAX                                 ; |Buffer
00406425  |. 897C24 18      MOV DWORD PTR SS:[ESP+18],EDI            ; |
00406429  |. FF15 60904100  CALL DWORD PTR DS:[<&KERNEL32.GetSystemD>; \GetSystemDirectoryA
0040642F  |. 8D4C24 58      LEA ECX,DWORD PTR SS:[ESP+58]
00406433  |. 8D9424 E801000>LEA EDX,DWORD PTR SS:[ESP+1E8]
0040643A  |. 51             PUSH ECX                                 ; /<%s>
0040643B  |. 68 74F34100    PUSH unpacked.0041F374                   ; |format = "%s\stpk.obj"
00406440  |. 52             PUSH EDX                                 ; |s
00406441  |. FF15 88964100  CALL DWORD PTR DS:[<&MSVCRT.sprintf>]    ; \sprintf
00406447  |. 8B35 94964100  MOV ESI,DWORD PTR DS:[<&MSVCRT.fopen>]   ;  msvcrt.fopen
0040644D  |. 8D8424 F401000>LEA EAX,DWORD PTR SS:[ESP+1F4]

…………                                                             ;  [ 省略若干行 ]

00406506  |. 6A 0A          PUSH 0A                                  ;  [ 0A 入棧,後面計算註冊碼會用到 ]

…………                                                             ;  [ 省略若干行 ]

0040651A  |. 50             PUSH EAX
0040651B  |. 894F 08        MOV DWORD PTR DS:[EDI+8],ECX
0040651E  |. E8 7DFBFFFF    CALL unpacked.004060A0                   ;  [ 計算註冊碼的關鍵 Call ]
00406523  |. 8B4424 24      MOV EAX,DWORD PTR SS:[ESP+24]
00406527  |. 83C4 0C        ADD ESP,0C
0040652A  |. 83C0 04        ADD EAX,4
0040652D  |. 8BCF           MOV ECX,EDI
0040652F  |. 6A 32          PUSH 32
00406531  |. 50             PUSH EAX
00406532  |. C747 04 010000>MOV DWORD PTR DS:[EDI+4],1
00406539  |. E8 D2020000    CALL unpacked.00406810                   ;  [ 關鍵 Call ,判斷註冊碼的第一部分是否全為數字 ]
0040653E  |. 8B47 04        MOV EAX,DWORD PTR DS:[EDI+4]             ;  [ EAX = DS:[EDI+4] ]
                                                                       [ 此處的 EAX 至與 00406539 的 Call 有關 ]
00406541  |. 85C0           TEST EAX,EAX
00406543  |. 74 54          JE SHORT unpacked.00406599               ;  [ 若 EAX = 00000000 , 則跳至 00406599 ]
                                                                       [ 即跳過註冊碼第二部分的判斷,直接以未註冊版執行 ]
00406545  |. 8B4C24 18      MOV ECX,DWORD PTR SS:[ESP+18]
00406549  |. 6A 09          PUSH 9                                   ; /maxlen = 9
0040654B  |. 83C1 0B        ADD ECX,0B                               ; |
0040654E  |. 8D5424 47      LEA EDX,DWORD PTR SS:[ESP+47]            ; |
00406552  |. 51             PUSH ECX                                 ; |s2         [ 讀入假碼的第二部分 ]
00406553  |. 52             PUSH EDX                                 ; |s1         [ 讀入真碼的第二部分 ]
00406554  |. FF15 84964100  CALL DWORD PTR DS:[<&MSVCRT.strncmp>]    ; \strncmp    [ 進行比較 ]

…………                                                             ;  [ 以下省略 ]


**************計算註冊碼的關鍵 Call*******************************************************

004060A0  /$ 53             PUSH EBX
004060A1  |. 55             PUSH EBP
004060A2  |. 8B6C24 10      MOV EBP,DWORD PTR SS:[ESP+10]
004060A6  |. 56             PUSH ESI
004060A7  |. 8B7424 10      MOV ESI,DWORD PTR SS:[ESP+10]
004060AB  |. 57             PUSH EDI
004060AC  |. 8BCE           MOV ECX,ESI
004060AE  |. 8D5D 07        LEA EBX,DWORD PTR SS:[EBP+7]
004060B1  |. C646 06 00     MOV BYTE PTR DS:[ESI+6],0
004060B5  |. 8BC5           MOV EAX,EBP
004060B7  |. 2BCD           SUB ECX,EBP
004060B9  |. BF 06000000    MOV EDI,6
004060BE  |> 8A1401         /MOV DL,BYTE PTR DS:[ECX+EAX]            ; /  004060BE~004060C5這一段的功能是:
004060C1  |. 8810           |MOV BYTE PTR DS:[EAX],DL                ; |  將註冊碼的第一部分複製 0012F8A0
004060C3  |. 40             |INC EAX                                 ; |  0012F8A0 就是真碼出現的地方
004060C4  |. 4F             |DEC EDI                                 ; |
004060C5  |.^75 F7          \JNZ SHORT unpacked.004060BE             ; \
004060C7  |. 8B7C24 1C      MOV EDI,DWORD PTR SS:[ESP+1C]            ;  [ 將 SS:[ESP+1C] 的值給 EDI ]
                                                                    ;  [ EDI = 0000000A ,即前面入棧的 0A ]
004060CB  |. C645 06 2D     MOV BYTE PTR SS:[EBP+6],2D               ;  [ 0012F8A0 中註冊碼第一部分的後面加上 - ]

--------------- 計算第二部分的前三個字母開始 ------------

004060CF  |. 0FBE4E 03      MOVSX ECX,BYTE PTR DS:[ESI+3]            ;  [ 將第一部分的第四個數字的 ASCII 碼給 ECX ]
004060D3  |. 0FBE06         MOVSX EAX,BYTE PTR DS:[ESI]              ;  [ 將第一部分的第一個數字的 ASCII 碼給 EAX ]
004060D6  |. 8BD7           MOV EDX,EDI                              ;  [ EDX = EDI = 0000000A ]
004060D8  |. 6A 03          PUSH 3
004060DA  |. 03D1           ADD EDX,ECX                              ;  [ EDX = EDX +ECX ]            
004060DC  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]
004060E1  |. 03C2           ADD EAX,EDX                              ;  [ EAX = EAX + EDX ]
004060E3  |. C64424 1B 00   MOV BYTE PTR SS:[ESP+1B],0
004060E8  |. 99             CDQ                                      ;  [ EAX 符號擴充套件為 64 位 EDX:EAX ]
                                                                       [ 此處 CDQ 的作用實際就是將 EDX 清零 ]
                                                                       ( 不知道我的理解對不對,望高手指點。)
004060E9  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,餘數存入 EDX ]
004060EB  |. 0FBE46 01      MOVSX EAX,BYTE PTR DS:[ESI+1]            ;  [ 將第一部分的第二個數字的 ASCII 碼給 EAX ]
004060EF  |. 8BCF           MOV ECX,EDI                              ;  [ ECX = EDI ]
004060F1  |. 80C2 41        ADD DL,41                                ;  [ DL = DL +41h ]
004060F4  |. 885424 18      MOV BYTE PTR SS:[ESP+18],DL              ;  [ 將 DL 值存入 SS:[ESP+18] ]
                                                                       [ 這就是註冊碼第二部分的第一位 ]
                                                                       [ 接下來是計算註冊碼第二部分的第二、三位]
                                                                       [ 演算法與此相同,不再贅述 ]
004060F8  |. 0FBE56 04      MOVSX EDX,BYTE PTR DS:[ESI+4]            
004060FC  |. 03CA           ADD ECX,EDX                              
004060FE  |. 03C1           ADD EAX,ECX                              
00406100  |. B9 19000000    MOV ECX,19                                
00406105  |. 99             CDQ                                      
00406106  |. F7F9           IDIV ECX                                  
00406108  |. 0FBE46 02      MOVSX EAX,BYTE PTR DS:[ESI+2]            
0040610C  |. 8BCF           MOV ECX,EDI                              
0040610E  |. 80C2 41        ADD DL,41                                
00406111  |. 885424 19      MOV BYTE PTR SS:[ESP+19],DL              
00406115  |. 0FBE56 05      MOVSX EDX,BYTE PTR DS:[ESI+5]            
00406119  |. 03CA           ADD ECX,EDX                              
0040611B  |. 03C1           ADD EAX,ECX                              
0040611D  |. B9 19000000    MOV ECX,19                                
00406122  |. 99             CDQ                                      
00406123  |. F7F9           IDIV ECX                                
00406125  |. 80C2 41        ADD DL,41                                
00406128  |. 885424 1A      MOV BYTE PTR SS:[ESP+1A],DL

--------------- 計算第二部分的前三個字母結束 -------------

0040612C  |. 8D5424 18      LEA EDX,DWORD PTR SS:[ESP+18]            
00406130  |. 52             PUSH EDX                                  
00406131  |. 53             PUSH EBX                                
00406132  |. 8B1D 8C964100  MOV EBX,DWORD PTR DS:[<&MSVCRT.strncpy>]  
00406138  |. FFD3           CALL EBX                                 ;  [ 將這三個字母接在 0012F8A0 中部分註冊碼的後面 ]

--------------- 計算第二部分的中間三個字母開始 --------------

0040613A  |. 0FBE46 03      MOVSX EAX,BYTE PTR DS:[ESI+3]            ;  [ 將第一部分的第四個數字的 ASCII 碼給 EAX ]
0040613E  |. 0FBE0E         MOVSX ECX,BYTE PTR DS:[ESI]              ;  [ 將第一部分的第一個數字的 ASCII 碼給 ECX ]
00406141  |. 2BC8           SUB ECX,EAX                              ;  [ ECX = ECX - EAX ]
00406143  |. 6A 03          PUSH 3
00406145  |. 8D4439 20      LEA EAX,DWORD PTR DS:[ECX+EDI+20]        ;  [ EAX = ECX + EDI + 20h ]
00406149  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]
0040614E  |. 99             CDQ                                      ;  [ 將 EDX 清零 ]
0040614F  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,餘數存入 EDX ]
00406151  |. 0FBE46 04      MOVSX EAX,BYTE PTR DS:[ESI+4]            ;  [ 將第一部分的第五個數字的 ASCII 碼給 EAX ]
00406155  |. 80C2 41        ADD DL,41                                ;  [ DL = DL + 41h ]
00406158  |. 885424 24      MOV BYTE PTR SS:[ESP+24],DL              ;  [ 將 DL 值存入 DS:[ESI+24] ]
                                                                       [ 這就是註冊碼第二部分的第四位 ]
                                                                       [ 接下來是計算註冊碼第二部分的第五、六位]
                                                                       [ 演算法與此相同,不再贅述 ]
0040615C  |. 0FBE56 01      MOVSX EDX,BYTE PTR DS:[ESI+1]
00406160  |. 2BD0           SUB EDX,EAX
00406162  |. 8D443A 20      LEA EAX,DWORD PTR DS:[EDX+EDI+20]
00406166  |. 99             CDQ
00406167  |. F7F9           IDIV ECX
00406169  |. 0FBE46 05      MOVSX EAX,BYTE PTR DS:[ESI+5]
0040616D  |. 80C2 41        ADD DL,41
00406170  |. 885424 25      MOV BYTE PTR SS:[ESP+25],DL
00406174  |. 0FBE56 02      MOVSX EDX,BYTE PTR DS:[ESI+2]
00406178  |. 2BD0           SUB EDX,EAX
0040617A  |. 8D443A 20      LEA EAX,DWORD PTR DS:[EDX+EDI+20]
0040617E  |. 99             CDQ
0040617F  |. F7F9           IDIV ECX
00406181  |. 8D45 0A        LEA EAX,DWORD PTR SS:[EBP+A]
00406184  |. 80C2 41        ADD DL,41
00406187  |. 885424 26      MOV BYTE PTR SS:[ESP+26],DL

--------------- 計算第二部分的中間三個字母結束 -----------------

0040618B  |. 8D5424 24      LEA EDX,DWORD PTR SS:[ESP+24]
0040618F  |. 52             PUSH EDX
00406190  |. 50             PUSH EAX
00406191  |. FFD3           CALL EBX                                 ;  [ 將這三個字母接在 0012F8A0 中部分註冊碼的後面 ]

--------------- 計算第二部分的後三個字母開始 -------------------

00406193  |. 0FBE46 03      MOVSX EAX,BYTE PTR DS:[ESI+3]            ;  [ 將第一部分的第四個數字的 ASCII 碼給 EAX ]
00406197  |. 0FBE0E         MOVSX ECX,BYTE PTR DS:[ESI]              ;  [ 將第一部分的第一個數字的 ASCII 碼給 ECX ]
0040619A  |. 03C7           ADD EAX,EDI                              ;  [ EAX = EAX + EDI ]
0040619C  |. 33C1           XOR EAX,ECX                              ;  [ EAX = EAX XOR ECX ]
0040619E  |. B9 19000000    MOV ECX,19                               ;  [ ECX = 19h ]
004061A3  |. 99             CDQ                                      ;  [ 將 EDX 清零 ]
004061A4  |. F7F9           IDIV ECX                                 ;  [ EAX 除以 ECX 商存入 EAX ,餘數存入 EDX ]
004061A6  |. 0FBE46 04      MOVSX EAX,BYTE PTR DS:[ESI+4]            ;  [ 將第一部分的第五個數字的 ASCII 碼給 EAX ]
004061AA  |. 80C2 41        ADD DL,41                                ;  [ DL = DL + 41h ]
004061AD  |. 03C7           ADD EAX,EDI                              ;  [ EAX = EAX + EDI ]
004061AF  |. 885424 2C      MOV BYTE PTR SS:[ESP+2C],DL              ;  [ DL 存入 SS:[ESP+2C] ]
                                                                       [ 這就是註冊碼第二部分的第七位 ]
                                                                       [ 接下來是計算註冊碼第二部分的第八、九位]
                                                                       [ 演算法與此相同,不再贅述 ]
004061B3  |. 0FBE56 01      MOVSX EDX,BYTE PTR DS:[ESI+1]
004061B7  |. 33C2           XOR EAX,EDX
004061B9  |. 6A 03          PUSH 3
004061BB  |. 99             CDQ
004061BC  |. F7F9           IDIV ECX
004061BE  |. 0FBE46 05      MOVSX EAX,BYTE PTR DS:[ESI+5]
004061C2  |. 03C7           ADD EAX,EDI
004061C4  |. 80C2 41        ADD DL,41
004061C7  |. 885424 31      MOV BYTE PTR SS:[ESP+31],DL
004061CB  |. 0FBE56 02      MOVSX EDX,BYTE PTR DS:[ESI+2]
004061CF  |. 33C2           XOR EAX,EDX
004061D1  |. 99             CDQ
004061D2  |. F7F9           IDIV ECX
004061D4  |. 8D45 0D        LEA EAX,DWORD PTR SS:[EBP+D]
004061D7  |. 80C2 41        ADD DL,41
004061DA  |. 885424 32      MOV BYTE PTR SS:[ESP+32],DL

--------------- 計算第二部分的後三個字母結束 -------------------

004061DE  |. 8D5424 30      LEA EDX,DWORD PTR SS:[ESP+30]
004061E2  |. 52             PUSH EDX
004061E3  |. 50             PUSH EAX
004061E4  |. FFD3           CALL EBX                               ;  [ 將這三個字母接在 0012F8A0 中部分註冊碼的後面 ]
                                                                     [ 至此,從 0012F8A0 開始為完整的正確註冊碼 ]
004061E6  |. 83C4 24        ADD ESP,24
004061E9  |. C645 10 00     MOV BYTE PTR SS:[EBP+10],0
004061ED  |. B8 01000000    MOV EAX,1
004061F2  |. 5F             POP EDI
004061F3  |. 5E             POP ESI
004061F4  |. 5D             POP EBP
004061F5  |. 5B             POP EBX
004061F6  \. C3             RETN

**********判斷註冊碼的第一部分是否全為數字關鍵 Call *******************************

00406810  /$ 8B51 04        MOV EDX,DWORD PTR DS:[ECX+4]
00406813  |. 85D2           TEST EDX,EDX
00406815  |. 74 30          JE SHORT unpacked.00406847
00406817  |. 8B4424 08      MOV EAX,DWORD PTR SS:[ESP+8]
0040681B  |> 85C0           /TEST EAX,EAX
0040681D  |. 7E 08          |JLE SHORT unpacked.00406827
0040681F  |. 48             |DEC EAX
00406820  |. 85D2           |TEST EDX,EDX
00406822  |.^75 F7          \JNZ SHORT unpacked.0040681B
00406824  |. C2 0800        RETN 8
00406827  |> 56             PUSH ESI
00406828  |. 8B7424 08      MOV ESI,DWORD PTR SS:[ESP+8]
0040682C  |. 33D2           XOR EDX,EDX
0040682E  |> 8A0432         /MOV AL,BYTE PTR DS:[EDX+ESI]
00406831  |. 3C 30          |CMP AL,30
00406833  |. 7C 04          |JL SHORT unpacked.00406839              ;  [ 比 30 小就令 DS:[ECX+4]=0 ]
00406835  |. 3C 39          |CMP AL,39
00406837  |. 7E 07          |JLE SHORT unpacked.00406840             ;  [ 比 39 大就令 DS:[ECX+4]=0 ]
00406839  |> C741 04 000000>|MOV DWORD PTR DS:[ECX+4],0
00406840  |> 42             |INC EDX
00406841  |. 83FA 06        |CMP EDX,6
00406844  |.^7C E8          \JL SHORT unpacked.0040682E
00406846  |. 5E             POP ESI
00406847  \> C2 0800        RETN 8

***********演算法總結***************************************************************

註冊碼由兩段組成:第一段必須為數字,有六位;第二段有九位,由第一部分算得。

第二部分九位的演算法:( !注意:以下均指 ASCII碼 )

前三個字母:   1) ( 第一段第一個 + 第一段第四個 + 0Ah ) 除以 19h 的餘數 + 41h 的和即為第二段第1個字母
              2) ( 第一段第二個 + 第一段第五個 + 0Ah ) 除以 19h 的餘數 + 41h 的和即為第二段第2個字母
              3) ( 第一段第三個 + 第一段第六個 + 0Ah ) 除以 19h 的餘數 + 41h 的和即為第二段第3個字母  

中間三個字母: 4) ( 第一段第一個 - 第一段第四個 + 0Ah + 20h ) 除以 19h 的餘數 + 41h 即為第二段第4個字母
              5) ( 第一段第二個 - 第一段第五個 + 0Ah + 20h ) 除以 19h 的餘數 + 41h 即為第二段第5個字母
              6) ( 第一段第三個 - 第一段第六個 + 0Ah + 20h ) 除以 19h 的餘數 + 41h 即為第二段第6個字母

後三個字母:   7) ( 第一段第四個 + 0Ah 的和與第一段第一個異或 ) 除以 19h 的餘數 + 41h 即為第二段第7個字母
              8) ( 第一段第五個 + 0Ah 的和與第一段第二個異或 ) 除以 19h 的餘數 + 41h 即為第二段第8個字母
              9) ( 第一段第六個 + 0Ah 的和與第一段第三個異或 ) 除以 19h 的餘數 + 41h 即為第二段第9個字母


相關文章