BUU_RE_刮开有奖
32,无壳
shift+f12查字符串,跟进
到主函数:
INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4) { const char *v4; // esi const char *v5; // edi int v7[2]; // [esp+8h] [ebp-20030h] BYREF int v8; // [esp+10h] [ebp-20028h] int v9; // [esp+14h] [ebp-20024h] int v10; // [esp+18h] [ebp-20020h] int v11; // [esp+1Ch] [ebp-2001Ch] int v12; // [esp+20h] [ebp-20018h] int v13; // [esp+24h] [ebp-20014h] int v14; // [esp+28h] [ebp-20010h] int v15; // [esp+2Ch] [ebp-2000Ch] int v16; // [esp+30h] [ebp-20008h] CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF char v18[65536]; // [esp+10034h] [ebp-10004h] BYREF if ( a2 == 272 ) return 1; if ( a2 != 273 ) return 0; if ( (_WORD)a3 == 1001 ) { memset(String, 0, 65535u); GetDlgItemTextA(hDlg, 1000, String, 65535); if ( strlen(String) == 8 ) { v7[0] = 90; v7[1] = 74; v8 = 83; v9 = 69; v10 = 67; v11 = 97; v12 = 78; v13 = 72; v14 = 51; v15 = 110; v16 = 103; sub_4010F0((int)v7, 0, 10); memset(v18, 0, 65535u); v18[0] = String[5]; v18[2] = String[7]; v18[1] = String[6]; v4 = sub_401000((int)v18, strlen(v18)); memset(v18, 0, 0xFFFFu); v18[1] = String[3]; v18[0] = String[2]; v18[2] = String[4]; v5 = sub_401000((int)v18, strlen(v18)); if ( String[0] == v7[0] + 34 && String[1] == v10 && 4 * String[2] - 141 == 3 * v8 && String[3] / 4 == 2 * (v13 / 9) && !strcmp(v4, "ak1w") && !strcmp(v5, "V1Ax") ) { MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0); } } return 0; } if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 ) return 0; EndDialog(hDlg, (unsigned __int16)a3); return 1; }
注意到输出上面有特殊字符串,跟进后发现:
有一串像base64的字符串,刚开始以为是自定义的base64,拿去在线解,结果:
然后试了直接解码,就出了:
分别对应v4:jMV,v5:WP1
前面分析应该可以得知flag是八位,现在还差两位,
注意:
这两段将字符串赋值到String,所以现在得到的flag就有:
flag{__WP1jMV}
根据这个能知道前两位是"|C"但是提交之后会发现是错的
看了大佬的wp,发现这些值和他的不一样,换了个ida就可以了:
但是当我直接把v9默认成90了,结果还是不对,仔细观察一番发现有个函数对v9进行处理:
int __cdecl sub_4010F0(int a1, int a2, int a3) { int result; // eax int i; // esi int v5; // ecx int v6; // edx result = a3; for ( i = a2; i <= a3; a2 = i ) { v5 = 4 * i; v6 = *(_DWORD *)(4 * i + a1); if ( a2 < result && i < result ) { do { if ( v6 > *(_DWORD *)(a1 + 4 * result) ) { if ( i >= result ) break; ++i; *(_DWORD *)(v5 + a1) = *(_DWORD *)(a1 + 4 * result); if ( i >= result ) break; while ( *(_DWORD *)(a1 + 4 * i) <= v6 ) { if ( ++i >= result ) goto LABEL_13; } if ( i >= result ) break; v5 = 4 * i; *(_DWORD *)(a1 + 4 * result) = *(_DWORD *)(4 * i + a1); } --result; } while ( i < result ); } LABEL_13: *(_DWORD *)(a1 + 4 * result) = v6; sub_4010F0(a1, a2, i - 1); result = a3; ++i; } return result; }
这里把伪代码转换成c语言:
#include <stdio.h> #include <string.h> int sub_4010F0(char* a1, int a2, int a3) { int result; // eax int i; // esi int v5; // ecx int v6; // edx result = a3; for (i = a2; i <= a3; a2 = i) { v5 = i; v6 = a1[i]; if (a2 < result && i < result) { do { if (v6 > a1[result]) { if (i >= result) break; ++i; a1[v5] = a1[result]; if (i >= result) break; while (a1[i] <= v6) { if (++i >= result) goto LABEL_13; } if (i >= result) break; v5 = i; a1[result] = a1[i]; } --result; } while (i < result); } LABEL_13: a1[result] = v6; sub_4010F0(a1, a2, i - 1); result = a3; ++i; } return result; } int main(void) { char str[] = "ZJSECaNH3ng"; sub_4010F0(str,0,10); printf("%s", str); return 0; }
其中的字符串"ZJ......"是v9到v19的ascii码,最开始我一直没找到
接下来运行出来:
然后想了想
发现这个运行得到的字符串替代了v9到v19,所以:
那么v9代表的就是3,v13代表的就是J
最后拼起来就是:
flag{UJWP1jMp}