給TAE!的小禮物---對DISKdata v3.3.2註冊演算法的分析 (14千字)

看雪資料發表於2001-07-13

DISKdata v3.3.2 (Write a KeyGen use TC2.0)

本文作者:CoolBob[CCG] * [CCG] stands for cHINA cRACKING gROUP
          coolbob@21cn.com QQ:1618778
所用工具:SoftICE4.05,DeDe v2.50,Turbo C 2.0
目標網址:http://www.digallery.com/diskdata/

前言:
   一日TAE!大蝦問小弟對DISKdata這個東東的註冊演算法有沒有興趣,偶當時正與MM聊的火熱,也沒在意:) 後來收信的時候看到了TAE!的信才想起來。
   小弟在匆忙中完成此篇,有什麼錯誤的地方,歡迎廣大的高手為小弟指正 ;d
正文:執行DISKdata後,點選右邊那個About頁,在Licensed to與License key文字框中分別填入姓名與註冊碼。不要急著點選Set按鈕,觀察一番先。發現下面有個Licensed copies:None Expiration:None,很明顯這個程式有很多種註冊方式!現在按Ctrl+D彈出SoftICE,下BPX Hmemcpy.按F5回到系統中來。再點選Set按鈕.啪~SoftICE露出了她那醜陋的臉^O^。12次F12後(為什麼是12次呢,因為Delphi 5寫的GetText(),一般要按12次,嘿嘿,不信你試試!)來到了這裡:
* Reference to: controls.TControl.GetText(TControl):System.String;
|
00490ED6  E8E5F7F9FF            call    004306C0
00490EDB  8B45F0                mov    eax, [ebp-$10]    //d eax,License key
00490EDE  8D55F4                lea    edx, [ebp-$0C]

* Reference to: sysutils.Trim(System.AnsiString):System.AnsiString;
|
00490EE1  E82E77F7FF            call    00408614
00490EE6  8B45F4                mov    eax, [ebp-$0C]
00490EE9  8D4DFC                lea    ecx, [ebp-$04]

* Possible String Reference to: 'DISKdata'
|
00490EEC  BA9C134900            mov    edx, $0049139C

|
00490EF1  E8CA05FEFF            call    004714C0    //第一個比較點,F8跟進
00490EF6  84C0                  test    al, al    //出來時al=0就886
00490EF8  0F84C7030000          jz      004912C5
--------------------------------
在DeDe中雙擊00490EF1處,
…… …… ……
00471559  8B5DF0                mov    ebx, [ebp-$10]
0047155C  03DB                  add    ebx, ebx
0047155E  4B                    dec    ebx
0047155F  8D4301                lea    eax, [ebx+$01]
00471562  D1F8                  sar    eax, 1
00471564  7903                  jns    00471569
00471566  83D000                adc    eax, +$00
00471569  99                    cdq
0047156A  F7FE                  idiv    esi
0047156C  8BC2                  mov    eax, edx

|
0047156E  E841FFFFFF            call    004714B4
00471573  F7EE                  imul    esi
00471575  50                    push    eax
00471576  8D4301                lea    eax, [ebx+$01]
00471579  D1F8                  sar    eax, 1
0047157B  7903                  jns    00471580
0047157D  83D000                adc    eax, +$00
00471580  99                    cdq
00471581  F7FE                  idiv    esi
00471583  58                    pop    eax
00471584  2BD0                  sub    edx, eax
00471586  52                    push    edx
00471587  8D45DC                lea    eax, [ebp-$24]
0047158A  B9C4164700            mov    ecx, $004716C4
0047158F  8B55F8                mov    edx, [ebp-$08]

* Reference to: system.@LStrCat3;
|
00471592  E85529F9FF            call    00403EEC
00471597  8B45DC                mov    eax, [ebp-$24]
0047159A  5A                    pop    edx
0047159B  8A4410FF              mov    al, byte ptr [eax+edx-$01]    //從一個固定的字串'DISKdata-'中取數'D'放入al中,以後依次迴圈
0047159F  8845EF                mov    [ebp-$11], al
004715A2  BAC8164700            mov    edx, $004716C8
004715A7  8D45D4                lea    eax, [ebp-$2C]

* Reference to: system.@PStrCpy;
|
004715AA  E88115F9FF            call    00402B30
004715AF  8D45D0                lea    eax, [ebp-$30]

* Reference to MainForm
|
004715B2  8B55FC                mov    edx, [ebp-$04]
004715B5  8A541AFF              mov    dl, byte ptr [edx+ebx-$01]    //從我們輸入的License key中取一個放入dl中
004715B9  885001                mov    [eax+$01], dl        //儲存dl
004715BC  C60001                mov    byte ptr [eax], $01
004715BF  8D55D0                lea    edx, [ebp-$30]
004715C2  8D45D4                lea    eax, [ebp-$2C]
004715C5  B102                  mov    cl, $02

* Reference to: system.@PStrNCat;
|
004715C7  E83415F9FF            call    00402B00
004715CC  8D55D4                lea    edx, [ebp-$2C]
004715CF  8D45CC                lea    eax, [ebp-$34]

* Reference to: system.@PStrCpy;
|
004715D2  E85915F9FF            call    00402B30
004715D7  8D45D0                lea    eax, [ebp-$30]

* Reference to MainForm
|
004715DA  8B55FC                mov    edx, [ebp-$04]
004715DD  8A141A                mov    dl, byte ptr [edx+ebx]    //接著取License key中的數
004715E0  885001                mov    [eax+$01], dl
004715E3  C60001                mov    byte ptr [eax], $01
004715E6  8D55D0                lea    edx, [ebp-$30]
004715E9  8D45CC                lea    eax, [ebp-$34]
004715EC  B103                  mov    cl, $03

* Reference to: system.@PStrNCat;
|
004715EE  E80D15F9FF            call    00402B00    //連線這兩個數字,假設我們輸入的License key為'12345',那麼連線後為$12
004715F3  8D55CC                lea    edx, [ebp-$34]
004715F6  8D45D8                lea    eax, [ebp-$28]

* Reference to: system.@LStrFromString(String;ShortString);
|          or: system.@WStrFromString(WideString;ShortString);
|
004715F9  E84628F9FF            call    00403E44
004715FE  8B45D8                mov    eax, [ebp-$28]

* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
00471601  E86E71F9FF            call    00408774    //字串轉化為十六進位制$12
00471606  8BD0                  mov    edx, eax    //dl就是轉化好的數,12->0x12
00471608  8A45EF                mov    al, byte ptr [ebp-$11]    //al='D'
0047160B  32D0                  xor    dl, al    //異或
0047160D  8D45E8                lea    eax, [ebp-$18]

* Reference to: system.@LStrFromChar(String;Char);
|          or: system.@LStrFromWChar(String;WideChar);
|          or: system.@WStrFromChar(WideString;Char);
|          or: system.@WStrFromWChar(WideString;WideChar);
|
00471610  E8B327F9FF            call    00403DC8
00471615  8D45E4                lea    eax, [ebp-$1C]
00471618  8B55E8                mov    edx, [ebp-$18]

* Reference to: system.@LStrCat;
|
0047161B  E88828F9FF            call    00403EA8
00471620  FF45F0                inc    dword ptr [ebp-$10]
00471623  4F                    dec    edi        //edi=LEN(License key)
00471624  0F852FFFFFFF          jnz    00471559    //迴圈
…… …… ……
* Reference to: system.@LStrLen:Integer;
|          or: system.@DynArrayLength;
|          or: system.DynArraySize(Pointer):Integer;
|
00471649  E85228F9FF            call    00403EA0
0047164E  8B55E4                mov    edx, [ebp-$1C]
00471651  8A5C02FF              mov    bl, byte ptr [edx+eax-$01]    //bl=上面迴圈後算出來的最後一位數
00471655  8B45F4                mov    eax, [ebp-$0C]
00471658  8B00                  mov    eax, [eax]

|
0047165A  E86D000000            call    004716CC    //除最後一位外,其它的相加,和&0xff
0047165F  3AD8                  cmp    bl, al    //比較
00471661  7404                  jz      00471667    //不等就886
…… …… …… 
call    004716CC 如下:
…… …… …… 
004716F8  BA01000000            mov    edx, $00000001
004716FD  8B4DFC                mov    ecx, [ebp-$04]
00471700  0FB64C11FF            movzx  ecx, byte ptr [ecx+edx-$01]    //取上面那個迴圈(EIP:0047160B) XOR後的結果
00471705  81E3FF000000          and    ebx, $000000FF
0047170B  03CB                  add    ecx, ebx        //連加
0047170D  81E1FF000000          and    ecx, $000000FF
00471713  8BD9                  mov    ebx, ecx
00471715  42                    inc    edx
00471716  48                    dec    eax
00471717  75E4                  jnz    004716FD
…… …… ……
* Reference to: controls.TControl.GetText(TControl):System.String;
|
00490F37  E884F7F9FF            call    004306C0
00490F3C  8B45DC                mov    eax, [ebp-$24]    //取姓名
00490F3F  8D55E0                lea    edx, [ebp-$20]

* Reference to: sysutils.UpperCase(System.AnsiString):System.AnsiString;
|
00490F42  E88974F7FF            call    004083D0        //將小寫字母轉化為大寫
00490F47  8B45E0                mov    eax, [ebp-$20]
00490F4A  8D55E4                lea    edx, [ebp-$1C]

…… …… ……
|
00490F55  E87207FEFF            call    004716CC
00490F5A  25FF000000            and    eax, $000000FF
00490F5F  3BF0                  cmp    esi, eax        //esi=上面那個迴圈XOR後的結果的第5、6兩個個數字轉化為十六進位制後的數,eax=姓名的所有字母大寫後的AScii碼之和
00490F61  0F8552030000          jnz    004912B9        //不等就886
…… …… ……

* Reference to: system.@LStrCmp;
|
00490FBF  E8EC2FF7FF            call    00403FB0        //比較。上面那個迴圈XOR後的結果的第一、二個數字與姓名的第一、二個字母比較
00490FC4  0F85EF020000          jnz    004912B9        //不等就886
00490FCA  8D45C0                lea    eax, [ebp-$40]
00490FCD  50                    push    eax
00490FCE  8D55B8                lea    edx, [ebp-$48]


…… …… ……
* Reference to: system.@LStrCmp;
|
00491041  E86A2FF7FF            call    00403FB0        //比較。上面那個迴圈XOR後的結果的第三、四個數字與姓名的倒數第二、一個字母比較
00491046  0F856D020000          jnz    004912B9
…… …… ……
下面的這段程式碼就是把上面那個迴圈XOR後的結果中的第十一位至第十四位與系統時間比較了
* Reference to: sysutils.StrToInt(System.AnsiString):System.Integer;
|
00491094  E8DB76F7FF            call    00408774    //字串轉化為整數
00491099  66B90100              mov    cx, $0001
0049109D  5A                    pop    edx

* Reference to: sysutils.EncodeDate(System.Word;System.Word;System.Word):System.TDateTime;
|
0049109E  E8C986F7FF            call    0040976C    //經過一番運算後
004910A3  DD5D98                fstp    qword ptr [ebp-$68]    //以浮點數儲存,在SoftICE下wf
004910A6  9B                    wait

* Reference to: sysutils.Date:System.TDateTime;
|
004910A7  E83089F7FF            call    004099DC    //取系統時間,2001=0x7D1,經過運算
004910AC  DC5D98                fcomp  qword ptr [ebp-$68] //與剛才的那個數比較
004910AF  DFE0                  fstsw  ax    
004910B1  9E                    sahf
004910B2  0F83F5010000          jnb    004912AD    //if jump,Bad guy!
004910B8  8D4594                lea    eax, [ebp-$6C]
004910BB  50                    push    eax
004910BC  B904000000            mov    ecx, $00000004
004910C1  BA07000000            mov    edx, $00000007
004910C6  8B45FC                mov    eax, [ebp-$04]
…… …… ……
* Possible String Reference to: '9999'
|
004910D1  BAC8134900            mov    edx, $004913C8

* Reference to: system.@LStrCmp;
|
004910D6  E8D52EF7FF            call    00403FB0    //這裡是比較,如果面那個迴圈XOR後的結果的第7~10四個數字要是等於'9999'的話,那麼註冊欄下面的Licensed copies:會顯示Site!
004910DB  7512                  jnz    004910EF     //注意上面那個'9999'

* Possible String Reference to: 'Site'            //還有這個'Site'
|
004910E3  BAD8134900            mov    edx, $004913D8

* Reference to: controls.TControl.SetText(TControl;System.String);
|
004910E8  E803F6F9FF            call    004306F0
004910ED  EB24                  jmp    00491113
004910EF  8D4590                lea    eax, [ebp-$70]
004910F2  50                    push    eax
004910F3  B904000000            mov    ecx, $00000004
004910F8  BA07000000            mov    edx, $00000007
004910FD  8B45FC                mov    eax, [ebp-$04]

…… …… ……
* Possible String Reference to: '12/99'        //注意這個'12/99'
|
0049115A  BAF4134900            mov    edx, $004913F4

* Reference to: system.@LStrCmp;
|
0049115F  E84C2EF7FF            call    00403FB0//這裡是比較,如果面那個迴圈XOR後的結果的第11~14四個數字要是等於'1299'的話,那麼註冊欄下面的Expiration:會顯示None!也就是永不過期!
00491164  7512                  jnz    00491178

* Reference to control TMainForm.ExpirationLabel : TLabel
|
00491166  8B8360040000          mov    eax, [ebx+$0460]

* Possible String Reference to: 'None'        //還有這個'None'
|
0049116C  BA04144900            mov    edx, $00491404

* Reference to: controls.TControl.SetText(TControl;System.String);
|
00491171  E87AF5F9FF            call    004306F0
00491176  EB63                  jmp    004911DB
00491178  8D857CFFFFFF          lea    eax, [ebp+$FFFFFF7C]
0049117E  50                    push    eax
0049117F  B902000000            mov    ecx, $00000002
00491184  BA0B000000            mov    edx, $0000000B
00491189  8B45FC                mov    eax, [ebp-$04]
…… …… ……
下面還有一段程式碼就是對登錄檔的操作了。忽略
---------DISKdata.reg----------------------
REGEDIT4

[HKEY_CURRENT_USER\Software\Digital Information Gallery\DiskData\Settings]
"Licensee"="CoolBob[CCG]"
"Key"="070614165C544D58147D7861725D3D"

--------------------------------------
:),還是帖個序號產生器,嘿嘿。
---------------------------------------



#include<stdio.h>
#include<ctype.h>
#include<string.h>
main(){
char name[60];
char code[15];
int n=0,i,result_xor=0;
char str[]="DISKdata-DISKdata-";
char date[]="99991299";    /* you can change this for try other License 12 stands for month */
clrscr();        /* 99 stands for 2099 year,Max year in our Windows98,9999 for 'Site' */
printf("DISKdata  v3.3.2 keymaker by CoolBob[CCG]\n");
printf("written at 2001-7-13\n");
printf("Enter your name:");
gets(name);
strupr(name);
for(i=0;i<=1;i++)
code[i]=str[i]^name[i];
code[2]=str[2]^name[strlen(name)-2];
code[3]=str[3]^name[strlen(name)-1];
for(i=0;i<strlen(name);i++)
n=n+name[i];
n=n&0xff;
if (n/0x10>9) code[4]=n/0x10+0x37^str[4];
else
code[4]=n/0x10+0x30^str[4];
if (n%0x10>9) code[5]=n%0x10+0x37^str[5];
else
code[5]=n%0x10+0x30^str[5];
for(i=6;i<14;i++)
code[i]=str[i]^date[i-6];
result_xor=name[0]+name[1]+name[strlen(name)-1]+name[strlen(name)-2];
result_xor=result_xor+(code[4]^str[4])+(code[5]^str[5]);
for(i=0;i<8;i++)
result_xor=result_xor+date[i];
result_xor=result_xor&0xff;
code[14]=result_xor^str[14];
printf("License key is:");
for(i=0;i<15;i++)
if (code[i]<=0xF) printf("0%X",code[i]);
else
printf("%X",code[i]);
printf("\npress any key  to exit!\n");
getch();
}





-------------------------------------------------------------------------------------
2001-7-13 written by CoolBob

相關文章