前两天是第一届TSCTF初赛,很成功撒花~虽然出了几道题但是被秒不是那么开心/(ㄒoㄒ)/~~,拿专家学长和曹老师出的几道逆向学习一下,这题确实很有意思,所以写成writeup贴上来,专家学长和曹老师受我一拜~
首先来看一下简洁明快的界面~
拖到ida和Ollydbg里面,动态分析一下,在关键处下一些断点,找到程序的主逻辑,把地址放到ida里面查看代码。
大概的逻辑是,不停读取输入的字符,转换成小人的行走方向,然后让小人在迷宫里穿梭,最后找到"E"得到答案,答案是把所有的方向bit异或之后的值。当然不是那么简单就出来的啊,看了几个小时%>_<%还是太弱。
这个就是迷宫了~
下面是小人在走迷宫。
走出来界面是这样的~
把源码贴上来和反编译的代码比较下~为了提高速度,还是要多读读二进制啊,加密与解密之类的,加快速度把sqli和reverse搞定,渗透和pwn等着我呢~~
?
char __thiscall sub_401700(void *this, char *a2) { void *v2; // [email protected] int file; // [email protected] char *sum; // [email protected] char *addroftext; // [email protected] unsigned int v6; // [email protected] signed int count; // [email protected] int *addrlow2b; // [email protected] int valow2b; // [email protected] char sumv; // [email protected] char result; // [email protected] signed int v12; // [email protected] struct AFX_MODULE_STATE *v13; // [email protected] HBITMAP v14; // [email protected] 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; } |