Archive for the ‘Chal6. ImagePrc Challenge’ Category

Run program, draw something and press check button. We’ll get the “Wrong” message box:


Figure 1

Load program to OllyDBG, search for all referenced text strings to find Wrong message:


Figure 2

Scroll up we can see a big loop that compare values at bl & cl, if not equal it will jump to the code displays wrong message:


Figure 3

Place bp at 004013A3 > > /8A11   mov   dl, byte ptr [ecx], press F9 to run, draw something and press check button, we will stop at bp. Look for the value store at [ecx] & [eax+ecx]:


Figure 4


Figure 5

Notice the 0x0047E060 address, this address belongs to rersource section (.rsrc):

Mem0ry map, item 22
 Size=00016000 (90112.)
 Owner=ImagePrc 00400000
 Type=Imag 01001002
 Initial access=RWE

Convert VA 0x0047E060 to Offset, we have 0x9060. Let’s use hex editor to open program, go to 0x9060:


Figure 6

Find and select all offsets has 0xFF value, we have the block size is:


Figure 7

This value corressponding with the number of iterations that we see in the loop check. So we know that the memory area pointed by ecx register must contains all the same value. How can we have theses value? Scroll up to the top of function, we see the code:

0040116A   .  8D4424 48    lea     eax, dword ptr [esp+0x48]
0040116E   .  50            push    eax                              ; /pPaintstruct
0040116F   .  56            push    esi                              ; |hWnd
00401170   .  FF15 E0504000 call    dword ptr [<BeginPaint>]         ; \BeginPaint

The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting. With this information, we guess that we have to draw something and then it can be used to compare with fixed data at offset 9060. Look at the code bellow BeginPaint:

0040117C   .  68 2000CC00           push    0xCC0020            ; /ROP = SRCCOPY
00401181   .  6A 00                 push    0x0                 ; |YSrc = 0x0
00401183   .  6A 00                 push    0x0                 ; |XSrc = 0x0
00401185   .  51                    push    ecx                 ; |hSrcDC => 0B0100AF
00401186   .  68 96000000           push    0x96                ; |Height = 96 (150.)
0040118B   .  68 C8000000           push    0xC8                ; |Width = C8 (200.)
00401190   .  6A 00                 push    0x0                 ; |YDest = 0x0
00401192   .  6A 00                 push    0x0                 ; |XDest = 0x0
00401194   .  50                    push    eax                 ; |hDestDC
00401195   .  FF15 30504000         call    dword ptr [<BitBlt>]; \BitBlt

The BitBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context. Scroll down a little bit, we see this code:

00401200   .  68 96000000           push    0x96                             ; /Height = 96 (150.)
00401205   .  68 C8000000           push    0xC8                             ; |Width = C8 (200.)
0040120A   .  56                    push    esi                              ; |hDC
0040120B   .  FF15 0C504000         call    dword ptr [<CreateCompatibleBitm>; \CreateCompatibleBitmap

The CreateCompatibleBitmap function creates a bitmap compatible with the device that is associated with the specified device context. Notice the Height and Width value, these value is the same with values at BitBlt call. Collect all information, we now know that we need to create a bitmap image with Height = 96 (150.) and Width = C8 (200.), and this image must contains 0x15F90 bytes from offset 0x9060. Let’s use mspaint to create a bitmap image with size is 200×150, open it in hex editor, then copy all data from offset 0x9060 and paste to offset of bitmap image that contains 0xFF values. Save image and open it, we get the flag:


Figure 8