x86 Binary Bomb: Phase 2

Omar Mokhtar
4 min readMay 6, 2024

Previous Phases: Phase 1
Hello World! Today we’ll be continuing our journey through the phases of the binary bomb.

At the start of the second phase, it asks for an input: so I’ll be giving 1 2 3 4 5 6 as my input.

We find a function named read_six_numbers() which takes 2 arguments, the first is our input string and the second is a memory reference (which happens to be an already saved string from the first phase) as pointed by EDX and EAX registers respectively.

read_six_numbers(input_string,var_reference)

Stepping into read_six_numbers() we see that 6 pointers with 4 bytes offset differences are being pushed onto the stack (This indicates that these pointers point to a 32 bit value), along with a format specifier %d %d %d %d %d %d and our input string pointer and then sscanf() is called.

Arguments of sscanf()

As we know, sscanf() is a C library function that reads formatted input from a string. In our example here it attempts to read six integers (as noted by the format specifier) from our input string and then assigns each of these integers to memory locations referenced by EDX (var_reference argument to read_six_numbers() )

sscanf() returns the number of variables filled, so in order to take the jump and exit the read_six_numbers() successfully: we must input a string that contains 6 numbers, otherwise the jump will not be taken and we’ll go to explode_bomb() instead.

So this function only serves as some sort of input sanitization and converts our string input to integers.

Then the program checks if the first number of the 6 integers is a 1, if it’s a 1 then we skip the bomb.

After skipping the bomb, the program initially loads 0x1 into EBX and then loads the pointer to the first number of our input into ESI , Then the EAX register is loaded with EBX+1 .

EBX here serves as an index and also a counter, this is because it is used in an operand in an imul instruction as an index (multiplied by 4 so that memory offsets are 4 byte aligned) and is displaced by -0x04 indicating that it accesses the i-1 index assuming EAX has i.

The imul instruction multiplies the forementioned i-1 element with EAX which has the value of i .

Then EAX is compared with the same memory reference without the displacement which indicates that it points to ith element in the input integers, if they’re equal, we skip the bomb: and we increment EBX and then check if EBX is ≤ 0x5, if it is indeed then we reiterate and do the loop all over again.

So the main goal of this loop is that we skip over the bomb for each iteration in the loop.

What do we conclude from the behavior of this loop?

Assume that EAX has the value of i that means that EBX has the value of i-1 , what the entire loop does is that it checks if the i element in our input is equal to i * input[i-1] .

So that means that our input must be:
[1,1*2,1*2*3,1*2*3*4,1*2*3*4*5,1*2*3*4*5] == [1, 2, 6, 24, 120, 720]
What does this remind us of? You guessed it: The factorial.

I’ll be writing down pseudocode to illustrate what the loop does:

int phase_2(){
int inp[6] = {1,2,6,24,120,720};
int mul=1;
for (int i = 1;i<=5;i++){
mul = i * inp[i-1];
if (mul == inp [i]){
continue;
}
else{explode_bomb()};
}
phase_defused();
}

This is also an application of a very famous mathematical property of factorials that you’ve probably taken in high school:

So the final solution of the secondary phase is 1 2 6 26 120 720

That wraps up the 2nd phase, see you on the next one!

--

--

Omar Mokhtar

Malware Analyst and Reverse Engineer Under Construction