我自己写的CrackMe的分析

 1 ; int __cdecl main(int argc, const char **argv, const char **envp)
 2 _main proc near
 3 
 4 Buf= byte ptr -114h
 5 var_110= dword ptr -110h
 6 var_10C= dword ptr -10Ch
 7 var_108= dword ptr -108h
 8 Filename= byte ptr -104h
 9 argc= dword ptr  4
10 argv= dword ptr  8
11 envp= dword ptr  0Ch
12 
13 sub     esp, 114h
14 push    ebx
15 push    esi
16 push    edi
17 push    offset Format   ; "欢迎各位来到52pojie,欢迎各位来尝试我的"...
18 call    _printf
19 push    offset aUZScQT  ; "最近重新再学一遍C语言,就写了这个,就当练"...
20 call    _printf
21 push    offset aByTk2012513 ; "by TK 2012-5-13\n"
22 call    _printf
23 push    offset asc_4090A0 ; "\n\n"
24 call    _printf
25 add     esp, 10h
26 lea     eax, [esp+120h+Filename]
27 push    104h            ; nSize,装载到缓冲区lpFileName的最大值,这里为260,在编程中为MAX_PATH
28 push    eax             ; lpFilename,一个指针,这里是存放获取到程序目录所在的位置的地址
29 push    0               ; hModule,实例的句柄,这里为本实例的句柄
30 call    ds:GetModuleFileNameA
31 lea     ecx, [esp+120h+Filename]
32 push    '\'             ; Ch
33 push    ecx             ; Str
34 call    _strrchr        ;查找一个字符c在另一个字符串str中末次出现的位置
35 mov     byte ptr [eax], 0
36 mov     edi, offset aNot_key_dat ; "\\not_key.dat"
37 or      ecx, 0FFFFFFFFh
38 xor     eax, eax
39 repne scasb
40 not     ecx
41 sub     edi, ecx
42 lea     edx, [esp+128h+Filename]
43 mov     esi, edi
44 mov     ebx, ecx
45 mov     edi, edx
46 or      ecx, 0FFFFFFFFh
47 repne scasb
48 mov     ecx, ebx
49 dec     edi
50 shr     ecx, 2
51 rep movsd
52 mov     ecx, ebx
53 lea     eax, [esp+128h+Filename]
54 and     ecx, 3
55 push    offset Mode     ; "r"
56 rep movsb
57 push    eax             ; Filename
58 call    _fopen          ;读取一个文件,文件名在参数中,读取方式也在参数中
59 mov     edi, eax        ;读取结果放入eax,然后又复制到edi中
60 add     esp, 10h
61 test    edi, edi
62 jnz     short loc_4010AA

总的来说,这段程序的目的就是打开keyfile文件,如果打开失败,就跳转到失败提示的地方。(这样,我们就在程序当前的目录下新建一个keyfile文件,文件名为not_key.dat)

如果要爆破这个程序,先要把这里改为jmp或nop掉。

如果打开文件成功,则继续判断。

通过IDA的F5功能,一些修改,变成了下面这样:

 1 fp = fopen(&Filename, "r");
 2 fp_same = fp;
 3 if ( fp )
 4   {
 5     *(_DWORD *)Buf = 0;
 6     v16 = 0;
 7     v17 = 0;
 8     v18 = 0;
 9     fgets(Buf, 16, fp);
10     if ( strcmp(Buf, "Hello World") )
11       v14 = "You didn't pass the test\n";
12     else
13       v14 = "Congratulations!  You are the best one!\n";
14     printf(v14);
15     fclose(fp_same);
16   }
17   else
18   {
19     printf("You didn't pass the test\n");
20   }
21   printf("\n\n");
22   return system("pause");

通过打开文件,读取文件的16个字节,然后与Hello World进行对比。

总结:这个程序的思路是很清晰的,读取keyfile,如果连keyfile都没有,那就不可能注册了。

  如果存在keyfile的话,那么从keyfile中读取16个字节,看它是否为我们所对应的key,如果正确,则提示正确

     如果不正确,那就显示不正确呗。

 

我对这个程序做了爆破测试,结果发现会出现异常,那么是什么原因呢?一,文件没有读取成功,而我们使用fgets函数,二,文件没有打开,也就是fopen没有返回

而我们又调用了fclose,所以爆破的时候要记得把这两个函数nop掉。

爆破视频:http://115.com/file/dpt63rpq

posted @ 2012-05-14 19:27  r3call  阅读(864)  评论(0编辑  收藏  举报