[原创]破解-分析Crackme算法

发布者:仙果
发布于:2009-06-13 22:18
【破文标题】新手-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
上传的附件:

声明:该文观点仅代表作者本人,转载请注明来自看雪