今天又来试着做NCTU,于是乎挑了这道题,题目描述如下:
BCG's full name is BeGiNnEr'S CrAcKiNg Group.... Do you have the ability to crack this program?.... press "start" then download it! Hint1: The checkin key is the "content"... Hint2: key length is the asked length, and all character is same as the first one.
这道题做完之后确实的说,也是挺简单的,但由于自己还是太弱,做的时候就没有这么顺利了。
首先打开程序,会发现上面有着各种说明,似乎这题是BCG申请加入时的题,程序上写的那些限制我也没太弄明白,不过这里既然只是解题,就不管了。
IDA反汇编程序会发现,程序只有一个很短的start,感觉应该是自解压的程序,于是乎先打开程序,再将OD附加到该程序上便开始调试。然而,尝试了半天之后,还是没有什么收获,一直没能看到什么关键代码。
实在无奈之下,用PEiD查了下,发现是有个aspack壳,于是在网上找了个脱壳软件将壳脱掉,再用IDA查看,顿时感觉就是柳暗花明。
程序很明确,一眼就看到关键程序,用IDA反编译得:
int __stdcall DialogFunc(HWND hDlg, int a2, int a3, int a4) { int result; // eax@4 int v5; // eax@14 if ( a2 == 273 ) { if ( a3 == 1 ) return MessageBoxA(0, "中, "OfficialCrackme", 0x1000u); if ( a3 == 2 ) return EndDialog(hDlg, 0); if ( a3 != 3 ) return 0; } else { if ( a2 != 272 ) { if ( a2 != 16 ) return 0; return EndDialog(hDlg, 0); } SetDlgItemTextA(hDlg, 10, String); } hFile = CreateFileA("[BCG].Key", 0xC0000000u, 3u, 0, 3u, (DWORD)"€", 0); if ( hFile == (HANDLE)-1 ) goto LABEL_22; if ( !ReadFile(hFile, (LPVOID)&String2, 0xAu, &NumberOfBytesRead, 0) ) goto LABEL_22; if ( !ReadFile(hFile, String1, 0xAu, &NumberOfBytesRead, 0) ) goto LABEL_22; CloseHandle(hFile); v5 = 0; do { *(&String2 + v5) ^= 0x58u; ++v5; } while ( *(&String2 + v5) ); if ( !lstrcmpA(String1, &String2) ) result = MessageBoxA(0, "注册验证成功,恭喜, "OfficialCrackme", 0x1000u); else LABEL_22: result = MessageBoxA(0, "革, "OfficialCrackme", 0x1000u); return result; }
程序流程很清楚,是从[BCG].Key中读出两个长度为0xA的字符串,然后其中一个字符串与0x58异或之后的结果正好要为另一个字符串,那我们可以取'0' xor 'h',于是在文件中写入hhhhhhhhhh0000000000,再尝试运行程序。可是,结果却与我们的预期大相径庭,还是告诉我们“革命尚未成功”。
下断点再调试程序发现,String2和String1在内存空间上正好相距10,也就是说String2的后面没有字符串结尾标志 ,这样导致异或的时候String2和String1都被异或的,这还不止,在lstrcmpA的时候,更是认为String1是String2的字串了,那么看来,这两个字符串肯定不会相等了。
为了解决这个问题,第一想法就是在文件中写入 ,然String2并不能真正读入10个字符或者说让第10个字符为 ,但这样且不说是否可行,但至少是相当麻烦的,那再仔细想想会发现,如果我们输入的String2中有字符X(即0x58),那么异或的时候就会产生 ,这样在lstrcmpA的时候,两个字符串就可以相等了。
那么,我们直接在文件中写入20个X,运行程序便成功弹出正确的提示框,得以解决。
PS:chekckin的时候需要注意,是提交10个X即可,不要提交20个,这问题坑了我半天……