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 410 argv= dword ptr 811 envp= dword ptr 0Ch12 13 sub esp, 114h14 push ebx15 push esi16 push edi17 push offset Format ; "欢迎各位来到52pojie,欢迎各位来尝试我的"...18 call _printf19 push offset aUZScQT ; "最近重新再学一遍C语言,就写了这个,就当练"...20 call _printf21 push offset aByTk2012513 ; "by TK 2012-5-13\n"22 call _printf23 push offset asc_4090A0 ; "\n\n"24 call _printf25 add esp, 10h26 lea eax, [esp+120h+Filename]27 push 104h ; nSize,装载到缓冲区lpFileName的最大值,这里为260,在编程中为MAX_PATH28 push eax ; lpFilename,一个指针,这里是存放获取到程序目录所在的位置的地址29 push 0 ; hModule,实例的句柄,这里为本实例的句柄30 call ds:GetModuleFileNameA31 lea ecx, [esp+120h+Filename]32 push '\' ; Ch33 push ecx ; Str34 call _strrchr ;查找一个字符c在另一个字符串str中末次出现的位置35 mov byte ptr [eax], 036 mov edi, offset aNot_key_dat ; "\\not_key.dat"37 or ecx, 0FFFFFFFFh38 xor eax, eax39 repne scasb40 not ecx41 sub edi, ecx42 lea edx, [esp+128h+Filename]43 mov esi, edi44 mov ebx, ecx45 mov edi, edx46 or ecx, 0FFFFFFFFh47 repne scasb48 mov ecx, ebx49 dec edi50 shr ecx, 251 rep movsd52 mov ecx, ebx53 lea eax, [esp+128h+Filename]54 and ecx, 355 push offset Mode ; "r"56 rep movsb57 push eax ; Filename58 call _fopen ;读取一个文件,文件名在参数中,读取方式也在参数中59 mov edi, eax ;读取结果放入eax,然后又复制到edi中60 add esp, 10h61 test edi, edi62 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 else13 v14 = "Congratulations! You are the best one!\n";14 printf(v14);15 fclose(fp_same);16 }17 else18 {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掉。
爆破视频: