The second session of ctf.360.cn, the fourth question of reverse part of writeup--
Topic: see attachment
This question is starting to get a little complicated.
When you run the program, you can see the interface as follows
Pay attention to "hiding information is over!" The position of the string
Search push 40405c directly to find the code location 401a48.
Search the Internet to find the entry address of the code block 4017a0. Obviously this is a very long function that uses IDA for static analysis.
V2 = CreateFileA (* (LPCSTR *) v1 + 24), 0x80000000u, 1U, 0,3U, 0x80u, 0); if (v2 = = (HANDLE)-1) {result = CWnd::MessageBoxA (v1, & unk_4040D4, 0,0);} else {v4 = CreateFileA (* ((LPCSTR *) v1 + 26), 0x80000000u, 1U, 0,3U, 0x80u, 0); hObject = v4 If (v4 = = (HANDLE)-1) {result = CWnd::MessageBoxA (v1, & unk_4040BC, 0,0);} else {v33 = CreateFileA (* ((LPCSTR *) v1 + 25), 0x40000000u, 1U, 0,2u, 0x80u, 0); if (v33 = = (HANDLE)-1) {result = CWnd::MessageBoxA (v1, & unk_40409C, 0,0) } else {SetFilePointer (v2,2,0,0); ReadFile (v2, & Buffer, 4U, & NumberOfBytesWritten, 0); SetFilePointer (v2,4,0,1U); ReadFile (v2, & v35,4U, & NumberOfBytesWritten, 0); SetFilePointer (v2,0,0,0); v5 = operator new (Buffer); lpBuffer = v5 ReadFile (v2, (LPVOID) v5, Buffer, & NumberOfBytesWritten, 0); v6 = (int) ((char *) v5 + v35); v7 = GetFileSize (v4,0); v31 = v7; v28 = operator new (v7); ReadFile (hObject, v28, v7, & NumberOfBytesWritten, 0); v8 = Buffer-v35-32; if (8 * v7 > = 1; + V6) -- v9;} while (v9); v14 = 16; v25 = v7 > > 16; do {LOWORD (v10) = * (_ BYTE *) v6 & 1; v10 ^ = v25 & 1 If ((_ WORD) v10) {v11 = (rand () & 1) = 0; v15 = * (_ BYTE *) v6; if (v11) v16 = v15-1; else v16 = v15 + 1; * (_ BYTE *) v6 = v16 } LOWORD (v25) = (unsigned _ int16) v25 > > 1; + + v6;-- v14;} while (v14); v17 = 0; v26 = 0; if (v7) {do {v18 = 8 V19 = * ((_ BYTE *) v28 + v17); do {if ((v19 ^ * (_ BYTE *) v6) & 1) {v11 = (rand () & 1) = 0; v20 = * (_ BYTE *) V6 If (v11) v21 = v20-1; else v21 = v20 + 1; * (_ BYTE *) V6 = v21;} v19 > > = 1; + + v6;-- v18 } while (v18); v17 = v26 others + + 1;} while (v26 < v31);} v22 = lpBuffer; v23 = v33; WriteFile (v33, lpBuffer, Buffer, & NumberOfBytesWritten, 0); operator delete ((void *) v22); operator delete (v28) CloseHandle (v2); CloseHandle (hObject); CloseHandle (v23); result = CWnd::MessageBoxA (v30, & unk_40405C, 0,0);} else {result = CWnd::MessageBoxA (v30, & unk_40406C, "Caption", 0);} return result
To understand the code, you first need to understand the format of the bmp file, which you can refer to http://www.cnblogs.com/kingmoon/archive/2011/04/18/2020097.html.
In fact, the algorithm of the topic is to skip the bmp header and the first 32 bytes of pixels, and then encode one plaintext byte to be encrypted every 8 bytes. The last bit of each pixel byte is used to represent the response bit of the plaintext byte to be encrypted.
+ 1 and-1 in the code are actually corrected to the same when the last bit of the pixel byte is inconsistent with the corresponding bit of the plaintext byte.
So if you know the algorithm, you will know how to decrypt it: take out the last bit of the byte containing the ciphertext and spell out the corresponding plaintext.
Extract the source code and do not post it.