首先是用exeinfope查看文件是否加壳,并同时查看该文件是32位还是64位
得出结论:32位无壳文件
然后用32位ida打开,找到main函数,再按F5反汇编
进入DialogFunc函数
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 ( a3 == 1001 ) { memset(String, 0, 0xFFFFu); GetDlgItemTextA(hDlg, 1000, String, 0xFFFF); if ( strlen(String) == 8 ) { v7[0] = 'Z'; v7[1] = 'J'; v8 = 'S'; v9 = 'E'; v10 = 'C'; v11 = 'a'; v12 = 'N'; v13 = 'H'; v14 = '3'; v15 = 'n'; v16 = 'g'; sub_4010F0(v7, 0, 10); memset(v18, 0, 0xFFFFu); v18[0] = String[5]; v18[2] = String[7]; v18[1] = String[6]; v4 = sub_401000(v18, strlen(v18)); memset(v18, 0, 0xFFFFu); v18[1] = String[3]; v18[0] = String[2]; v18[2] = String[4]; v5 = sub_401000(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 ( a3 != 1 && a3 != 2 ) return 0; EndDialog(hDlg, a3); return 1; }
这条语句可以判断出string的长度是8
变量在存储空间是按顺序排列的,由于v7[]到v16是按顺序声明的,所以这些变量可一起看作是v7数组。
进入sub_4010F0函数,往下拉,发现函数有递归,v7数组会发生改变,就写一个脚本
#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; }
运行结果是 3CEHJNSZagn,即为变化后的v7数组
返回DialogFunc函数,继续往下看
sub_401000函数被调用了两次,点进去查看
_BYTE *__cdecl sub_401000(int a1, int a2) { int v2; // eax int v3; // esi size_t v4; // ebx _BYTE *v5; // eax _BYTE *v6; // edi int v7; // eax _BYTE *v8; // ebx int v9; // edi int v10; // edx int v11; // edi int v12; // eax int i; // esi _BYTE *result; // eax _BYTE *v15; // [esp+Ch] [ebp-10h] _BYTE *v16; // [esp+10h] [ebp-Ch] int v17; // [esp+14h] [ebp-8h] int v18; // [esp+18h] [ebp-4h] 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 = *(v3 + a1) | (v9 << 8); ++v3; } while ( v10 < 3 ); v11 = v9 << (8 * (3 - v10)); v12 = 0; v17 = v3; for ( i = 18; i > -6; i -= 6 ) { if ( v10 >= v12 ) { *(&v18 + v12) = (v11 >> i) & 0x3F; v8 = v16; } else { *(&v18 + v12) = 64; } *v8++ = byte_407830[*(&v18 + v12++)]; v16 = v8; } v3 = v17; if ( v17 >= a2 ) break; v7 = a2; } v6 = v15; } result = v6; *v8 = 0; return result; }
byte_407830点进去查看是base64编码,因此这个函数的目的应该是把字符串转换为base64编码
接着返回DialogFunc函数往下看,有一个判断语句
“U g3t 1T!”和 “you get it”很像,说明满足以上6个判断条件就能得到flag了
#include <stdio.h> #include <string.h> int main() { char v7[] = "3C", v8 = 'E', v9 = 'H', v10 = 'J', v11 = 'N', v12 = 'S', v13 = 'Z', v14 = 'a', v15 = 'g', v16 = 'n'; char str[8] = { 0 }; str[0] = v7[0] + 34; str[1] = v10; str[2] = (3 * v8 + 141) / 4; str[3] = 2 * (v13 / 9) * 4; printf("%s", str); return 0; }
运行后,string的前四位为 UJWP
然后由v4和v5逆推string的3~8位
import base64 v4 = "ak1w"; v5 = "V1Ax"; flag1=base64.b64decode(v4) flag2=base64.b64decode(v5) print(flag1) print(flag2)
运行后再一一对照,str[5]=j,str[6]=M,str[7]=p,str[2]=W,str[3]=P,str[4]=1
连起来,得到flag: UJWP1jMp