Test file: https://adworld.xctf.org.cn/media/task/attachments/c6cf449ae4b7498eba5027c533386a40.exe
1. Prepare
getting information:
- 32 files
2.IDA Open
Disassembly main function
1 void sub_401100() 2 { 3 signed int v0; // esi 4 signed int v1; // esi 5 unsigned int v2; // edi 6 void **v3; // ebx 7 void **v4; // eax 8 int v5; // ecx 9 int v6; // ST04_4 10 int v7; // ST08_4 11 int v8; // ST0C_4 12 int v9; // eax 13 int v10; // ST0C_4 14 char *v11; // esi 15 int v12; // ecx 16 void **v13; // eax 17 int v14; // eax 18 int v15; // ST0C_4 19 int v16; // eax 20 int v17; // ST0C_4 21 int v18; // eax 22 int v19; // ST0C_4 23 int v20; // eax 24 int v21; // ST0C_4 25 int v22; // eax 26 int v23; // ST0C_4 27 int v24; // eax 28 int v25; // ST0C_4 29 int v26; // eax 30 int v27; // ST0C_4 31 int v28; // eax 32 int v29; // [esp-4h] [ebp-13Ch] 33 int Dst; // [esp+14h] [ebp-124h] 34 char v31[4]; // [esp+20h] [ebp-118h] 35 char v32; // [esp+24h] [ebp-114h] 36 int v33; // [esp+5Ch] [ebp-DCh] 37 char v34; // [esp+61h] [ebp-D7h] 38 int v35; // [esp+64h] [ebp-D4h] 39 int v36; // [esp+68h] [ebp-D0h] 40 char v37; // [esp+6Ch] [ebp-CCh] 41 FILE *File; // [esp+70h] [ebp-C8h] 42 char v39; // [esp+84h] [ebp-B4h] 43 void *v40; // [esp+CCh] [ebp-6Ch] 44 int v41; // [esp+DCh] [ebp-5Ch] 45 unsigned int v42; // [esp+E0h] [ebp-58h] 46 void *v43; // [esp+E4h] [ebp-54h] 47 unsigned int v44; // [esp+F4h] [ebp-44h] 48 unsigned int v45; // [esp+F8h] [ebp-40h] 49 void *Memory[4]; // [esp+FCh] [ebp-3Ch] 50 unsigned int v47; // [esp+10Ch] [ebp-2Ch] 51 unsigned int v48; // [esp+110h] [ebp-28h] 52 __int128 v49; // [esp+114h] [ebp-24h] 53 __int16 v50; // [esp+124h] [ebp-14h] 54 char v51; // [esp+126h] [ebp-12h] 55 int v52; // [esp+134h] [ebp-4h] 56 57 v45 = 15; 58 v44 = 0; 59 LOBYTE(v43) = 0; 60 v52 = 0; 61 v42 = 15; 62 v41 = 0; 63 LOBYTE(v40) = 0; 64 LOBYTE(v52) = 1; 65 v0 = 0; 66 v47 = 'dime'; 67 LOWORD(v48) = 'a'; 68 *(_OWORD *)Memory = xmmword_40528C; // htadimehtadimeht 69 v50 = '.<'; 70 v51 = 0; 71 v49 = xmmword_4052A4; // <<<....++++----> 72 do 73 { 74 sub_4021E0(&v40, 1u, (*((_BYTE *)Memory + v0) ^ *((_BYTE *)&v49 + v0)) + 22); 75 ++v0; 76 } 77 while ( v0 < 18 ); 78 v1 = 0; 79 v48 = 15; 80 v47 = 0; 81 LOBYTE(Memory[0]) = 0; 82 LOBYTE(v52) = 2; 83 v2 = v42; 84 v3 = (void **)v40; 85 do 86 { 87 v4 = &v40; 88 if ( v2 >= 0x10 ) 89 v4 = v3; 90 sub_4021E0(Memory, 1u, *((_BYTE *)v4 + v1++) + 9); 91 } 92 while ( v1 < 18 ); 93 memset(&Dst, 0, 0xB8u); 94 sub_401620(v5, v6, v7, v8); 95 LOBYTE(v52) = 3; 96 if ( v31[*(_DWORD *)(Dst + 4)] & 6 ) 97 { 98 v9 = sub_402A00(std::cerr, "?W?h?a?t h?a?p?p?e?n?", sub_402C50); 99 std::basic_ostream<char,std::char_traits<char>>::operator<<(v9, v10); 100 exit(-1); 101 } 102 sub_402E90(&Dst, &v43); 103 v11 = &v32; 104 if ( File ) 105 { 106 if ( !(unsigned __int8)sub_4022F0(&v32) ) 107 v11 = 0; 108 if ( fclose(File) ) 109 v11 = 0; 110 } 111 else 112 { 113 v11 = 0; 114 } 115 v37 = 0; 116 v34 = 0; 117 std::basic_streambuf<char,std::char_traits<char>>::_Init(&v32); 118 v35 = dword_408590; 119 File = 0; 120 v36 = dword_408594; 121 v33 = 0; 122 if ( !v11 ) 123 std::basic_ios<char,std::char_traits<char>>::setstate((char *)&Dst + *(_DWORD *)(Dst + 4), 2, 0); 124 v13 = Memory; 125 if ( v48 >= 0x10 ) 126 v13 = (void **)Memory[0]; 127 if ( sub_4020C0(&v43, v12, v44, (int)v13, v47) ) 128 { 129 v28 = sub_402A00(std::cout, "=W=r=o=n=g=K=e=y=", sub_402C50); 130 } 131 else 132 { 133 v14 = sub_402A00(std::cout, "|------------------------------|", sub_402C50); 134 std::basic_ostream<char,std::char_traits<char>>::operator<<(v14, v15); 135 v16 = sub_402A00(std::cout, "|==============================|", sub_402C50); 136 std::basic_ostream<char,std::char_traits<char>>::operator<<(v16, v17); 137 v18 = sub_402A00(std::cout, "|==============================|", sub_402C50); 138 std::basic_ostream<char,std::char_traits<char>>::operator<<(v18, v19); 139 v20 = sub_402A00(std::cout, "|==============================|", sub_402C50); 140 std::basic_ostream<char,std::char_traits<char>>::operator<<(v20, v21); 141 v22 = sub_402A00(std::cout, "\\ /\\ /\\ /\\ /\\==============|", sub_402C50); 142 std::basic_ostream<char,std::char_traits<char>>::operator<<(v22, v23); 143 v24 = sub_402A00(std::cout, " \\/ \\/ \\/ \\/ \\=============|", sub_402C50); 144 std::basic_ostream<char,std::char_traits<char>>::operator<<(v24, v25); 145 v26 = sub_402A00(std::cout, " |-------------|", sub_402C50); 146 std::basic_ostream<char,std::char_traits<char>>::operator<<(v26, v27); 147 std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_402C50); 148 v28 = sub_402A00(std::cout, "Congrats You got it!", sub_402C50); 149 } 150 std::basic_ostream<char,std::char_traits<char>>::operator<<(v28, v29); 151 sub_401570(&v39); 152 std::basic_ios<char,std::char_traits<char>>::~basic_ios<char,std::char_traits<four>>(&v39); 153 if ( v48 >= 0x10 ) 154 sub_402630(Memory[0], v48 + 1); 155 if ( v2 >= 0x10 ) 156 sub_402630(v3, v2 + 1); 157 if ( v45 >= 0x10 ) 158 sub_402630(v43, v45 + 1); 159 }
The last parameter 74 line calls sub_4021E0 function generates a character passed. Generating a string to link
#include <iostream>
#define _BYTE unsigned char
using namespace std;
int main()
{
const char* Memory = "themidathemidathemid";
const char* v50 = ">----++++....<<<<.";
signed int v0 = 0;
char str;
do {
str = (*(Memory + v0) ^ *(v50 + v0)) + 22;
cout << str;
++v0;
} while (v0 < 18);
system("PAUSE");
return 0;
}
`[^ VZe`uYaY]` s ^ joY
3.OD Open
Output is this program opens
OD opened after use, to locate the string, the instructions can be found in front of the input string to skip this
00211233 . 8B40 04 mov eax,dword ptr ds:[eax+0x4] 00211236 . F68405 E8FEFF>test byte ptr ss:[ebp+eax-0x118],0x6 0021123E 74 25 je Xkey.00211265 00211240 . 8B0D C8502100 mov ecx,dword ptr ds:[<&MSVCP140.std::ce>; MSVCP140.std::cerr 00211246 . BA E4522100 mov edx,key.002152E4 ; ASCII "?W?h?a?t h?a?p?p?e?n?" 0021124B . 68 502C2100 push key.00212C50 00211250 . E8 AB170000 call key.00212A00 00211255 . 8BC8 mov ecx,eax 00211257 . FF15 98502100 call dword ptr ds:[<&MSVCP140.std::basic>; MSVCP140.std::basic_ostream<wchar_t,std::char_traits<wchar_t> >::operator<< 0021125D . 6A FF push -0x1 ; /status = FFFFFFFF (-1.) 0021125F . FF15 68512100 call dword ptr ds:[<&api-ms-win-crt-runt>; \exit
Therefore, we can determine, this string is a smoke bomb, so we can not really enter the program, but the real key just below.
4. Analysis Code
if ( v48 >= 0x10 ) v13 = (void **)Memory[0]; if ( sub_4020C0(&v43, v12, v44, (int)v13, v47) ) { v28 = sub_402A00(std::cout, "=W=r=o=n=g=K=e=y=", sub_402C50); } else {
...
By this code, we can know, sub_4020C0 function on the hidden key, the corresponding code OD found, set a breakpoint
00211317 . FF75 D4 push dword ptr ss:[ebp-0x2C] 0021131A . 0F4345 C4 cmovnb eax,dword ptr ss:[ebp-0x3C] 0021131E . 50 push eax 0021131F . FF75 BC push dword ptr ss:[ebp-0x44] 00211322 . 51 push ecx 00211323 . 8D4D AC lea ecx,dword ptr ss:[ebp-0x54] 00211326 . E8 950D0000 call key.002120C0
In front of all the parameters of the function, the breakpoint operation
At the register, we found the key we need
5.get flag!
idg_cni ~ bjbfi | gsxb