环境:
Windows xp
工具:
IDA
EXEINFOPE
OD
0x00 查壳
EXEINFOPE查壳,
无壳
0x01 分析
if ( (unsigned __int16)wParam == 0x40B ) // 成功{*(_OWORD *)v22 = xmmword_41DB98;v25 = 0;v23 = xmmword_41DBA8;v24 = xmmword_41DBB8;memset_4039D0(&v26, 0, 150);MessageBoxW(hWnd, v22, L"Successed", 0);return 0;}if ( (unsigned __int16)wParam == 0x40C ){sub_402970((_WORD *)lParam, &v21);v9 = (_WORD *)sub_402CD6(2 * (v21 + 1) | -((unsigned __int64)(unsigned int)(v21 + 1) >> 31 != 0));strcpy_402870((int)v9, (_WORD *)lParam);sub_4029B0(v9);sub_402A00(v9);memset_4039D0((_BYTE *)v22, 0, 200);strcpy_402870((int)v22, v9);release_402CDF(v9);v10 = 0;if ( v22[0] ){v11 = 0;v12 = v22;do{++v10;*v12 ^= *(_WORD *)(v11 + lParam);v11 = 2 * v10;v12 = &v22[v10];}while ( *v12 );}if ( sub_402810((char *)lParam, (char *)v22) )SendMessageW(hWnd, 0x111u, 0x40Au, 0);return 0;}if ( (unsigned __int16)wParam == 1039 ) // 0x40F{MessageBoxW(0, L"something you lost!", L"Failed", 0);return 0;}return DefWindowProcW(hWnd, 0x111u, wParam, lParam);}if ( (unsigned __int16)wParam == 0x40A ){*(_OWORD *)Text = xmmword_41DB60;v28 = xmmword_41DB70;v29 = xmmword_41DB80;_mm_storel_epi64((__m128i *)&v30, _mm_loadl_epi64((const __m128i *)&qword_41DB90));memset_4039D0(&v31, 0, 44);MessageBoxW(hWnd, Text, L"Failed", 0);return 0;}`
可知wParam == 0x40B时弹出成功对话框。
if ( a1 ){if ( a2 ) // 第2次调用时执行这里{v8 = debug_4048DE();memset_4039D0(&String, 0, 200);GetWindowTextW(*((HWND *)v2 + 3), &String, 200);// 读取输入内容v4 = 0; // 输入内容长度v5 = &String;if ( String ){do{++v5;++v4;}while ( *v5 );}v6 = (_WORD *)sub_402CD6(2 * (v4 + 1) | -((unsigned __int64)(v4 + 1) >> 31 != 0));if ( debug_4048DE() - v8 > 2 ) // 猜测是测试是否在被调试{sub_404BB1();JUMPOUT(*(_DWORD *)byte_401E45);}strcpy_402870((int)v6, &String); // v6是个地址,输入内容长度xor0x5if ( v4 >= 7 ){if ( v4 <= 7 ) // 输入内容长度是否为7{sub_401A60((int)v2, v6); // 下一关return;}v7 = 0x40D;}else{v7 = 0x40E;}SendMessageW(*((HWND *)v2 + 1), v7, 0, 0);release_402CDF(v6);return;}if ( sub_401C00(a1) // 检查输入内容是否含有'b'&& (memset_4039D0(&String, 0, 200),GetWindowTextW(*((HWND *)v2 + 3), &String, 100),sub_402A50(v3, (__int16 *)&String, 'p')) )// 检查输入内容是否含有'p'{sub_401CB0(v2, 1);}else{SendMessageW(*((HWND *)v2 + 1), 0x111u, 0x40Fu, 0);}}
首先是判断输入内容里是否含有’b’、'p’这两个字符
然后再判断输入内容长度是否为7
do{v18 = v3[v17];if ( v18 >= 0x61 && v18 <= 0x7A )v3[v17] = v18 - 32;++v17;}while ( v17 < v15 ); // 输入内容小写字母转大写}
do{if ( v20 ){v23 = *v22; // 输入内容v24 = v33; // A-Zv25 = 0;while ( v23 != *v24 ) // 判断输入的字符是否在表中{v24 = &v33[++v25];if ( !v33[v25] ) // 是否超出A-Z范围goto LABEL_37;}*(_WORD *)v21 = v33[v25]; // 在范围里的话就保存起来v21 = (__int64 *)((char *)v21 + 2);
LABEL_37:v20 = v33[0];}v22 = &v3[++v19]; // 下一个字符}while ( v3[v19] );
如果输入的内容是字母就保存起来。
v27 = &v35; // 提取出来的字符if ( (_WORD)v35 ){do{v27 = (__int64 *)((char *)v27 + 2);++v26;}while ( *(_WORD *)v27 );if ( v26 == 2 ) // 如果有两个字符是在表中{LODWORD(v35) = 0x350031; // 这里确定了输入内容第3位到第6位只能是15pbHIDWORD(v35) = &unk_420050;v28 = v3 + 2;v36 = 0;v29 = 0;while ( *((_WORD *)&v35 + v29) == *v28 ){++v29;++v28;if ( v29 >= 4 ){if ( !sub_401740((_DWORD *)v2, v3) ) // v2尝试次数break;v31 = 0x40B;return PostMessageW(*(HWND *)(v2 + 4), 0x111u, v31, 0);// 成功}}}}v31 = 0x40A;return PostMessageW(*(HWND *)(v2 + 4), 0x111u, v31, 0);
统计输入内容是字母的个数,不等于2个就错误。
然后将输入内容与常数值比较,不满足也错误。
do{*(_WORD *)v4 = v5;v4 = (__int128 *)((char *)v4 + 2); // 将1-9放入v4++v5;}while ( v5 <= 0x39 );v6 = 0;v7 = v2;if ( v2 && *v2 ){do{++v7;++v6; // 计算输入长度}while ( *v7 );}v8 = sub_4028D0((char *)&v20, &v2[*v3]); // 将1-9和输入的内容拼接,开始位置为尝试的次数v9 = &v2[v6 - 1]; // 取最后一个字符v19 = v8;v10 = 0;v17 = v9;if ( (_WORD)v20 ){v11 = (char *)&v20;v12 = *v9 & 1;while ( 1 ){v13 = v12 + (*(_WORD *)v11 >> 2);if ( v13 == 0x32 )break;if ( v13 != 0x64 ){v11 = (char *)&v20 + 2 * ++v10; // 下一个字符if ( *(_WORD *)v11 )continue;}v8 = v19;goto LABEL_12;}}else{
LABEL_12:v14 = &v20;v15 = 0x31;while ( *(_WORD *)v14 == *(_WORD *)((char *)v14 + (char *)v2 - (char *)&v20) )// 判断输入的第1个字符是否为1,// 第2个字符是否为2,由此可知前6个字符为1215pb{v15 += 6;v14 = (__int128 *)((char *)v14 + 2);if ( v15 > 0x39 ){if ( *v2 + *((_WORD *)v8 + 9) == 0x63 && *v17 == *v18 + *((_WORD *)v8 + 6) )// v8[9]=='2' && s[6]==v8[6]+尝试次数,v8[6]必定为7,// v8[9]为输入内容[尝试次数],由上面可知这个尝试次数必定为1// 则s[6]必定为'8',故结果为1215bp8return 1; // 一定要返回1return 0;}}}