史萊姆論壇

史萊姆論壇 (http://forum.slime.com.tw/)
-   Hacker/Cracker 及加解密技術文件 (http://forum.slime.com.tw/f132.html)
-   -   菜鳥對Splish-crackme的算法分析 (http://forum.slime.com.tw/thread90591.html)

psac 2004-01-10 10:36 PM

菜鳥對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");
}


所有時間均為台北時間。現在的時間是 06:12 AM

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

『服務條款』

* 有問題不知道該怎麼解決嗎?請聯絡本站的系統管理員 *


SEO by vBSEO 3.6.1