[原創]破解-分析Crackme演算法

仙果發表於2009-06-13
【破文標題】新手-Crackme
【破文作者】仙果
【破解工具】OD,IDA
【破解平臺】Windows XP SP2
【軟體簡介】從看雪上下載的。。。
【破解宣告】純屬愛好
------------------------------------------------------------------------
【破解過程】
    破解一直都是自己的弱項,尤其是演算法,某日從看雪上下載一個crackme,放了兩天,正好今天週六,好毒的太陽也沒有心情出去耍,乾脆就來破解下這個好了。想到,馬上開工。
    PEID檢測為VC++6.0編寫,無殼,還好,不然還要脫殼,又麻煩。
    OD載入分析,F9執行,輸入0123456789提示“Your Password Is Invalid!”,大喜,馬上"超級字串參考",結果發現字元都被加密過,加密演算法未知。
    只有老老實實的分析了,透過分析,發現字串的解密函式
CALL 破解我.004018E0:
004018E0  PUSH EDI
004018E1  MOV EDI,DWORD PTR SS:[ESP+C]             ;  破解我.00404084
004018E5  PUSH EDI                                 ; /String
004018E6  CALL DWORD PTR DS:[<&KERNEL32.lstrlenA>] ; \lstrlenA  //得到字串長度
004018EC  XOR ECX,ECX
004018EE  DEC EAX
004018EF  TEST EAX,EAX
004018F1  JL SHORT 破解我.00401917
004018F3  PUSH EBP
004018F4  PUSH ESI
004018F5  MOV ESI,DWORD PTR SS:[ESP+10]
004018F9  LEA EDX,DWORD PTR DS:[EAX+1]
004018FC  MOV ECX,ESI
004018FE  SUB EDI,ESI
00401900  MOV EBP,EDX
00401902  /MOV AL,BYTE PTR DS:[EDI+ECX]
00401905  |XOR AL,22                             //解密的KEY
00401907  |MOV BYTE PTR DS:[ECX],AL
00401909  |INC ECX
0040190A  |DEC EDX
0040190B  \JNZ SHORT 破解我.00401902
0040190D  MOV BYTE PTR DS:[ESI+EBP],0
00401911  MOV EAX,ESI
00401913  POP ESI
00401914  POP EBP
00401915  POP EDI
00401916  RETN
00401917  MOV EAX,DWORD PTR SS:[ESP+8]
0040191B  POP EDI
0040191C  MOV BYTE PTR DS:[ECX+EAX],0
00401920  RETN
00401921  NOP


其實解密的函式很簡單,只是簡單的異或0x22,據此自己寫了段程式碼來還原加密後的字串,如下:
#include <windows.h>
#include <string.h>
#include <stdio.h>

unsigned char encode[500]=
"\x7B\x4D\x57\x50\x02\x72\x43\x51\x51\x55\x4D\x50\x46\x02\x6B\x51"//Your Password Is Invalid!
"\x02\x6B\x4C\x54\x43\x4E\x4B\x46\x03\x00\x00\x00\x7B\x4D\x57\x02"
"\x43\x50\x47\x02\x74\x47\x50\x5B\x02\x6C\x60\x03\x00\x00\x00\x00"//You are Very NB!
"\x49\x47\x50\x4C\x47\x4E\x11\x10\x0C\x46\x4E\x4E\x00\x00\x00\x00"
"\x57\x51\x47\x50\x11\x10\x0C\x46\x4E\x4E\x00\x00\x65\x47\x56\x72"
"\x50\x4D\x41\x63\x46\x46\x50\x47\x51\x51\x00\x00\x65\x47\x56\x75"
"\x4B\x4C\x46\x4D\x55\x76\x47\x5A\x56\x63\x00\x00\x6D\x52\x47\x4C"
"\x72\x50\x4D\x41\x47\x51\x51\x00\x75\x50\x4B\x56\x47\x72\x50\x4D"
"\x41\x47\x51\x51\x6F\x47\x4F\x4D\x50\x5B\x00\x00\x51\x53\x00\x00"
"\x61\x50\x47\x43\x56\x47\x76\x4A\x50\x47\x43\x46\x00\x00\x00\x00"
"\x70\x47\x43\x46\x72\x50\x4D\x41\x47\x51\x51\x6F\x47\x4F\x4D\x50"
"\x5B\x00\x00\x00\x71\x4E\x47\x47\x52\x00\x00\x00\x65\x47\x56\x61"
"\x57\x50\x50\x47\x4C\x56\x72\x50\x4D\x41\x47\x51\x51\x6B\x46\x00";

int main()
{
	unsigned char decode[500];	
	int i;
	int nLen;
	nLen=sizeof(encode)-1;
	for (i=0; i<nLen;i++)
	{
		decode[i] = encode[i] ^ 0x22;
		printf("%c",decode[i]);
	}

}


以下是解密後的字串
Your Password Is Invalid!"""You are Very NB!""""kernel32.dll""""user32.dll""GetP
rocAddress""GetWindowTextA""OpenProcess"WriteProcessMemory""sq""CreateThread"
ReadProcessMemory"""Sleep"""GetCurrentProcessId

    從中可以很容易找到關鍵字元

接著往下跟就是程式的演算法:也很簡單
00401199    MOV CL,BYTE PTR DS:[EAX+404245]          ;  讀取輸入的註冊碼
0040119F    INC EAX
004011A0    TEST CL,CL
004011A2    JNZ SHORT 破解我.00401199
004011A4    CMP EAX,0A                               ;  比較註冊碼的數目 0A=10,註冊碼要求10位
004011A7    MOV DWORD PTR DS:[404200],EAX
004011AC    JE SHORT 破解我.004011EF
004011AE    PUSH 破解我.00404054
004011B3    PUSH 破解我.0040420C                        ;  getcurrentprocessid
004011B8    CALL 破解我.004018E0                        ;  這個地方生成提示語句
004011BD    ADD ESP,8
004011C0    PUSH 0
004011C2    LEA EAX,DWORD PTR DS:[40420C]
004011C8    PUSH EAX
004011C9    PUSH 0
004011CB    PUSH 0
004011CD    PUSH 4
004011CF    MOV EAX,DWORD PTR DS:[<&KERNEL32.ExitPro>
004011D4    MOV ECX,DWORD PTR DS:[404234]            ;  USER32.77D10000
004011DA    ADD EAX,5
004011DD    PUSH EAX
004011DE    PUSH 破解我.00404038                        ;  ogqqceg`mzc
004011E3    PUSH ECX
004011E4    CALL 破解我.004019F0
004011E9    ADD ESP,0C
004011EC    ADD ESP,14
004011EF   >MOVSX EDI,BYTE PTR DS:[404244]           ;  把註冊碼第一位放入EDI
004011F6    AND EDI,80000003                         ;  EDI=1
004011FC    JNS SHORT 破解我.00401203
004011FE    DEC EDI
004011FF    OR EDI,FFFFFFFC
00401202    INC EDI
00401203    MOV EAX,1
00401208   >MOVSX EDX,BYTE PTR DS:[EAX+404244]       ;  取第二位賦給edx
0040120F    AND EDX,80000003                         ;  第一位+80000003
00401215    JNS SHORT 破解我.0040121C
00401217    DEC EDX
00401218    OR EDX,FFFFFFFC
0040121B    INC EDX
0040121C    ADD EDI,EDX                              ;  第一位與的值和第二位與的值相加
0040121E    INC EAX
0040121F    CMP EAX,4                                ;  判讀eax是否為4,是否為第五位
00401222    JLE SHORT 破解我.00401208                   ;  前五位與0x80000003相與,然後得到的值相加
00401224   >MOVSX EAX,BYTE PTR DS:[404249]           ;  讀第六位,賦給EAX
0040122B    CDQ                                      ;  CDQ   雙字擴充套件.   (把EAX中的字的符號擴充套件到EDX中去)
0040122C    MOV ECX,3                                ;  ecx=3
00401231    MOV DWORD PTR DS:[404208],EDI            ;  儲存EDI
00401237    IDIV ECX                                 ;  整數除法. 第六位的值除以ECX,值賦給EAX,商賦給EDX
00401239    MOV ECX,6
0040123E    MOV ESI,EDX                              ;  把商賦給ESI
00401240   >MOVSX EAX,BYTE PTR DS:[ECX+404244]       ;  第七位賦給EAX,ECX為計數器
00401247    CDQ                                      ;  CDQ   雙字擴充套件.   (把EAX中的字的符號擴充套件到EDX中去)
00401248    MOV EBX,3
0040124D    IDIV EBX
0040124F    ADD ESI,EDX                              ;  與之前得到商相加
00401251    INC ECX
00401252    CMP ECX,9                                ;  判斷是不是第九位
00401255    JLE SHORT 破解我.00401240
00401257    CMP EDI,ESI                              ;  esi與edx相等
00401259    MOV DWORD PTR DS:[404200],ECX            ;  ECX為0A
0040125F    MOV DWORD PTR DS:[404204],ESI            ;  ESI為05
00401265    JNZ SHORT 破解我.004012AA                   ;  不相等則跳,如果需要正確註冊,esi等於edi
00401267    PUSH 破解我.00404070
0040126C    PUSH 破解我.0040420C                        ;  getcurrentprocessid
00401271    CALL 破解我.004018E0                        ;  正確註冊
00401276    ADD ESP,8
00401279    PUSH 0
0040127B    LEA EAX,DWORD PTR DS:[40420C]
00401281    PUSH EAX
00401282    ADD EAX,0D
00401285    PUSH EAX
00401286    PUSH 0
00401288    PUSH 4
0040128A    CALL 破解我.00401160
0040128F    MOV EDX,DWORD PTR DS:[404234]            ;  USER32.77D10000
00401295    PUSH 0
00401297    PUSH 破解我.00404038                        ;  ogqqceg`mzc
0040129C    PUSH EDX
0040129D    CALL 破解我.004019F0
004012A2    ADD ESP,0C
004012A5    ADD ESP,14
004012A8    JMP SHORT 破解我.004012EA
004012AA    PUSH 破解我.00404054
004012AF    PUSH 破解我.0040420C                        ;  getcurrentprocessid
004012B4    CALL 破解我.004018E0                        ;  錯誤註冊


到這裡整個程式就分析清楚了,註冊碼要求有10位,前五位與0x80000003分別相與,得到的值相加得到和A
後五位與3整除,得到的商相加,得到和B,判斷A和B相等,則註冊正確,反之則錯誤
輸入10個a程式就提示註冊完成,好雷哦。。。。
本來想寫序號產生器的,奈何本人的數學實在是差的糊塗,序號產生器就不寫了,如果牛人看到這篇文章,給處序號產生器的提示,感激不盡啊。
------------------------------------------------------------------------
【破解總結】    花了一天的時間把這個Crackme分析完畢,其中也學習到了很多知識,歡迎大家交流!
                                                                  2009.6.13
------------------------------------------------------------------------
【版權宣告】轉載請註明出處
原crackme地址:http://bbs.pediy.com/showthread.php?p=644333#post644333
上傳的附件:

相關文章