時間到了 v1.5 簡單註冊演算法分析 + 序號產生器原始碼(tc2) (9千字)

看雪資料發表於2003-04-12

時間到了 v1.5 簡單註冊演算法分析 + 序號產生器原始碼(tc2)

破解目標:時間到了 1.5
官方主頁:無
軟體簡介:本軟體可以安排X分鐘後“顯示一段資訊”、“執行某個檔案”、“鎖定螢幕”、“關閉Windows”、“迴圈鎖屏”其中一個且只有一個任務。但在非Win9x作業系統下取消了有關鎖屏的功能(即是說在非Win9x系統下不能使用上述的全部功能).“迴圈鎖屏(隔時鎖屏)”只向註冊使用者開放,除此沒有限制。注:在Windows 2000/xp/NT可以使用,但封印了部分功能。
下載地址:http://count.skycn.com/softdown.php?id=11656&url=http://on165-down.skycn.net/down/sjdl.rar

使用工具:FI 2.50、CASPr 1.10、W32Dasm、Ollydbg 1.09b 漢化版

作者:炎之川[BCG]
時間:2003.4.12
主頁:http://skipli.yeah.net/

宣告: 此文僅用於學習及交流,若要轉載請保持文章完整。

這個軟體是昨天在 fixdown 的國產軟體破解更新裡面看到的,只有一個註冊碼,所以就隨便下載了一個,開始時發現其中用了一些浮點指令,本來有些怕,不過把註冊流程跟了一遍才發現那是哄人的……

用 Fileinfo 2.50 徵測,得知軟體是用 ASPack 1.082 加的殼,真是很古老的版本啊~用 CASPr 輕鬆脫掉殼。

使用 W32Dasm 分析,可以找到註冊成功、失敗等提示資訊,稍作分析後用 OD 裝入程式,在 48CCF8 處下斷點,然後 Ctrl+F2 重新載入程式,F9 執行,輸入註冊名及假註冊碼並點選“驗證”:
Name: lovefire
Serial: 787878
注意註冊名必須為8位,這是軟體提示你的。

浮點指令的解釋參考自看雪大哥的 Crack Tutorial 2001


0048CCF8  /. 55            PUSH EBP  //斷在這裡
0048CCF9  |. 8BEC          MOV EBP,ESP
0048CCFB  |. 33C9          XOR ECX,ECX
0048CCFD  |. 51            PUSH ECX
0048CCFE  |. 51            PUSH ECX
0048CCFF  |. 51            PUSH ECX
0048CD00  |. 51            PUSH ECX
0048CD01  |. 51            PUSH ECX
0048CD02  |. 51            PUSH ECX
0048CD03  |. 51            PUSH ECX
0048CD04  |. 51            PUSH ECX
0048CD05  |. 53            PUSH EBX
0048CD06  |. 56            PUSH ESI
0048CD07  |. 57            PUSH EDI
0048CD08  |. 8BF0          MOV ESI,EAX
0048CD0A  |. 33C0          XOR EAX,EAX
0048CD0C  |. 55            PUSH EBP
0048CD0D  |. 68 58CE4800    PUSH un.0048CE58
0048CD12  |. 64:FF30        PUSH DWORD PTR FS:[EAX]
0048CD15  |. 64:8920        MOV DWORD PTR FS:[EAX],ESP
0048CD18  |. 8D55 F4        LEA EDX,DWORD PTR SS:[EBP-C]
0048CD1B  |. 8B86 00040000  MOV EAX,DWORD PTR DS:[ESI+400]
0048CD21  |. E8 B205FAFF    CALL un.0042D2D8
0048CD26  |. 8B45 F4        MOV EAX,DWORD PTR SS:[EBP-C]  //使用者名稱送eaxDWOR
0048CD29  |. E8 0670F7FF    CALL un.00403D34  //這個call取得使用者名稱的長度
0048CD2E  |. 83F8 08        CMP EAX,8  //比較輸入的使用者名稱是否等於8?
0048CD31  |. 74 21          JE SHORT un.0048CD54  //等於則跳轉到下面的註冊碼計算部分
0048CD33  |. 6A 40          PUSH 40
0048CD35  |. 68 68CE4800    PUSH un.0048CE68
0048CD3A  |. 68 70CE4800    PUSH un.0048CE70
0048CD3F  |. A1 E4384900    MOV EAX,DWORD PTR DS:[4938E4]
0048CD44  |. E8 C366FAFF    CALL un.0043340C
0048CD49  |. 50            PUSH EAX                                ; |hOwner
0048CD4A  |. E8 159DF7FF    CALL <JMP.&user32.MessageBoxA>          ; \MessageBoxA  //不等於8,則彈出提示“註冊識別符號長度不足!”
0048CD4F  |. E9 D9000000    JMP un.0048CE2D
0048CD54  |> 8D55 F0        LEA EDX,DWORD PTR SS:[EBP-10]
0048CD57  |. 8B86 00040000  MOV EAX,DWORD PTR DS:[ESI+400]
0048CD5D  |. E8 7605FAFF    CALL un.0042D2D8  //再次取使用者名稱
0048CD62  |. 8B45 F0        MOV EAX,DWORD PTR SS:[EBP-10]  //使用者名稱送eax
0048CD65  |. E8 CA6FF7FF    CALL un.00403D34  //使用者名稱長度
0048CD6A  |. 8BD8          MOV EBX,EAX  //長度送ebx
0048CD6C  |. 85DB          TEST EBX,EBX  //比較ebx是否為0
0048CD6E  |. 7C 32          JL SHORT un.0048CDA2  //小於則跳過迴圈,直接失敗(這裡驗證註冊名是否有輸入?)
0048CD70  |. 43            INC EBX  //ebx是使用者名稱長度,ebx+1=9 作計數器
0048CD71  |. 33FF          XOR EDI,EDI  //edi清零

0048CD73  |> 8D55 EC        /LEA EDX,DWORD PTR SS:[EBP-14]
0048CD76  |. 8B86 00040000  |MOV EAX,DWORD PTR DS:[ESI+400]
0048CD7C  |. E8 5705FAFF    |CALL un.0042D2D8  //再次取使用者名稱
0048CD81  |. 8B45 EC        |MOV EAX,DWORD PTR SS:[EBP-14  //使用者名稱送eax
0048CD84  |. 0FB64438 FF    |MOVZX EAX,BYTE PTR DS:[EAX+EDI-1]  //逐位取使用者名稱
//由於上面將ebx計數器+1,所以第一次迴圈時[EAX+EDI-1]的值為0,什麼也取不到
0048CD89  |. 69C0 43020000  |IMUL EAX,EAX,243  /eax=eax*243,注意第一次迴圈時eax=0,第二次迴圈開始,eax為註冊名的ASCII值
0048CD8F  |. 05 89000000    |ADD EAX,89  //eax=eax+89
0048CD94  |. 8945 E8        |MOV DWORD PTR SS:[EBP-18],EAX  //得出的eax值放入堆疊SS
0048CD97  |. DB45 E8        |FILD DWORD PTR SS:[EBP-18]  //浮點指令!裝入整數到st(0)
0048CD9A  |. DD5D F8        |FSTP QWORD PTR SS:[EBP-8]  //dest <- st(0),即將目的運算元(dest)放入 [EBP-8]
0048CD9D  |. 9B            |WAIT
0048CD9E  |. 47            |INC EDI  //edi+1
0048CD9F  |. 4B            |DEC EBX  //ebx-1
0048CDA0  |.^75 D1          \JNZ SHORT un.0048CD73  //沒有取完就跳回去繼續

第一次迴圈,取得的eax值為0,所以 eax=eax*243+89=0*243+89=89,st(0)=137.00000000000000000
第二次迴圈,取得的eax值為6C(即“l”),所以 eax=eax*243+89=6C*243+89=F4CD,st(0)=62669.000000000000000
…………
第九次迴圈,取得的eax值為65(即“e”),所以 eax=eax*243+89=65*243+89=E4F8,st(0)=58616.00000000000000000

結果這個迴圈的真實作用就是:
(註冊名最後一個字元ASCII值)*243+89
所以只有最後一次的計算有效,前面的計算均無實際用途。

0048CDA2  |> 8D55 E4        LEA EDX,DWORD PTR SS:[EBP-1C]
0048CDA5  |. 8B86 04040000  MOV EAX,DWORD PTR DS:[ESI+404]
0048CDAB  |. E8 2805FAFF    CALL un.0042D2D8  //取假碼
0048CDB0  |. 8B45 E4        MOV EAX,DWORD PTR SS:[EBP-1C]  //假碼放入eax
0048CDB3  |. 50            PUSH EAX  //假碼入棧
0048CDB4  |. DD45 F8        FLD QWORD PTR SS:[EBP-8]  //又一個浮點指令,作用是裝入實數到st(0),此時 [EBP-8] 中放的資料就是上面最後一次迴圈得出的值
0048CDB7  |. 83C4 F4        ADD ESP,-0C
0048CDBA  |. DB3C24        FSTP TBYTE PTR SS:[ESP]                  ; |  dest <- st(0),即將目的運算元(dest)放入 [ESP]
0048CDBD  |. 9B            WAIT                                    ; |
0048CDBE  |. 8D45 E0        LEA EAX,DWORD PTR SS:[EBP-20]            ; |
0048CDC1  |. E8 AEBEF7FF    CALL un.00408C74                        ; \  //得出實數部分,即真實註冊碼,放在[EBP-20]中
0048CDC6  |. 8B55 E0        MOV EDX,DWORD PTR SS:[EBP-20]  //真碼送edx
0048CDC9  |. 58            POP EAX  //假碼出棧
0048CDCA  |. E8 7570F7FF    CALL un.00403E44  //比較真假註冊碼
0048CDCF  |. 75 40          JNZ SHORT un.0048CE11  //不同則註冊失敗
0048CDD1  |. 6A 40          PUSH 40
0048CDD3  |. 68 88CE4800    PUSH un.0048CE88
0048CDD8  |. 68 94CE4800    PUSH un.0048CE94
0048CDDD  |. A1 E4384900    MOV EAX,DWORD PTR DS:[4938E4]
0048CDE2  |. E8 2566FAFF    CALL un.0043340C
0048CDE7  |. 50            PUSH EAX                                ; |hOwner
0048CDE8  |. E8 779CF7FF    CALL <JMP.&user32.MessageBoxA>          ; \MessageBoxA  //這裡彈出註冊失敗的MessageBox

歸根到底,雖然軟體用了一些浮點指令,但根本沒有用到小數部分的計算,全部都是實數部分的計算。

演算法總結:
(註冊名的最後一個字元的ASCII值)*243+89,結果轉換為10進位制就是註冊碼。

註冊資訊儲存在系統目錄下的 vsde.dll 檔案中,這其實是一個ini檔案,註冊後內容如下:
[set]
vnt=1
left=320
top=171
finished=1
reg=1  //註冊後增加此行

至此,時間到了 v1.5 註冊演算法分完成,由於是國產軟體,所以不提供可用的註冊碼。

----------------------------------------------------------
序號產生器原始碼(TC 2.0)

以下是序號產生器原始碼,TC 中似乎不能進行浮點計算,但軟體的演算法部分的浮點指令並不是計算指令,只是資料傳遞和對常量的操作指令,且只用到了實數部分,並沒有用小數,所以姑且按普通的整型寫一下注冊機,想來應該不會有什麼大問題吧^_^

另外由於水平非常有限,寫的程式碼可能比較一般……^_^


/* KeyGen by 炎之川[BCG],2003.4.12 */

/* KeyGen by 炎之川[BCG],2003.4.12,修正於 2003.4.13 */
/* 感謝 wscn 兄的指點 */

#include <stdio.h>
#include <string.h>
main()
{
        char name[80];
        int name_len,i;
        unsigned long int sn1;
        unsigned long int sn2=0;
        clrscr();
        printf("    _/_/_/      _/_/_/    _/_/_/\n  _/    _/  _/        _/\n  _/_/_/    _/        _/  _/_/\n _/    _/  _/        _/    _/\n_/_/_/      _/_/_/    _/_/_/\n\n -= shijiandaole 1.5 KeyGen by lovefire[BCG] =-\n\n\nPlease enter your name: ");
        gets(name);
        name_len=strlen(name);
        if (name_len>7 && name_len<9)
        {
                for (i=0;i<name_len;i++)
                {
                        sn2=name[i]*0x243+0x89;
                }
                printf("\nok, try this serial: %u\n",sn2);
                printf("\n\nNOTE: serial only for test!");
                printf("\nIf you like it, buy it to support the soft's author!");
        }
                else
                {
                        printf("\nReg Name MUST have 8 char. ;)\n");
                }
        printf("\n\nhave fun^^\nwelcome to http://skipli.yeah.net/");
        getch();
}


----------------------------------------------------------

炎之川
屬於中國破解組織BCG(Beginner's Cracking Group)

    _/_/_/      _/_/_/    _/_/_/
  _/    _/  _/        _/
  _/_/_/    _/        _/  _/_/
_/    _/  _/        _/    _/
_/_/_/      _/_/_/    _/_/_/

相關文章