7 minute read



sushitake (Find the Flag) - Target

  • Name: Find the Flag
  • Author: sushitake
  • Platform: Windows
  • Architecture: x86-64
  • Language: C / C++
  • Difficulty: 2.0 (Beginner) 🟡
  • Quality: 4.9 ⭐
  • Upload Date: 2024-02-08
  • Description: A crackme reverse-engineering challenge. It can be solved dynamically, but in this writeup we will go through static reverse engineering. The target asks the user to enter a value that the program checks internally. The goal is to find the input that passes this check.

Running the target

After running the target, it asks the user to input the flag:

Program asks for flag

It shows an unlucky message and exits if the flag is incorrect:

Unlucky message


Now reverse-engineering time

I opened the target in IDA Pro and decompiled the main function. After decompiling, the first thing is to locate the success/fail decision.

Here is the if condition and we can see the unlucky message:

If condition shows unlucky

We can refactor that block into a clearer form like this:

Refactored if condition

Now we want yay printed instead of unlucky.


Identify user input

In the snippet below, the user input is stored in Block, then later copied into v10:

User input stored in Block then v10

Notice: v10 is used in the if condition, so we’re on the right track.


Identify the flag buffer

After analysing the snippet below, we can see that v9 is the flag buffer, and v15 is a pointer to v9. That explains why v15 appears in the if condition.

v9 flag buffer and v15 pointer

We can also notice overlapping writes used to confuse/obfuscate the final string.


Rebuild the flag by going through the overlapping writes

1) First write

It assigns v9 to the string "meow":

Assign v9 = meow

So the v9 value will look like:

v9 after first write

2) Second overlapping write

Second overlapping write snippet

This means we add the string "meow" again, but starting from index 3. If a position is already occupied, it gets overwritten.

Explaining start index 3 overwrite

In this case, v9 becomes:

v9 after second write

3) Third overlapping write (endianness trick)

Third overlapping write snippet

It starts from index 2. The tricky part: we can’t insert the hex directly as-is because x86 is little-endian (bytes are reversed in memory).

Instead of inserting bytes like this:

Incorrect byte order

We reverse them like this:

Correct little-endian byte order

To simplify, convert the hex to ASCII:

Hex to ASCII

Now add the ASCII into v9 + 2:

Write ASCII into v9+2

So v9 will be:

v9 after third write

4) Final overlapping write

Write s at index 10 snippet

This means we add "s" at index 10:

s added at index 10


This line adds the null terminator \0 so the program knows the string end:

Null terminator write


Final flag: meilovecats

Let’s try it:

Yay success

  • We get yay, which means we recovered the correct flag ✅
  • Thanks for reading! This challenge is a fun example of how overlapping memory writes can hide a flag, solved fully via static analysis.