刮开有奖
查壳发现是一个32位无壳
进入WINMain主函数
关键点在于DialogFunc函数里面,进去查看
看一遍下来通过代码GetDlgItemTextA(hDlg, 1000, &String, 0xFFFF);
知道了String是我们输入的flag。通过代码**if ( strlen(&String) == 8 )**,我们知道flag的长度应该是8。再从上往下慢慢分析,先给V7-V17赋值,进入函数sub_4010F0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| int __cdecl sub_4010F0(int a1, int a2, int a3) { int result; int i; int v5; int v6;
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; }
|
发现是一个排序的函数,将前面赋值的十个数从小到大排序
点击查看V23
V23等于string[5],依次可以看出V24等等
*v4 = (const char )sub_401000(&v26, strlen(&v26));,接下来继续看sub_401000
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
| _BYTE *__cdecl sub_401000(int a1, int a2) { int v2; int v3; size_t v4; _BYTE *v5; _BYTE *v6; int v7; _BYTE *v8; int v9; signed int v10; int v11; signed int v12; signed int v13; _BYTE *result; _BYTE *v15; _BYTE *v16; int v17; int v18;
v2 = a2 / 3; v3 = 0; if ( a2 % 3 > 0 ) ++v2; v4 = 4 * v2 + 1; v5 = malloc(v4); v6 = v5; v15 = v5; if ( !v5 ) exit(0); memset(v5, 0, v4); v7 = a2; v8 = v6; v16 = v6; if ( a2 > 0 ) { while ( 1 ) { v9 = 0; v10 = 0; v18 = 0; do { if ( v3 >= v7 ) break; ++v10; v9 = *(unsigned __int8 *)(v3++ + a1) | (v9 << 8); } while ( v10 < 3 ); v11 = v9 << 8 * (3 - v10); v12 = 0; v17 = v3; v13 = 18; do { if ( v10 >= v12 ) { *((_BYTE *)&v18 + v12) = (v11 >> v13) & 0x3F; v8 = v16; } else { *((_BYTE *)&v18 + v12) = 64; } *v8++ = byte_407830[*((char *)&v18 + v12)]; v13 -= 6; ++v12; v16 = v8; } while ( v13 > -6 ); v3 = v17; if ( v17 >= a2 ) break; v7 = a2; } v6 = v15; } result = v6; *v8 = 0; return result; }
|
看到这个就知道是熟悉的base64加密
1 2 3 4 5 6
| if ( String == v7 + 34 && string[1] == v11 && 4 * string[2] - 141 == 3 * v9 && string[3] / 4 == 2 * (v14 / 9) && !strcmp(v4, "ak1w") && !strcmp(v5, "V1Ax") )
|
看最后的一段代码
然后通过python脚本解密ak1w和V1Ax
1 2 3 4 5 6 7 8
| import base64 str1 = 'ak1w' str2 = 'V1Ax' flag1 = base64.b64decode(str1) flag2 = base64.b64decode(str2) print(flag1) print(flag2)
|
得到 jMp和WP1
上面第三行和第四行代码是比较 4*’x-141==3 *69 算出来x=87,是W
所以WP1在前面,flag就可以组合起来了