[簡單]TVjukebox2.0 序號分析

看雪資料發表於2005-01-04

【軟體名稱】TV jukebox2.0
【下載地址】拿別人的複製
【應用平臺】Win9x/NT/2000/XP
【軟體大小】未知
【軟體限制】安裝序列號
【破解作者】sword
【破解宣告】破解只是感興趣,無其它目的。失誤之處敬請諸位大俠賜教!
【破解工具】ollydbg,C32Asm
【軟體簡介】一款電視卡軟體,同學說只能從光碟安裝時才會出現輸入序列號的地方,否則安裝完成後,提示序號錯誤退出!
========================================================================================

【分析過程】



【前言】很弱智的軟體加密演算法,高手別看了。浪費時間

【Thinking in Crack】既然能安裝成功,在執行時才提示出錯,那麼註冊碼基本上就是寫在硬碟或者登錄檔的某個地方,(1)可以用RegOpenKey和CreateFile下斷試試!(2)既然會彈出錯誤提示我們不防反編譯一下,找找從哪提示出錯的,很遺憾找不到,那樣的話,就用下MessageBox看看有沒有收穫,呵呵有,下面用第二種方式分析:

【演算法追蹤】

程式碼:
0041DC55  |. 50                   PUSH EAX                                        ; /pBufSize 0041DC56  |. 8B4424 14            MOV EAX,DWORD PTR SS:[ESP+14]                   ; | 0041DC5A  |. 8D5424 50            LEA EDX,DWORD PTR SS:[ESP+50]                   ; | 0041DC5E  |. 51                   PUSH ECX                                        ;                                        |  Buffer 0041DC5F  |. 52                   PUSH EDX                                        ; |pValueType 0041DC60  |. 53                   PUSH EBX                                        ; |Reserved 0041DC61  |. 68 98494400          PUSH tvjukebo.00444998                          ; |ValueName = serial_number" 0041DC66  |. 50                   PUSH EAX                                        ; |hKey 0041DC67  |. C74424 60 00010000   MOV DWORD PTR SS:[ESP+60],100                   ; | 0041DC6F  |. FF15 00204300        CALL DWORD PTR DS:[<&ADVAPI32.RegQueryValueExA>>; \取登錄檔的鍵值  哈哈看看你的登錄檔看看有沒有這個,沒有的話自己建一個,然後給他符一個字串 我用sword 0041DC75  |. 85C0                 TEST EAX,EAX 0041DC77  |. 75 25                JNZ SHORT tvjukebo.0041DC9E                     ;  如果沒有那個鍵值的話,跳走 0041DC79  |. 8B4424 4C            MOV EAX,DWORD PTR SS:[ESP+4C] 0041DC7D  |. BF 01000000          MOV EDI,1 0041DC82  |. 3BC7                 CMP EAX,EDI 0041DC84  |. 75 18                JNZ SHORT tvjukebo.0041DC9E 0041DC86  |. 8D8C24 20010000      LEA ECX,DWORD PTR SS:[ESP+120]                  ;  傳字串首地址 0041DC8D  |. 51                   PUSH ECX 0041DC8E  |. E8 8D070000          CALL tvjukebo.0041E420                          ;  很容易發現這裡是對輸入的註冊碼進行計算和比較的--跟進 0041DC93  |. 83C4 04              ADD ESP,4 0041DC96  |. 85C0                 TEST EAX,EAX 0041DC98  |. 75 04                JNZ SHORT tvjukebo.0041DC9E 0041DC9A  |. 897C24 44            MOV DWORD PTR SS:[ESP+44],EDI 0041DC9E  |> 8B5424 10            MOV EDX,DWORD PTR SS:[ESP+10] 0041DCA2  |. 52                   PUSH EDX                                        ; /hKey 0041DCA3  |. FF15 10204300        CALL DWORD PTR DS:[<&ADVAPI32.RegCloseKey>]     ; \RegCloseKey 0041DCA9  |. 395C24 44            CMP DWORD PTR SS:[ESP+44],EBX 0041DCAD     75 28                JNZ SHORT tvjukebo.0041DCD7 0041DCAF  |. A1 148D4400          MOV EAX,DWORD PTR DS:[448D14] 0041DCB4  |. 53                   PUSH EBX                                        ; /Style 0041DCB5  |. 68 40DC4300          PUSH tvjukebo.0043DC40                          ; |Title = "TV Jukebox 2.0" 0041DCBA  |. 8B48 5C              MOV ECX,DWORD PTR DS:[EAX+5C]                   ; | 0041DCBD  |. 51                   PUSH ECX                                        ; |Text 0041DCBE  |. 53                   PUSH EBX                                        ; |hOwner 0041DCBF  |. FF15 58234300        CALL DWORD PTR DS:[<&USER32.MessageBoxA>]       ;  \MessageBoxA  彈出錯誤提示框! 0041DCC5  |. 5F                   POP EDI 0041DCC6  |. 5E                   POP ESI


【具體演算法】跟進上面的那個call
程式碼:
0041E420  /$ 83EC 14              SUB ESP,14 0041E423  |. 56                   PUSH ESI 0041E424  |. 8B7424 1C            MOV ESI,DWORD PTR SS:[ESP+1C] 0041E428  |. 57                   PUSH EDI 0041E429  |. 0FBE46 03            MOVSX EAX,BYTE PTR DS:[ESI+3]                   ;  註冊碼的第四位字元 0041E42D  |. 0FBE4E 0B            MOVSX ECX,BYTE PTR DS:[ESI+B]                   ;  註冊碼的第十二位字元,如果註冊碼長度小於12 這裡是程式中的一個值 0041E431  |. 8D7E 0B              LEA EDI,DWORD PTR DS:[ESI+B]                    ;  字串地址傳送指令,將第12個字元以後的字串首地址寫入edi中 0041E434  |. 03C8                 ADD ECX,EAX                                     ;  將輸入註冊碼的第四位和第十二位相加, 0041E436  |. 81E1 01000080        AND ECX,80000001                                ;  這裡的結果決定下面第二個跳轉的分支 0041E43C  |. 79 05                JNS SHORT tvjukebo.0041E443                     ;  符號位為0時跳 0041E43E  |. 49                   DEC ECX 0041E43F  |. 83C9 FE              OR ECX,FFFFFFFE 0041E442  |. 41                   INC ECX 0041E443  |> 75 38                JNZ SHORT tvjukebo.0041E47D                     ;  根據上面和的奇偶值不同做不同的處理 0041E445  |. 8B4E 08              MOV ECX,DWORD PTR DS:[ESI+8]                    ;  取雙位元組的值 0041E448  |. 8B56 04              MOV EDX,DWORD PTR DS:[ESI+4] 0041E44B  |. 894C24 0C            MOV DWORD PTR SS:[ESP+C],ECX 0041E44F  |. 895424 08            MOV DWORD PTR SS:[ESP+8],EDX 0041E453  |. 0FBE0E               MOVSX ECX,BYTE PTR DS:[ESI] 0041E456  |. C64424 10 00         MOV BYTE PTR SS:[ESP+10],0 0041E45B  |. 8D0C89               LEA ECX,DWORD PTR DS:[ECX+ECX*4]                ;  註冊碼的第一個字元乘5 0041E45E  |. 8D1489               LEA EDX,DWORD PTR DS:[ECX+ECX*4]                ;  註冊碼的第一個字元乘5之後結果再乘5 也就是第一個字元乘25 0041E461  |. 0FBE4E 01            MOVSX ECX,BYTE PTR DS:[ESI+1] 0041E465  |. 8D0C91               LEA ECX,DWORD PTR DS:[ECX+EDX*4]                ;  註冊碼的第二個字元和第一個字元計算的結果相加 0041E468  |. 8D0C89               LEA ECX,DWORD PTR DS:[ECX+ECX*4]                ;  結果乘5 0041E46B  |. 8D1489               LEA EDX,DWORD PTR DS:[ECX+ECX*4]                ;  結果再乘5 0041E46E  |. 0FBE4E 02            MOVSX ECX,BYTE PTR DS:[ESI+2]                   ;  註冊碼的第三位 0041E472  |. 8D0C91               LEA ECX,DWORD PTR DS:[ECX+EDX*4] 0041E475  |. 8D0C89               LEA ECX,DWORD PTR DS:[ECX+ECX*4] 0041E478  |. 8D1489               LEA EDX,DWORD PTR DS:[ECX+ECX*4]                ;  和上面兩位的處理一樣 0041E47B  |. EB 37                JMP SHORT tvjukebo.0041E4B4 0041E47D  |> 33C9                 XOR ECX,ECX 0041E47F  |> 8A17                 /MOV DL,BYTE PTR DS:[EDI]                       ;  取註冊碼的第十二位 0041E481  |. 88540C 08            |MOV BYTE PTR SS:[ESP+ECX+8],DL 0041E485  |. 41                   |INC ECX 0041E486  |. 4F                   |DEC EDI 0041E487  |. 83F9 08              |CMP ECX,8 0041E48A  |.^7C F3                \JL SHORT tvjukebo.0041E47F                     ;  將從第12位往前的8個字串逆序 0041E48C  |. C6440C 08 00         MOV BYTE PTR SS:[ESP+ECX+8],0 0041E491  |. 8D0480               LEA EAX,DWORD PTR DS:[EAX+EAX*4]                ;  註冊碼的第4位字元 0041E494  |. 0FBE4E 02            MOVSX ECX,BYTE PTR DS:[ESI+2]                   ;  註冊碼的第三位字元 0041E498  |. 8D1480               LEA EDX,DWORD PTR DS:[EAX+EAX*4]                ;  第四位字元乘25 0041E49B  |. 8D0491               LEA EAX,DWORD PTR DS:[ECX+EDX*4]                ;  第三位和上面的結果相加 0041E49E  |. 0FBE4E 01            MOVSX ECX,BYTE PTR DS:[ESI+1]                   ;  註冊碼的第二位字元 0041E4A2  |. 8D0480               LEA EAX,DWORD PTR DS:[EAX+EAX*4] 0041E4A5  |. 8D0480               LEA EAX,DWORD PTR DS:[EAX+EAX*4]                ;  上面的結果乘25 0041E4A8  |. 8D0481               LEA EAX,DWORD PTR DS:[ECX+EAX*4] 0041E4AB  |. 8D0480               LEA EAX,DWORD PTR DS:[EAX+EAX*4] 0041E4AE  |. 8D1480               LEA EDX,DWORD PTR DS:[EAX+EAX*4] 0041E4B1  |. 0FBE06               MOVSX EAX,BYTE PTR DS:[ESI] 0041E4B4  |> 8D4C24 08            LEA ECX,DWORD PTR SS:[ESP+8]                    ;  從註冊碼的第5位開始 0041E4B8  |. 8D3C90               LEA EDI,DWORD PTR DS:[EAX+EDX*4]                ;  註冊碼的第四位開始計算 0041E4BB  |. 51                   PUSH ECX 0041E4BC  |. 0FAFFF               IMUL EDI,EDI                                    ;  乘方,取雙位元組 註冊碼的十六進位制 0041E4BF  |. E8 1EA60000          CALL tvjukebo.00428AE2 0041E4C4  |. 8BD0                 MOV EDX,EAX 0041E4C6  |. 0FAFD0               IMUL EDX,EAX 0041E4C9  |. 03D7                 ADD EDX,EDI 0041E4CB  |. 8D4424 0C            LEA EAX,DWORD PTR SS:[ESP+C] 0041E4CF  |. 52                   PUSH EDX                                        ; /<%08x> 0041E4D0  |. 68 E4494400          PUSH tvjukebo.004449E4                          ; |Format = "%08x" 0041E4D5  |. 50                   PUSH EAX                                        ; |s 0041E4D6  |. FF15 80234300        CALL DWORD PTR DS:[<&USER32.wsprintfA>]         ; \轉化為長度為8的十六進位制字串 0041E4DC  |. 83C4 10              ADD ESP,10 0041E4DF  |. 33C0                 XOR EAX,EAX                                     ;  清空累加器 0041E4E1  |> 8A4C06 0C            /MOV CL,BYTE PTR DS:[ESI+EAX+C]                 ;  從註冊碼的第十三位開始比較 0041E4E5  |. 8A5404 08            |MOV DL,BYTE PTR SS:[ESP+EAX+8] 0041E4E9  |. 3ACA                 |CMP CL,DL 0041E4EB  |. 75 0E                |JNZ SHORT tvjukebo.0041E4FB 0041E4ED  |. 40                   |INC EAX 0041E4EE  |. 83F8 08              |CMP EAX,8 0041E4F1  |.^7C EE                \JL SHORT tvjukebo.0041E4E1 0041E4F3  |. 5F                   POP EDI 0041E4F4  |. 33C0                 XOR EAX,EAX 0041E4F6  |. 5E                   POP ESI 0041E4F7  |. 83C4 14              ADD ESP,14 0041E4FA  |. C3                   RETN 0041E4FB  |> 5F                   POP EDI 0041E4FC  |. B8 01000000          MOV EAX,1 0041E501  |. 5E                   POP ESI 0041E502  |. 83C4 14              ADD ESP,14 0041E505  \. C3                   RETN


========================================================================================

【分析總結】



【演算法總結】從上面的分析可以看出 註冊碼的長度必須為>=20個字元 根據第四位和第12位的和(奇偶性)不同採用不同的變換,但是演算法都差不多,然後處理前4個字元,將處理的結果轉化成長度為8的字串,這8個字元就是註冊碼第13位到第20位的字元。

【序號產生器寫法】先讓使用者輸入固定的前12位字元然後,根據使用者的輸入計算出後8個字元,兩個相連線,就是最後的序號。
程式碼:
void CTVjukebox_keygenDlg::OnCalc()  {   // TODO: Add your control notification handler code here   UpdateData(TRUE);   //MessageBox(m_xuhao);   if (strlen(m_xuhao)<12)//避免後面計算時記憶體出錯   {     MessageBox("您輸入的序列號不足12位,請重新輸入!");     return ;   }   int ad=0;   ad = (int)m_xuhao[3]+(int)m_xuhao[11];   if (0 == ad%2) //偶數不跳   {     ad = (int)m_xuhao[0]*25;     ad = ad * 4 + (int)m_xuhao[1];     ad = ad * 25;     ad = ad * 4 + (int)m_xuhao[2];     ad = ad * 25;     ad = ad * 4 + (int)m_xuhao[3];     ad = ad * ad;   }   else   {     ad = (int)m_xuhao[3]*25;     ad = ad * 4 + (int)m_xuhao[2];     ad = ad * 25;     ad = ad * 4 + (int)m_xuhao[1];     ad = ad * 25;     ad = ad * 4 + (int)m_xuhao[0];     ad = ad * ad;   }   m_xuhao.Format(m_xuhao+"%08x",ad); //連線字串   UpdateData(FALSE); }


【後記】註冊軟體我不知道從哪裡來得,破解價值不是很大,難度也巨容易,你要是看到這裡那你虧大了,我只是聊以此文迎接新年!呵呵



========================================================================================



【版權資訊】無



                                                   2005-1-4

相關文章