BUUOJ reverse 刮开有奖
刮开有奖
这是一个赌博程序,快去赚钱吧!!!!!!!!!!!!!!!!!!!!!!!!!!!(在编辑框中的输入值,即为flag,提交即可) 注意:得到的 flag 请包上 flag{} 提交
拖到ida 找到关键函数:
BOOL __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4) { const char *v4; // esi const char *v5; // edi int v7; // [esp+8h] [ebp-20030h] int v8; // [esp+Ch] [ebp-2002Ch] int v9; // [esp+10h] [ebp-20028h] int v10; // [esp+14h] [ebp-20024h] int v11; // [esp+18h] [ebp-20020h] int v12; // [esp+1Ch] [ebp-2001Ch] int v13; // [esp+20h] [ebp-20018h] int v14; // [esp+24h] [ebp-20014h] int v15; // [esp+28h] [ebp-20010h] int v16; // [esp+2Ch] [ebp-2000Ch] int v17; // [esp+30h] [ebp-20008h] CHAR String; // [esp+34h] [ebp-20004h] char v19; // [esp+35h] [ebp-20003h] char v20; // [esp+36h] [ebp-20002h] char v21; // [esp+37h] [ebp-20001h] char v22; // [esp+38h] [ebp-20000h] char v23; // [esp+39h] [ebp-1FFFFh] char v24; // [esp+3Ah] [ebp-1FFFEh] char v25; // [esp+3Bh] [ebp-1FFFDh] char v26; // [esp+10034h] [ebp-10004h] char v27; // [esp+10035h] [ebp-10003h] char v28; // [esp+10036h] [ebp-10002h] if ( a2 == 272 ) return 1; if ( a2 != 273 ) return 0; if ( (_WORD)a3 == 1001 ) { memset(&String, 0, 0xFFFFu); GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF); if ( strlen(&String) == 8 ) { v7 = 90; v8 = 74; v9 = 83; v10 = 69; v11 = 67; v12 = 97; v13 = 78; v14 = 72; v15 = 51; v16 = 110; v17 = 103; sub_4010F0((int)&v7, 0, 10); memset(&v26, 0, 0xFFFFu); v26 = v23; v28 = v25; v27 = v24; v4 = sub_401000((int)&v26, strlen(&v26)); memset(&v26, 0, 0xFFFFu); v27 = v21; v26 = v20; v28 = v22; v5 = sub_401000((int)&v26, strlen(&v26)); if ( String == v7 + 34 && v19 == v11 && 4 * v20 - 141 == 3 * v9 && v21 / 4 == 2 * (v14 / 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; }
可以现将比对数组进行了一顿操作(从v7到v17)于是进到sub_4010F0函数里:
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代码,Python太弱 大神勿喷.....)
#include<bits/stdc++.h> using namespace std; 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; } char s[20]={90,74,83,69,67,97,78,72,51,110,103}; int main() { cout<<s<<endl; sub_4010F0(s,0,10); for(int i=0;i<=10;i++) cout<<s[i]<<','; cout<<endl;; }
输出是3,C,E,H,J,N,S,Z,a,g
再来看原函数 是将第678位和345位分别调用sub_401000函数,
进去看一下发现就是个base64加密,解密之后得到WP1jMp
在根据最后的判断,可以知道前两位是UJ
所以flag就是UJWP1jMp