• 标 题:给TAE!的小礼物---对DISKdata v3.3.2注册算法的分析 (14千字)
  • 作 者:CoolBob[CCG]
  • 时 间:2001-7-13 2:05:23
  • 链 接:http://bbs.pediy.com

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

  • 标 题:对注册机的一点补充 (187字)
  • 作 者:CoolBob[CCG]
  • 时 间:2001-7-13 16:43:54

char date[]="99991299'//注册机中的这个'9999'可以用'CCG!'来代替,这样生成的注册码就能显示Liscensed Copies:CCG!

因为这个是用Setwindowtext来搞定的,所以你可以看看那个调用