KEYGENNING4NEWBIES #7破解過程+序號產生器 (6千字)

看雪資料發表於2001-08-21

KEYGENNING4NEWBIES #7破解過程+序號產生器

前兩天TAE!讓我看看KEYGENNING4BEWBIES 的#3,那個東西很簡單,做了它的序號產生器
後來看雪給了我一個代理伺服器地址,使我能夠到國外的一些破解站轉轉,於是我找
到了這個NUMBER 7

KEYGENNING4NEWBIES有7個KEYGENME(其中第二個有問題),這些KEYGENME的
作用就是讓初學者練習寫KEYGEN,其中有的是比較簡單的(如#1,#3)
這次我要寫的KEYGENME #7用了MD5演算法(相應的資料可以在http://www.rsa.com找到)
下載地址:http://www.leelouonline.com/users/bofh/k4n/k4n7.zip
使用工具:TRW2000
難度    :5(10為最難,0為最易)
CRACKER :偽裝者[BCG&&CCG]
目的    :學習破解一週年紀念
目標    : 做出這個的序號產生器,並且使初學者看完之後能有所收穫
過程如下:
執行KEYGENNING4NEWBIES #7(以下簡稱"#7")
輸入使用者名稱,註冊碼
使用者名稱:cracknow
註冊碼:121212
啟動TRW2000
BPX HMEMCPY
按"OK"鍵,被攔截
一次PMODULE後來到0167:00401B8A這裡
BC *並用F9在這裡下新的斷點
0167:00401B8A  CMP      EAX,BYTE +10 -------------->輸入的註冊碼的位數和16比較
0167:00401B8D  JNZ      00401BA8                    不是16就跳(呵呵~~想起一位大客的口訣
0167:00401B8F  PUSH    BYTE +64                    "一條就死,九筒便和"不過如果這樣的話
0167:00401B91  PUSH    DWORD 0040603C              就不能叫KEYGEN ME了~~)所以從新輸入注
0167:00401B96  PUSH    DWORD 03E8                  冊碼,新註冊碼為:1212121212121212
0167:00401B9B  PUSH    ESI
0167:00401B9C  CALL    EDI                     
0167:00401B9E  CALL    00401D90------------------>將輸入的註冊碼轉成十六進位制
0167:00401BA3  CALL    00401C70------------------>關鍵的CALL 了,一定要進去!
0167:00401BA8  POP      EDI
0167:00401BA9  XOR      EAX,EAX
0167:00401BAB  POP      ESI
0167:00401BAC  RET      10

***********************************************
0167:00401CAF  LEA      EAX,[EBP-78]-------------->進入之後不是到這裡,但上面的我覺得             
0167:00401CB2  PUSH    EAX                        都不重要,所以沒有U下來
0167:00401CB3  CALL    00401A10                  將使用者名稱進行進行標準的MD5轉換(不重要
0167:00401CB8  ADD      ESP,BYTE +08              不用跟,跟也看不明白~~呵呵~~~)
0167:00401CBB  MOV      EBX,[EBP-14]-------------->從這裡開始你必須要集中精力了,因為如
0167:00401CBE  MOV      [EBP-04],EBX          |  果你要做這個的序號產生器,那麼底下的每一       
0167:00401CC1  XOR      EBX,[EBP-0C]      |  行你都要明白是做什麼用的!
0167:00401CC4  MOV      [00406CE4],EBX          |  我們設使用者名稱經過MD5轉換後的結果為S
0167:00401CCA  MOV      EBX,[EBP-10]            | S[0]~~S[3]分別表示S的4個部分,這些
0167:00401CCD  MOV      [EBP-18],EBX            | 行的作用就是使[ebp-4]=[ebp-14]=s[0]
0167:00401CD0  MOV      EBX,[EBP-0C]            |  [ebp-10]=[ebp-18]=s[1],[ebp-c]=[ebp-
0167:00401CD3  MOV      [EBP-1C],EBX            |  1c]=s[2],[ebp-8]=[ebp-20]=s[3],另外
0167:00401CD6  MOV      EBX,[EBP-08]            | 再設一個N,N=S[0]^S[2];
0167:00401CD9  MOV      [EBP-20],EBX-------------
0167:00401CDC  MOV      EBX,[004060A0]----->註冊碼的前8個和後8個分別放入ebp-80,ebp-7c
0167:00401CE2  MOV      [EBP-7C],EBX      | 這時你會發現如果註冊碼用1212121212121212這
0167:00401CE5  MOV      EBX,[004060A4]    | 樣前後相同的數回造成不方便觀察,所以退出,將
0167:00401CEB  MOV      [EBP-80],EBX------->註冊碼改成1212121234343434 繼續
0167:00401CEE  MOV      ECX,[EBP-7C]------------->從這裡開始是關鍵中的關鍵!!!!!!
0167:00401CF1  SHL      ECX,04                  | 最好用筆抄下來慢慢分析
0167:00401CF4  ADD      ECX,[EBP-1C]            | 這些行將輸入的註冊碼和字串s做
0167:00401CF7  MOV      EDX,[EBP-7C]            | 運算,最後的結果分別和0x6779656b
0167:00401CFA  ADD      EDX,[00406CE4]          | 0x656d6e65比較(呵呵~~就是keygenme)
0167:00401D00  XOR      ECX,EDX                |
0167:00401D02  MOV      EAX,[EBP-7C]            |
0167:00401D05  SHR      EAX,05                  |
0167:00401D08  ADD      EAX,[EBP-20]            |
0167:00401D0B  XOR      ECX,EAX                |
0167:00401D0D  MOV      EDX,[EBP-80]            |
0167:00401D10  SUB      EDX,ECX                |
0167:00401D12  MOV      [EBP-80],EDX            | ********注意這裡!!!********
0167:00401D15  MOV      EAX,[EBP-80]            |
0167:00401D18  SHL      EAX,04                  |
0167:00401D1B  ADD      EAX,[EBP-04]            |
0167:00401D1E  MOV      ECX,[EBP-80]            |
0167:00401D21  ADD      ECX,[00406CE4]          |
0167:00401D27  XOR      EAX,ECX                |
0167:00401D29  MOV      EDX,[EBP-80]            |
0167:00401D2C  SHR      EDX,05                  |
0167:00401D2F  ADD      EDX,[EBP-18]            |
0167:00401D32  XOR      EAX,EDX                |
0167:00401D34  MOV      ECX,[EBP-7C]            |
0167:00401D37  SUB      ECX,EAX                |
0167:00401D39  MOV      [EBP-7C],ECX------------->
0167:00401D3C  CMP      DWORD [EBP-7C],6779656B-->跳就死!
0167:00401D43  JNZ      00401D69                |
0167:00401D45  CMP      DWORD [EBP-80],656D6E65 |
0167:00401D4b JNZ      00401D69----------------->跳就死!
現在開始對那個"關鍵中的關鍵"分析
比較的是[ebp-7c]與0x6779656B,[ebp-80]與0x656D6E65,所以如果註冊碼正確那麼這兩處在比較的時候
就分別應該為0x6779656B,0x656D6E65,看看上面的這行0167:00401D12  MOV      [EBP-80],EDX
將edx放入[ebp-80]中,那麼這個EDX就應該等於0x656D6E65,並且這行0167:00401D12以後的[ebp-80]
都要等於0x656D6E65!利用這點我們可以反推出401D34行中的ecx,它就是正確的註冊碼的第二部分,
然後再利用這個反推出401D0D中的edx,這個就是正確註冊碼的第一部分
得到結果
使用者名稱:cracknow
註冊碼:f7afdc2f25d32e18

序號產生器如下(VC)

#include <stdio.h>
#include <stdlib.h>
#include "md5lib.h"
void main()
{unsigned long s[4],k[2],ea,eb,ec,ed,n,sn1,sn2;
  char *text;
  int i,j;
  int tmp[16],d[2];
printf("*********KEYGENME #7*********\nThis keygen is made by Pretender\nPlease input your name : ");
k[0]=0x656d6e65;k[1]=0x6779656b;
gets(text);
text=MDString(text);                                                //使用者名稱做MD5
for(i=0;i<16;i++)                                                  //將結果分為s[0]~s[3]
{d[0]=text[i*2];d[1]=text[i*2+1];                                  //四個部分
for(j=0;j<2;j++)
  {if(d[j]>47&&d[j]<58) d[j]=d[j]-48;
  if(d[j]>64&&d[j]<71) d[j]=d[j]-55;
  if(d[j]>96&&d[j]<103) d[j]=d[j]-87;
  }
  tmp[i]=d[0]*16+d[1];
  if(i%4==3)
  s[i/4]=tmp[i]*65536*256+tmp[i-1]*65536+tmp[i-2]*256+tmp[i-3];
}

n=s[0]^s[2];                            
//printf("%lx\n",n);                        //反推的過程
ea=k[0];
ea<<=4;
ea+=s[0];
ec=k[0];
ec+=n;
//printf("%lx",ea);
ea^=ec;
ed=k[0];
ed>>=5;
ed+=s[1];
ea^=ed;
ec=ea+k[1];
sn2=ec;
ec<<=4;
ec+=s[2];
ed=sn2;
ed+=n;
ec^=ed;
ea=sn2;
//printf("%lx",ea);
ea/=32;
ea+=s[3];
ec^=ea;
ed=ec+k[0];
printf("Your Register code is  : %08lx%08lx",ed,sn2);      //輸出結果
  printf("\n *****************************      ---    ---    ---\n *Welcome to WWW.CRACKNOW.COM*      /      /      / --\n *****************************      ---    ---    --/\n");

}

相關文章