Archive for the ‘Chal11. Direct3D_FPS Challenge’ Category

Run FPS.exe, we will start the game with a gun:


Figure 1

Use direction key to move character, we will see the strange doll. They can not die if we shoot them. The game will end if we touch them :).


Figure 2

Let’s use IDA and OllyDBG combination to analyse target. In OllyDBG, search all referenced text strings, we find the “Game Clear” string:


Figure 3

Double clicking on this string will bring us to the routine:


Figure 4

In IDA we have:


Figure 5

With this information, we can see that the text in message box is encrypted. So we need to decrypt this string. Follow in Dump in OllyDBG:


Figure 6

In IDA, select this text and press “X” to find another routine references to it.


Figure 7

Double clicking on sub_403400+2D:


Figure 8

This routine will be used to decrypt the text of message box. First, we see that the eax register is used as index of encrypted string, I named it is Msg_text. Value of eax is set by the call sub_403440, so that eax will have values in range [0…52], ecx = eax * 0x210. Ecx register is used as specific offset to set value to cl, then use xor to decrypt: Msg_txt[eax] = Msg_txt[eax] ^ cl. This is the pseudo-code for the snippet:

unsigned int sub_403400()
unsigned int i; // eax@1
unsigned int j; // ecx@2
int v2; // edx@2

i = sub_403440();
if ( i != 0xFFFFFFFF )
	j = 0x84 * i;
	v2 = dword_409190[0x84 * i];
	if ( v2 > 0 )
		dword_409190[j] = v2 - 2;
		dword_409194[j] = 0;
		Msg_text[i] ^= byte_409184[j * 4];
return i;

Try to set bp and debug in OllyDBG, we know cl register will have value is 0x0, 0x4, 0x8, 0xC,…


Figure 9

Here is the code to find the Flag:

#include <stdio.h>
#include <stdlib.h>

int main()
    unsigned char encrypted_str[52]={0x43, 0x6B, 0x66, 0x6B, 0x62, 0x75, 0x6C, 0x69, 0x4C, 0x45, 0x5C, 0x45, 0x5F, 0x5A, 0x46, 0x1C, 0x07, 0x25, 0x25, 0x29, 0x70, 0x17, 0x34, 0x39, 0x01, 0x16, 0x49, 0x4C, 0x20, 0x15, 0x0B, 0x0F, 0xF7, 0xEB, 0xFA, 0xE8, 0xB0, 0xFD, 0xEB, 0xBC, 0xF4, 0xCC, 0xDA, 0x9F, 0xF5, 0xF0, 0xE8, 0xCE, 0xF0, 0xA9, 0x00};
    unsigned char flag[100]={0};
    int i=0;

    for (i=0; encrypted_str[i]!=0;i++)
        flag[i] = encrypted_str[i] ^ (i*4);
    flag[i] = '\x00';

    printf("The right flag is: %s", flag);
    return 0;

Figure 10