史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > Hacker/Cracker 及加解密技術文件
忘記密碼?
論壇說明

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

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

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

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2004-01-10, 10:36 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 金幣
預設 菜鳥對Splish-crackme的算法分析

菜鳥對Splish-crackme的算法分析

作者:winroot
工具: TRW2000 v1.22 W32dasmVGOLD
環境:M$ win98
這是我第一次寫pj文章,請大家指教.因我是只大菜鳥,所以文中難免有錯誤,請各位高手指正.

這個crackme有3問(Nag&Serial&hard code)其他兩個很簡單,無太大意義,也就不必說了.
主要是name/serial
W32dasmVGOLD點擊表單項的參考-->字串串資料參考-->"Sorry, please try again"
出錯後我們看到
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016C8(C)<------從這裡跳出錯的我們就跳回去
|
:004016E2 6A00 push 00000000

* Possible StringData Ref from Data Obj ->"Splish, Splash"
|
:004016E4 680A304000 push 0040300A

* Possible StringData Ref from Data Obj ->"Sorry, please try again."
|
:004016E9 6867304000 push 00403067
:004016EE 6A00 push 00000000
_________________________________________________________________________
到了004016C8我們往上看,看到
:004016A6 EB4D jmp 004016F5
無條件跳~~~那麼她下面的部分就與這句上面部分無關(不知對不對??)
我們就來看這句話的下面:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167C(U)
|
:004016A8 8D354D324000 lea esi, dword ptr [0040324D] //傳送位址給esi
:004016AE 8D3D58324000 lea edi, dword ptr [00403258] //傳送位址給edi
:004016B4 33DB xor ebx, ebx//ebx=0

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004016CB(U)
|
:004016B6 3B1D63344000 cmp ebx, dword ptr [00403463] |
:004016BC 740F je 004016CD //跳走到正確 |
:004016BE 0FBE041F movsx eax, byte ptr [edi+ebx] |
:004016C2 0FBE0C1E movsx ecx, byte ptr [esi+ebx] |
:004016C6 3BC1 cmp eax, ecx | 這裡肯定是關鍵
:004016C8 7518 jne 004016E2//不等就跳失敗 |
~~~~~~~~~~~~~~ ~~~~~~~~~~~~ |
:004016CA 43 inc ebx //加1 |
:004016CB EBE9 jmp 004016B6//我就是跳~~~~~ |
在這裡會有幾個疑問:
1.如果eax=ecx,每次ebx=ebx加1然後直到eax和dword ptr [00403463]相等.
那麼,dword ptr [00403463]是什麼?
2.dword ptr [00403258]
dword ptr [0040324D]
裡面究竟是什麼?
那麼我們就搜尋這幾個位址~~~
___________________________________________________________________________

先不要看程式碼,先看下面的解釋
* Referenced by a CALL at Address:
|:00401402
|
:004015E4 55 push ebp
:004015E5 8BEC mov ebp, esp
:004015E7 6A20 push 00000020
:004015E9 6842324000 push 00403242
:004015EE FF750C push [ebp+0C]
* Reference To: USER32.GetWindowTextA, Ord:015Bh
|
:004015F1 E834010000 Call 0040172A//取serial
:004015F6 85C0 test eax, eax//此時eax=serial長度如果serial長度是0出錯
:004015F8 0F8495000000 je 00401693//跳出
:004015FE A367344000 mov dword ptr [00403467], eax//把eax的值送入00403467
:00401603 6A0B push 0000000B
:00401605 6836324000 push 00403236
:0040160A FF7508 push [ebp+08]

* Reference To: USER32.GetWindowTextA, Ord:015Bh
|
:0040160D E818010000 Call 0040172A//取name
:00401612 85C0 test eax, eax//看eax=name的長度是不是0
:00401614 7468 je 0040167E
:00401616 A363344000 mov dword ptr [00403463], eax//把eax的值送入00403463
:0040161B 33C9 xor ecx, ecx//
:0040161D 33DB xor ebx, ebx// 清0
:0040161F 33D2 xor edx, edx//
:00401621 8D3536324000 lea esi, dword ptr [00403236]//讀取name,計算完後存入00403258
:00401627 8D3D58324000 lea edi, dword ptr [00403258]
:0040162D B90A000000 mov ecx, 0000000A//ecx=10

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401650(C)
|
:00401632 0FBE041E movsx eax, byte ptr [esi+ebx]//先符號擴展,再傳送給eax
:00401636 99 cdq//雙字擴展.(把EAX中的字的符號擴展到EDX中去)
:00401637 F7F9 idiv ecx//除以10將餘數放入edx
:00401639 33D3 xor edx, ebx//兩者異或
:0040163B 83C202 add edx, 00000002//edx=edx+2
:0040163E 80FA0A cmp dl, 0A//如果dl不小於10就跳dl=edx
:00401641 7C03 jl 00401646
:00401643 80EA0A sub dl, 0A//dl=dl-10

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401641(C)
|
:00401646 88141F mov byte ptr [edi+ebx], dl//傳值
:00401649 43 inc ebx//自加一
:0040164A 3B1D63344000 cmp ebx, dword ptr [00403463]//比較name長度如果不相等就跳
:00401650 75E0 jne 00401632
:00401652 33C9 xor ecx, ecx//
:00401654 33DB xor ebx, ebx// 清零
:00401656 33D2 xor edx, edx//
:00401658 8D3542324000 lea esi, dword ptr [00403242]//讀取serial,計算完後存入0040324D
:0040165E 8D3D4D324000 lea edi, dword ptr [0040324D]
:00401664 B90A000000 mov ecx, 0000000A//eax=10

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040167A(C)
|
:00401669 0FBE041E movsx eax, byte ptr [esi+ebx]//變成雙字元
:0040166D 99 cdq //雙字擴展.(把EAX中的字的符號擴展到EDX中去)
:0040166E F7F9 idiv ecx//除以10將餘數放入dl=edx
:00401670 88141F mov byte ptr [edi+ebx], dl//將dl值傳入edi+ebx
:00401673 43 inc ebx//ebx自加一
:00401674 3B1D67344000 cmp ebx, dword ptr [00403467]//比較如果不等就跳
:0040167A 75ED jne 00401669
:0040167C EB2A jmp 004016A8// 絕對跳轉

我覺得肯定有和我一樣的初學者會問:你是怎麼知道取serial和取name???

答案是:你看* Reference To: USER32.GetWindowTextA, Ord:015Bh
說明使用GetWindowText這個函數,(如果和我一樣沒有學過編程的人就需要查winapi)

GetWindowText
參數 類型及說明
hwnd Long,欲獲取文字的那個視窗的關鍵
lpString String,預定義的一個緩衝區,至少有cch+1個字串大小;隨同視窗文字載入
cch Long,lpString緩衝區的長度
那麼在彙編中它就會表現為:
:00401603 6A0B push 0000000B//
:00401605 6836324000 push 00403236//3個參數
:0040160A FF7508 push [ebp+08]//
:004015F1 E834010000 Call 0040172A//取name
這時eax=name長度
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
知道這些我們來解答上面的問題:
1.dword ptr [00403463]是什麼?
:00401616 A363344000 mov dword ptr [00403463], eax//把eax的值送入00403463
是name的長度
2.dword ptr [00403258]
dword ptr [0040324D]
裡面究竟是什麼?
:00401621 8D3536324000 lea esi, dword ptr [00403236]//讀取00403236,存入00403258
:00401627 8D3D58324000 lea edi, dword ptr [00403258]
那麼00403236是什麼?看:00401605 6836324000 push 00403236
是GetWindowText的一個參數,是什麼呢?我們用trw看一下是輸入的name
所以dword ptr [00403258]是name ascii對應的數值.
同理:dword ptr [0040324D]是serial ascii對應的數值.
好了,既然是算法分析我們就看他把name怎麼變了??
從00401632到00401650是個循環!!!!
只要仔細分析就不難得出:
____________________________________________________________循環直到ebx=eax_______
| |
| |~如果大於10就減10| |
|~>esi+ebx--->eax---->edx=edx%ebx--->edx=edx^ebx--->edx=edx+2| |-|
| |~小於10就跳 |
name|
|
~>eax=name長度設為變數i

計算完後存入00403258

再看
____________________________________________________________循環直到ebx=eax_______
| |
| |
|~>esi+ebx--->eax---->edx=edx%ebx------------------------------------------------|
|
serail|
|
~>eax=serail長度設為變數

計算完後存入0040324D
最後兩者比較,註冊碼只有和註冊名位數相同的部分才起作用
這就是我的算法分析~~~~!!!!!
如果要寫註冊機,只要把註冊嗎那段求逆就行了
#include "stdio.h"
main()
{char name[30],serial;
int i,j,a,b,m,n;
printf(" your name:");
scanf("%s",name);
n=strlen(name);
printf("your serial is:");
for(i=0;i<n;i++)
{a=name[i];
b=a%10;
m=b^i;
m=m+2;
if(m>=10) m=m-10;
for(j=0;j<10;j++)
{serial=m+j*10;
if(serial>48)
{if(serial<122) printf("%c",serial);
else break;}
}
}
printf("\n");
}
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
 



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

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


所有時間均為台北時間。現在的時間是 10:40 PM


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


SEO by vBSEO 3.6.1