FlareOn-9 Writeups 02 Pixel Poker
Introduction
Description:
I said you wouldn’t win that last one. I lied. The last challenge was basically a captcha. Now the real work begins. Shall we play another game?
For this first real reverse-engineering challenge, an executable file is provided, “PixelPoker.exe”, along with a read-me that explained what this binary is about:
Welcome to PixelPoker ^_^, the pixel game that's sweeping the nation!
Your goal is simple: find the correct pixel and click it
Good luck!
Launching the binary gives us the following:
To win this game, it seems that we have to click to correct pixel from a 600+ / 700+ grid.
Let’s fire-up our disassembler and see if we can find a way to solve this.
Analysis
One way to quickly locate the interesting portion of code that deal with our pixel choice is to look in the import table of the binary:
All the imports from GDI32.dll are quite interesting, as they allow the program to interact with the graphic interface. More precisely, the GetPixel() function is a good starting point:
The GetPixel function retrieves the red, green, blue (RGB) color value of the pixel at the specified coordinates.
The function is called every time a pixel is clicked, for the purpose of two tasks: saving the coordinates of the last clicked pixel, and setting is value to the white color, to visually indicate that a pixel was clicked:
The function that call this one is a bit more interesting, as it seems to be the entry-point of the logic behind the graphical application (called at every “ticks” of the graphical interface). This can be observed by this call to SetWindowtextA(), which update the pixel position on the window title each time we hoover a new pixel:
But also by this exit loop that kill the program when we reach the maximum number of incorrect guess:
We can spot an interesting comparison being made a bit latter (coming from the BitBlt() function):
For the first comparison, the values being checked are dword_412004 % width_cx
, and dword_412008 % y
.
dword_412004
have a constant value of0x52414C46
.dword_412008
have a constant value of0x6E4F2D45
.
If we observe the content of the EDX
register on the cmp
instruction that occurs just after the check for the width_cx
, we obtain, for this particular pixel choice, the desired value of 0x5F
:
We can observe in our debugger that these conditions seems to always failed, as the pixel we click never satisfy the conditions on the X and Y coordinated.
To quickly circumvent the comparison, we simply have to invert the ZF (zero-flag) after the two comparisons. That way, we will force the program to reach a new interesting portion of code that is not accessible for now.
And this is enough to get the flag:
w1nN3r_W!NneR_cHick3n_d1nNer@flare-on.com