前两天是第一届TSCTF初赛,很成功撒花~虽然出了几道题但是被秒不是那么开心/(ㄒoㄒ)/~~,拿专家学长和曹老师出的几道逆向学习一下,这题确实很有意思,所以写成writeup贴上来,专家学长和曹老师受我一拜~
首先来看一下简洁明快的界面~
拖到ida和Ollydbg里面,动态分析一下,在关键处下一些断点,找到程序的主逻辑,把地址放到ida里面查看代码。
大概的逻辑是,不停读取输入的字符,转换成小人的行走方向,然后让小人在迷宫里穿梭,最后找到"E"得到答案,答案是把所有的方向bit异或之后的值。当然不是那么简单就出来的啊,看了几个小时%>_<%还是太弱。
这个就是迷宫了~
下面是小人在走迷宫。
走出来界面是这样的~
把源码贴上来和反编译的代码比较下~为了提高速度,还是要多读读二进制啊,加密与解密之类的,加快速度把sqli和reverse搞定,渗透和pwn等着我呢~~
char __thiscall sub_401700(void *this, char *a2) { void *v2; // ebx@1 int file; // ebp@1 char *sum; // esi@3 char *addroftext; // edi@4 unsigned int v6; // ecx@5 signed int count; // edx@5 int *addrlow2b; // ecx@5 int valow2b; // eax@6 char sumv; // al@11 char result; // al@19 signed int v12; // eax@20 struct AFX_MODULE_STATE *v13; // eax@22 HBITMAP v14; // eax@22 const CHAR *v15; // [sp-Ch] [bp-53Ch]@2 const CHAR *v16; // [sp-8h] [bp-538h]@2 char v17; // [sp+10h] [bp-520h]@1 char v18; // [sp+11h] [bp-51Fh]@1 …… char v33; // [sp+20h] [bp-510h]@1 char v34; // [sp+21h] [bp-50Fh]@22 unsigned int low; // [sp+24h] [bp-50Ch]@5 int v36; // [sp+28h] [bp-508h]@5 …… int v98; // [sp+120h] [bp-410h]@1 char Text[1024]; // [sp+124h] [bp-40Ch]@3 int v100; // [sp+52Ch] [bp-4h]@1
v2 = this; v43 = dword_42D324; v44 = dword_42D328; …… v62 = dword_42D2E0; v63 = dword_42D2C4; v100 = 0; v64 = dword_42D2C8; v65 = dword_42D2CC; v66 = dword_42D2D0; v17 = 25; v18 = '; v19 = '; v20 = '\x03'; v21 = -108; v22 = -99; v23 = 10; v24 = 12; v25 = 32; v26 = 115; v27 = 117; v28 = 112; v29 = -40; v30 = -91; v31 = -92; v32 = -115; v33 = -106; v39 = dword_42D314; v40 = dword_42D318; …… v97 = dword_42D31C; v98 = dword_42D320; file = openfile(a2, (int)aRb); if ( file ) { bufinit((int)&v39); Text[0] = getchar((FILE *)file); sum = (char *)&v43 + 1; if ( !(*(_BYTE *)(file + 0xC) & 0x10) ) { addroftext = Text; while ( 2 ) { v6 = (unsigned __int8)*addroftext; low = v6 >> 6; // 模4? v36 = (signed int)(v6 >> 4) % 4; // 先模16再模4的余数 v6 = (signed int)v6 % 16; // 模16的余数 v37 = (signed int)v6 / 4; // 除4的整数 v38 = (signed int)v6 % 4; // 模4的余数 count = 0; addrlow2b = (int *)&low; do { valow2b = *addrlow2b; *sum = ' '; switch ( valow2b ) // 判断a0 a1 { case 0: // 注意,这里是前进后退,别搞错了! sum -= 16; break; case 1: ++sum; break; case 2: sum += 16; break; case 3: --sum; break; default: break; } sumv = *sum; if ( *sum == 'W' ) { v16 = aGiveMyAliceBac; v15 = aEasenseAliceCa; goto LABEL_19; } if ( sumv == ' ' ) { v16 = Caption; v15 = ::Text; goto LABEL_19; } if ( sumv == 'E' ) // v10需要等于69,构造第一个字符 { v12 = 0; do { *(&v17 + v12) ^= Text[v12]; ++v12; } while ( v12 <= 16 ); v34 = 0; v13 = AfxGetModuleState(); v14 = LoadBitmapA(*((HINSTANCE *)v13 + 2), (LPCSTR)0x87); SendMessageA(*((HWND *)v2 + 45), 0xF7u, 0, (LPARAM)v14); strcpy(Text, aEasenseIFinall); strcat(Text, &v17); strcat(Text, aAliceBnbnbnbnw); sub_41A2CD(Text, aTryAnotherAlic, 0x41u);// 就是这!为什么还给一个another alicebob,混淆? goto LABEL_23; } ++count; ++addrlow2b; // 应该是连一起的,这里应该是下2个bit了 *sum = 'A'; // 这个地方用65有用吗,上面不是有改成32了? } while ( count <= 3 ); ++addroftext; *addroftext = getchar((FILE *)file); if ( !(*(_BYTE *)(file + 12) & 16) ) continue; break; } } LABEL_23: fclose((FILE *)file); v100 = -1; sub_41B968(&a2); result = 1; } else { v16 = aCanNotFindAnyA; v15 = aEasenseWhereIs; LABEL_19: sub_41A2CD(v15, v16, 0x11u); v100 = -1; sub_41B968(&a2); result = 0; } return result; } |
bool CAliceAndBobDlg::Check_Serial(CString file_name) { //1122 3322 2111 1222 3322 3322 1111 1001 1001 0000 0001 0111 2222 3322 2112 2332 2211 //5a fa 95 6a fa fa 55 41 41 00 01 15 aa fa 96 be a5 char flag[] = {0x19, 0x95, 0xF1, 0x03, 0x94, 0x9D, 0x0A, 0x0C, 0x20, 0x73, 0x75, 0x70, 0xD8, 0xA5, 0xA4, 0x8D, 0x96};
char misc[15][16]={"WWWWWWWWWWWWWWW", "WA WWWWWW W", "WWW WWWWW WW W", "W WWWWW WWW W", "W WWWWWWW WWW W", "W WWWWWWW W W", "W WWW W WWW", "WWWWW WWW W WWW", "WWWWW WWW W W", "WWW WW WWW W", "WWW WWWW WW W", "W WW WW WWW", "W WWWW WWWW WWW", "W WWWW EW", "WWWWWWWWWWWWWWW"};
FILE *file = fopen(file_name, "rb");
if (file == NULL) { MessageBox("Easense: Where is my dear \"Alice\"? o.O", "Can not find any \"Alice\" here...", MB_OKCANCEL | MB_ICONERROR); return false; }
change_to_love(misc);
int ii=0; unsigned char a[1024]; a[ii] = getc(file);
char *p_check = &misc[1][1];
int code[4]; while (!feof(file)) { code[0] = (a[ii]/16) / 4; code[1] = (a[ii]/16) % 4; code[2] = (a[ii]%16) / 4; code[3] = (a[ii]%16) % 4;
for (int k=0; k<=3; k++) { *p_check = ' '; switch (code[k]) { //0 for up //1 for right //2 for down //3 for left case 0: p_check -= 16; break;
case 1: p_check += 1; break;
case 2: p_check += 16; break;
case 3: p_check -= 1; break;
default: break; }
if (*p_check == 'W') { MessageBox("Easense: Alice can not pass the wall! O.o", "Give my Alice back...", MB_OKCANCEL | MB_ICONERROR); return false; } else if (*p_check == ' ') { MessageBox("Easense: Alice can not go back! O.O", "I want my Alice...", MB_OKCANCEL | MB_ICONERROR); return false; } else if (*p_check == 'E') { for (int jj=0; jj<=16; jj++) { flag[jj] ^= (char)a[jj]; } flag[17] = '\0'; HBITMAP bmp; bmp = LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(SUCCESS)); this->m_btn_easense.SetBitmap(bmp);
char buf[1024]; strcpy(buf, "Easense:\r\nI finally meet you! Alice! o(∩_∩)o \r\nI want to tell you that——TSCTF{"); strcat(buf, flag); strcat(buf, "}\r\n\r\nAlice:\r\n…………WTF?\r\nI just want my Bob! QAQ");
MessageBox(buf, "Try another Alice and Bob!", MB_OKCANCEL | MB_ICONINFORMATION); fclose(file); return true; } else//心 { *p_check = 'A'; } }
ii++; a[ii] = getc(file); }
fclose(file);
return true; }
bool CAliceAndBobDlg::change_to_love(char misc[15][16]) { for (int i=0; i<=14; i++) { for (int j=0; j<=15; j++) { if (misc[i][j] == ' ') { misc[i][j] = (char)36; } } }
return true; } |