史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > Hacker/Cracker 及加解密技術文件
忘記密碼?
註冊帳號 論壇說明 標記討論區已讀

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2004-01-10, 10:31 PM   #1
psac
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 製作mIRC6.02註冊機

暑假裡迷起了irc,所以拿到了mIRC就順便把它keygen了。我用的是mIRC 6.02版。此軟體採用的是用戶名/註冊碼的保護,在軟體的說明 表單裡有註冊選項。
首先我們看看基本的註冊情況。填好相關的註冊碼和用戶名之後,點註冊會發現提示錯誤。之後自動清除了輸入的內容,但是還是可以繼續註冊。瞭解這些就夠了。
現在開始我們的破解之旅。
輸入好註冊碼和用戶名之後,進入trw,下斷點,bpx GetDlgItemTextA,bpx GetWindowTextA。
因為這兩個是常用的獲取EDIT控件文本內容的函數啦。
點註冊,發現沒有攔截下來。
那麼就有兩種可能性了:第一,程序採用了其他的方法獲得文本內容,比如除了剛才的兩個斷點之外,還可以向EDIT控件傳送WM_GETTEXT消息來獲得文本;第二,程序是用delphi編寫的,有自己獨立的獲取方式而不依靠windows提供的函數。
無論是哪種可能性,都可以用一種方法來解決,那就是下斷點bpx hmemcpy。這個號稱是9x平台下的萬能斷點,只要是輸入註冊碼的,都可以用這個斷點來攔截。
下斷點,點註冊。終於攔截下來了。攔下後,下指令pmodule,回到mIRC程序裡,發現我們在call SendDlgItemMessageA的下面,原來它是用這個函數給對話視窗裡的EDIT控件傳送WM_GETTEXT消息。

016F:004C688D 68A8A85700 PUSH DWORD 0057A8A8 <==============以後名字存放的地點
016F:004C6892 68E7030000 PUSH DWORD 03E7
016F:004C6897 6A0D PUSH BYTE +0D <====================WM_GETTEXT的值
016F:004C6899 6883000000 PUSH DWORD 83
016F:004C689E FF7508 PUSH DWORD [EBP+08]
016F:004C68A1 E8284B0900 CALL `USER32!SendDlgItemMessageA`
016F:004C68A6 688FAC5700 PUSH DWORD 0057AC8F <=======+=======pmodule後我們就在這裡了
016F:004C68AB 68E7030000 PUSH DWORD 03E7 |_______以後我們輸入的註冊碼
016F:004C68B0 6A0D PUSH BYTE +0D 存放的地點
016F:004C68B2 6882000000 PUSH DWORD 82
016F:004C68B7 FF7508 PUSH DWORD [EBP+08]
016F:004C68BA E80F4B0900 CALL `USER32!SendDlgItemMessageA`
016F:004C68BF 688FAC5700 PUSH DWORD 0057AC8F <==============註冊碼作為參數二
016F:004C68C4 68A8A85700 PUSH DWORD 0057A8A8 <==============姓名作為參數一
016F:004C68C9 E88FFBFFFF CALL 004C645D <====================使用函數(關鍵的函數)!!
016F:004C68CE 85C0 TEST EAX,EAX <====================測試函數返回值
016F:004C68D0 0F84B7000000 JZ NEAR 004C698D <===============返回值如果等於0
就跳走(出錯的地方)

從我們看到的程式碼來看,004c645d處函數肯定是產生註冊碼並且進行比較的函數.因此我們應當跟進去,走到004C68C9的時候,F8跟進去.看到:
016F:004C645D 55 PUSH EBP
016F:004C645E 8BEC MOV EBP,ESP
016F:004C6460 53 PUSH EBX
016F:004C6461 56 PUSH ESI
016F:004C6462 57 PUSH EDI
016F:004C6463 8B750C MOV ESI,[EBP+0C]
016F:004C6466 8B5D08 MOV EBX,[EBP+08]
016F:004C6469 BF440E5800 MOV EDI,00580E44
016F:004C646E 6804010000 PUSH DWORD 0104
016F:004C6473 6A00 PUSH BYTE +00
016F:004C6475 57 PUSH EDI
016F:004C6476 E8D55C0800 CALL 0054C150
016F:004C647B 83C40C ADD ESP,BYTE +0C
016F:004C647E 6804010000 PUSH DWORD 0104
016F:004C6483 6A00 PUSH BYTE +00
016F:004C6485 68480F5800 PUSH DWORD 00580F48
016F:004C648A E8C15C0800 CALL 0054C150
016F:004C648F 83C40C ADD ESP,BYTE +0C
016F:004C6492 56 PUSH ESI
016F:004C6493 57 PUSH EDI
016F:004C6494 8BF7 MOV ESI,EDI
016F:004C6496 8BFB MOV EDI,EBX
016F:004C6498 33C0 XOR EAX,EAX
016F:004C649A 83C9FF OR ECX,BYTE -01
016F:004C649D F2AE REPNE SCASB
016F:004C649F F7D1 NOT ECX
016F:004C64A1 2BF9 SUB EDI,ECX
016F:004C64A3 87F7 XCHG ESI,EDI
016F:004C64A5 8BC7 MOV EAX,EDI
016F:004C64A7 8BD1 MOV EDX,ECX
016F:004C64A9 C1E902 SHR ECX,02
016F:004C64AC F3A5 REP MOVSD
016F:004C64AE 8BCA MOV ECX,EDX
016F:004C64B0 83E103 AND ECX,BYTE +03
016F:004C64B3 F3A4 REP MOVSB
016F:004C64B5 5F POP EDI
016F:004C64B6 5E POP ESI
016F:004C64B7 56 PUSH ESI
016F:004C64B8 57 PUSH EDI
016F:004C64B9 8BFE MOV EDI,ESI
016F:004C64BB BE480F5800 MOV ESI,00580F48
016F:004C64C0 33C0 XOR EAX,EAX
016F:004C64C2 83C9FF OR ECX,BYTE -01
016F:004C64C5 F2AE REPNE SCASB
016F:004C64C7 F7D1 NOT ECX
016F:004C64C9 2BF9 SUB EDI,ECX
016F:004C64CB 87F7 XCHG ESI,EDI
016F:004C64CD 8BC7 MOV EAX,EDI
016F:004C64CF 8BD1 MOV EDX,ECX
016F:004C64D1 C1E902 SHR ECX,02
016F:004C64D4 F3A5 REP MOVSD
016F:004C64D6 8BCA MOV ECX,EDX
016F:004C64D8 83E103 AND ECX,BYTE +03
016F:004C64DB F3A4 REP MOVSB
016F:004C64DD 5F POP EDI
016F:004C64DE 5E POP ESI
016F:004C64DF 68480F5800 PUSH DWORD 00580F48
016F:004C64E4 57 PUSH EDI
016F:004C64E5 E880FEFFFF CALL 004C636A <==================call 後面緊跟test和跳轉的
016F:004C64EA 85C0 TEST EAX,EAX 就要留意了
016F:004C64EC 740A JZ 004C64F8 <===eax=0就跳到失敗,所以在函數返回前不能
讓eax=0

016F:004C64EE B801000000 MOV EAX,01 <========令eax=1,然後跳轉,不遠處就返回了,
016F:004C64F3 E991000000 JMP 004C6589 回到上面004c68ce的地方,上面要求
eax不等於0就註冊成功,這裡是1正好
滿足,所以這個004664E5大有文章.

前面的一大票程式碼看起來很難分析,其實暫時可以不管,因為這還是我們第一遍跟蹤.第一遍只要大概掌握程式碼的情況就可以了.我們注意到004C64E5 處的call和後面的test jz又構成了一個使用函數然後比較返回值的情況.而且它後面有mov eax,1 jmp 004c6589.這就可以肯定是判斷註冊碼是否合法的函數了.看看在call前面push 入棧的是哪些東西.在執行到0x4c64e4的時候,下指令d 580f48 可以看到註冊碼,d edi 看到名字.所以,這更加肯定了我們的推測,004c636a處的函數就是核心.在跟進去之前要記住,不能讓eax=0,不然就是註冊失敗的標誌.好了跟進來.

016F:004C636A 55 PUSH EBP
016F:004C636B 8BEC MOV EBP,ESP
016F:004C636D 83C4F4 ADD ESP,BYTE -0C
016F:004C6370 53 PUSH EBX
016F:004C6371 56 PUSH ESI
016F:004C6372 57 PUSH EDI
016F:004C6373 8B750C MOV ESI,[EBP+0C]
016F:004C6376 FF7508 PUSH DWORD [EBP+08] <==========d *(ebp+8)發現這是名字
016F:004C6379 E8525F0800 CALL 0054C2D0 <====這個函數是幹什麼的?
016F:004C637E 59 POP ECX <=====執行完函數到了這裡,看看eax裡是什麼?是名字的
016F:004C637F 83F805 CMP EAX,BYTE +05 <==比較名字是不是大於5個字母 長度.
016F:004C6382 7307 JNC 004C638B
016F:004C6384 33C0 XOR EAX,EAX <==小於5就把eax清零,返回,就註冊失敗了.
016F:004C6386 E9C9000000 JMP 004C6454
016F:004C638B 6A2D PUSH BYTE +2D <==0x2d就是字串"-"
016F:004C638D 56 PUSH ESI <==註冊碼
016F:004C638E E89D5E0800 CALL 0054C230 <==這個函數跟蹤後發現是返回"-"在註冊碼中
016F:004C6393 83C408 ADD ESP,BYTE +08 的位置.如果你輸入的註冊碼不含"-"就失敗
016F:004C6396 8BD8 MOV EBX,EAX
016F:004C6398 85DB TEST EBX,EBX
016F:004C639A 7507 JNZ 004C63A3
016F:004C639C 33C0 XOR EAX,EAX
016F:004C639E E9B1000000 JMP 004C6454
016F:004C63A3 C60300 MOV BYTE [EBX],00 <===把"-"替換成0,就是說把我們輸入的
016F:004C63A6 56 PUSH ESI 註冊碼變成兩個字串串
016F:004C63A7 E878ED0800 CALL 00555124 <===把註冊碼第一部分轉化成數值
(原來輸入的是字串)
016F:004C63AC 59 POP ECX
016F:004C63AD 8945FC MOV [EBP-04],EAX <===把第一部分的數值放入這個地方
016F:004C63B0 C6032D MOV BYTE [EBX],2D <===把註冊碼恢復成員來的樣子
016F:004C63B3 43 INC EBX
016F:004C63B4 803B00 CMP BYTE [EBX],00
016F:004C63B7 7507 JNZ 004C63C0
016F:004C63B9 33C0 XOR EAX,EAX
016F:004C63BB E994000000 JMP 004C6454
016F:004C63C0 53 PUSH EBX
016F:004C63C1 E85EED0800 CALL 00555124 <===把註冊碼第二部分轉化成數值
016F:004C63C6 59 POP ECX
016F:004C63C7 8945F8 MOV [EBP-08],EAX <===存好
016F:004C63CA FF7508 PUSH DWORD [EBP+08] <===姓名
016F:004C63CD E8FE5E0800 CALL 0054C2D0 <===取得姓名長度
016F:004C63D2 59 POP ECX
016F:004C63D3 8945F4 MOV [EBP-0C],EAX <===把長度存好
016F:004C63D6 33C0 XOR EAX,EAX <===開始計算了
016F:004C63D8 33DB XOR EBX,EBX
016F:004C63DA BA03000000 MOV EDX,03
016F:004C63DF 8B4D08 MOV ECX,[EBP+08]
016F:004C63E2 83C103 ADD ECX,BYTE +03 <===從姓名第三個字開始算
016F:004C63E5 3B55F4 CMP EDX,[EBP-0C]
016F:004C63E8 7D1C JNL 004C6406
016F:004C63EA 0FB631 MOVZX ESI,BYTE [ECX] <===取姓名裡的一個字串
016F:004C63ED 0FAF3485B8835600 IMUL ESI,[EAX*4+005683B8] <==與一個數相乘儲存在esi中
016F:004C63F5 03DE ADD EBX,ESI <=累加起來 (這個數直接是什麼後面講)
016F:004C63F7 40 INC EAX
016F:004C63F8 83F826 CMP EAX,BYTE +26
016F:004C63FB 7E02 JNG 004C63FF
016F:004C63FD 33C0 XOR EAX,EAX
016F:004C63FF 42 INC EDX
016F:004C6400 41 INC ECX
016F:004C6401 3B55F4 CMP EDX,[EBP-0C]
016F:004C6404 7CE4 JL 004C63EA 循環完成循環計算後,ebx裡面就是計算的結果
016F:004C6406 3B5DFC CMP EBX,[EBP-04] 比較ebx和開始獲得的註冊碼第一部分數值
016F:004C6409 7404 JZ 004C640F 相等就繼續計算第二部分
016F:004C640B 33C0 XOR EAX,EAX 不然就清0 eax滾蛋
016F:004C640D EB45 JMP SHORT 004C6454
016F:004C640F 33C0 XOR EAX,EAX <==第二部分開始了
016F:004C6411 33DB XOR EBX,EBX
016F:004C6413 BA03000000 MOV EDX,03
016F:004C6418 8B4D08 MOV ECX,[EBP+08]
016F:004C641B 83C103 ADD ECX,BYTE +03 <=還是從姓名的第3個字開始算
016F:004C641E 3B55F4 CMP EDX,[EBP-0C]
016F:004C6421 7D23 JNL 004C6446
016F:004C6423 0FB631 MOVZX ESI,BYTE [ECX] <=取姓名裡的一個字
016F:004C6426 0FB679FF MOVZX EDI,BYTE [ECX-01] <=取前一個字
016F:004C642A 0FAFF7 IMUL ESI,EDI <=相乘
016F:004C642D 0FAF3485B8835600 IMUL ESI,[EAX*4+005683B8] <=再與另一個數相乘
016F:004C6435 03DE ADD EBX,ESI <=累加 (和上面的那個一樣後面講)
016F:004C6437 40 INC EAX
016F:004C6438 83F826 CMP EAX,BYTE +26
016F:004C643B 7E02 JNG 004C643F
016F:004C643D 33C0 XOR EAX,EAX
016F:004C643F 42 INC EDX
016F:004C6440 41 INC ECX
016F:004C6441 3B55F4 CMP EDX,[EBP-0C]
016F:004C6444 7CDD JL 004C6423 循環計算
016F:004C6446 3B5DF8 CMP EBX,[EBP-08] 比較計算結果,和註冊碼第二部分數值
016F:004C6449 7404 JZ 004C644F 相同則跳到成功標誌
016F:004C644B 33C0 XOR EAX,EAX
016F:004C644D EB05 JMP SHORT 004C6454
016F:004C644F B801000000 MOV EAX,01 設立註冊碼比較成功標誌
016F:004C6454 5F POP EDI
016F:004C6455 5E POP ESI
016F:004C6456 5B POP EBX
016F:004C6457 8BE5 MOV ESP,EBP
016F:004C6459 5D POP EBP
016F:004C645A C20800 RET 08

好了,現在講一講上面兩次出現的[EAX*4+005683B8]是什麼意思.
在跟蹤到那個乘法的時候,下d 005683B8,會看到資料欄裡是這個樣子
0B000000 06000000 11000000 0C000000
0C000000 0E000000 05000000 0C000000
10000000 0A000000 0B000000 06000000
0E000000 0E000000 04000000 0B000000
06000000 0E000000 0E000000 04000000
0B000000 09000000 0C000000 0B000000
0A000000 08000000 0A000000 0A000000
10000000 08000000 04000000 06000000
0A000000 0C000000 10000000 08000000
0A000000 04000000 10000000 00000000
發現資料都是每4字元出現一次,這就是為什麼用eax*4了.其實005683B8這個位址裡出現的資料是類BIOS的,就是說這是個字典,每次計算註冊碼的時候到裡面來查一個數字然後跟名字的一個字母做乘法運算.那麼我怎麼才能知道這個字典是多大呢?那就看
016F:004C63F8 83F826 CMP EAX,BYTE +26

016F:004C6438 83F826 CMP EAX,BYTE +26
都是把eax和0x26,也就是38來比較,所以一共有39個資料.就是除了0之外的那些.

至此,我們完全摸清了,mIRC的註冊碼的計算情況.當我們執行到016F:004C6406和016F:004C6446的時候各做一次? ebx顯示出十進制值,然後把兩個值用"-"連結起來就是我們輸入名字所對應的註冊碼了,比如我的lllaaa[BCG]對應7591-674568.

好了,既然搞清楚了算法,寫註冊機也就容易了.下面我貼出註冊機的c語言來源碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc,char *argv[])
{
char dict[39]=
{
0x0b,0x06,0x11,0x0c,0x0c,0x0e,0x05,0x0c,0x10,0x0a,
0x0b,0x06,0x0e,0x0e,0x04,0x0b,0x06,0x0e,0x0e,0x04,
0x0b,0x09,0x0c,0x0b,0x0a,0x08,0x0a,0x0a,0x10,0x08,
0x04,0x06,0x0a,0x0c,0x10,0x08,0x0a,0x04,0x10
};
char name[255];
printf("Input your name please:");
gets(name);
int length=strlen(name);
if (length>=39)
{
printf("\nYour name is longer than 39 chars,please choose another one.");
return 1;
}
int i=0;
long serial1=0,serial2=0;
for (i=0;i<length-3;i++)
{
serial1+=name[i+3]*dict[i];
serial2+=name[i+3]*name[i+2]*dict[i];
}
printf("The serial number is:%d-%d",serial1,serial2);
return 1;
}

本來源程序是支持名字超過39字元的,但是我為了編程的簡單,就做了限制.
psac 目前離線  
送花文章: 3, 收花文章: 1630 篇, 收花: 3204 次
 


主題工具
顯示模式

發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 02:41 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2020, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1