查壳
- 没有壳,32位可执行程序。
- 运行一下程序,可知是MFC框架的对话框程序,随便输入数据,点击注册失败。
分析
-
IDA分析,找到winmain,这是MFC的主函数
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { return DialogBoxParamW(hInstance, (LPCWSTR)0x65, 0, DialogFunc, 0); }
-
函数就一个操作,载入对话框,对话框的主程序就是DialogFunc 。
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4) { HMODULE v5; // eax HICON v6; // eax HMODULE v7; // eax HCURSOR v8; // ST20_4 HWND v9; // eax CHAR email; // [esp+8h] [ebp-340h] CHAR serial[4]; // [esp+108h] [ebp-240h] char serial[4]; // [esp+10Ch] [ebp-23Ch] char serial[5]; // [esp+10Dh] [ebp-23Bh] char serial[6]; // [esp+10Eh] [ebp-23Ah] char serial[7]; // [esp+10Fh] [ebp-239h] char serial[8]; // [esp+110h] [ebp-238h] char serial[9]; // [esp+111h] [ebp-237h] char serial[10]; // [esp+112h] [ebp-236h] char serial[11]; // [esp+113h] [ebp-235h] char serial[12]; // [esp+114h] [ebp-234h] char serial[13]; // [esp+115h] [ebp-233h] char serial[14]; // [esp+116h] [ebp-232h] char serial[15]; // [esp+117h] [ebp-231h] CHAR Text; // [esp+208h] [ebp-140h] char sucess_msg[16]; // [esp+308h] [ebp-40h] __int128 v26; // [esp+318h] [ebp-30h] int v27; // [esp+328h] [ebp-20h] __int128 fail_msg; // [esp+32Ch] [ebp-1Ch] int v29; // [esp+33Ch] [ebp-Ch] __int16 v30; // [esp+340h] [ebp-8h] if ( a2 == 16 ) { EndDialog(hDlg, 0); return 0; } if ( a2 == 272 ) { v5 = GetModuleHandleW(0); v6 = LoadIconW(v5, (LPCWSTR)0x67); SetClassLongA(hDlg, -14, (LONG)v6); v7 = GetModuleHandleW(0); v8 = LoadCursorW(v7, (LPCWSTR)0x66); v9 = GetDlgItem(hDlg, 1); SetClassLongA(v9, -12, (LONG)v8); return 1; } if ( a2 != 273 || (unsigned __int16)a3 != 1 ) return 0; memset(&email, (unsigned __int16)a3 - 1, 0x100u); memset(serial, 0, 0x100u); memset(&Text, 0, 0x100u); GetDlgItemTextA(hDlg, 1001, &email, 256); GetDlgItemTextA(hDlg, 1002, serial, 256); if ( strstr(&email, "@") && strstr(&email, ".") && strstr(&email, ".")[1] && strstr(&email, "@")[1] != '.' )// 校验邮箱地址的合法性 { fail_msg = xmmword_1390AA0; // 拼接失败消息 v29 = 1701999980; *(_OWORD *)sucess_msg = xmmword_1390A90; v30 = '.'; v26 = xmmword_1390A80; v27 = ':si'; if ( strlen(serial) != 0x10 || serial[0] != 'C' || serial[15] != 'X' || serial[1] != 'Z' || serial[1] + serial[14] != 0x9B // 5a || serial[2] != '9' || serial[2] + serial[13] != 0x9B // 0x39 || serial[3] != 'd' || serial[12] != '7' || serial[4] != 'm' || serial[11] != 'G' || serial[5] != 'q' || serial[5] + serial[10] != 0xAA // 0x71 || serial[6] != '4' || serial[9] != 'g' || serial[7] != 'c' || serial[8] != '8' ) { strcpy_s(&Text, 0x100u, (const char *)&fail_msg); } else { strcpy_s(&Text, 0x100u, sucess_msg); strcat_s(&Text, 0x100u, serial); } } else { strcpy_s(&Text, 0x100u, "Your E-mail address in not valid."); } MessageBoxA(hDlg, &Text, "Registeration", 0x40u); return 1; }
-
IDA有时对数组的分析不是很好,比如 CHAR serial[4] 下面的相连的12个变量,其实根据分析得知都是一起的合为一个字符数组,所以改一下名字,方便后面的分析。
-
程序先是验证邮箱的合法性,然后验证serial。通过前面的变量名重定义,分析起serial就很清晰明了了。
-
最后手逆一下即可得到FLAG:CZ9dmq4c8g9G7bAX