FlareOn-9 Writeups 02 Pixel Poker

chall 02 banner

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: PixelPoker Window

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: PixelPoker import table

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: PixelPoker click function

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: PixelPoker update title

But also by this exit loop that kill the program when we reach the maximum number of incorrect guess: PixelPoker exit loop

We can spot an interesting comparison being made a bit latter (coming from the BitBlt() function): PixelPoker pixel comparison

For the first comparison, the values being checked are dword_412004 % width_cx, and dword_412008 % y.

  • dword_412004 have a constant value of 0x52414C46.
  • dword_412008 have a constant value of 0x6E4F2D45.

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: PixelPoker desired value

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: PixelPoker flag

w1nN3r_W!NneR_cHick3n_d1nNer@flare-on.com

PixelPoker solved