# Wapiflapi reverse engeneering exercices

Right now I'm trying to solve r5 from here

I've already tried to understand pseudo-code from Hooper

``````function check_password {
var_28 = arg0;
if (strlen(var_28) != strlen("this_is_not_even_interesting_its_garbage")) {
rax = 0xffffffff;
}
else {
strcpy("this_is_not_even_interesting_its_garbage", var_28);
var_18 = 0x1;
while (var_18 != 0x0) {
var_18 = 0x0;
for (var_14 = 0x0; var_14 <= 0x27; var_14 = var_14 + 0x1) {
if ((*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff) != 0x0) {
rax = random();
rcx = *(int8_t *)(sign_extend_64(var_14) + 0x6010a0) & 0xff & 0xff;
temp_3 = rax % rcx;
*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) = (*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff) - temp_3 + 0x1;
var_18 = var_18 | *(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff & 0xff;
*(int8_t *)(sign_extend_32(var_14) + "this_is_not_even_interesting_its_garbage") = (*(int8_t *)(sign_extend_32(var_14) + "this_is_not_even_interesting_its_garbage") & 0xff) - temp_3 + 0x1;
}
}
}
rax = *master;
rax = strcmp(rax, "this_is_not_even_interesting_its_garbage");
}
return rax;
}
``````

but it's too complicated for me right now. So I know that the password length should be 40 but how does the other part of the code work?

The unclear parts are the `unt8_t` casts. I've used gdb to step through the code, and I saw the results of certain instructions but cannot understand why these are the results ?

• The best way to start understanding these type of things it writing your own pseudo-code or simulator. That way you force yourself to actually read and comprehend the code in front of you. Have you tried doing that? What were the parts that were difficult? – NirIzr Aug 18 '16 at 21:12
• @Nirlzr first of all I tried to run this code in gdb with breakpoints. I can see two loops in asm code, but what happens next is some kind of magick for me. While running it with gdb I've figured out that the first value of rcx in loop was 3. But I'm not sure from where is that digit – desu Aug 18 '16 at 21:23
• So you'd say the line that you're having trouble with is `rcx = *(int8_t *)(sign_extend_64(var_14) + 0x6010a0) & 0xff & 0xff;`? Will you mind edit that in? Any other lines you're struggling with? – NirIzr Aug 18 '16 at 21:25
• @Nirlzr all that lines with cast to int8_t looks strange for me – desu Aug 18 '16 at 21:32
• @NirIzr I think that (int8_t *) is casting (sign_extend + offset) to the signed 8 bit int After that it takes the value from that pointer and doing bitwise and. But I don't know what result will it give to me. Looks like `int and 0xff` will always return int – desu Aug 18 '16 at 22:12

Although OP clarified only the inner `for` is unreadable to him, I'll write an answer that thoroughly explains the first few lines and then abruptly stops at the most crucial part of the inner for loop. While believing examples are a great way to learn, I do that to make this as educational as possible, without interfering with the learning process of independently solving exercises. I am also unfamiliar with the specific set of exercises and would like to avoid providing full answers where those were not intended by the creator.

I hope i hit that sweet spot of being educational enough yet not too much.

Good luck with the exercise, here goes:

`var_18 = 0x1;`

Set an internal state to 1.

`while (var_18 != 0x0) {`

While state is `True`, continue executing loop's content. The state is actually a boolean indicating processing is not finished yet.

`var_18 = 0x0;`

Set internal state to zero at every outer loop iteration. This means every iteration must set the "not finished yet" flag.

`for (var_14 = 0x0; var_14 <= 0x27; var_14 = var_14 + 0x1) {`

Inner for iterates 0x28 times, 40 in decimal. Since we know this is the length of the entire string, we can assume the inner loop somehow iterates over all characters of the string. This might be a coincidence, but we should keep an eye for it.

`if ((*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff) != 0x0) {`

Now here it gets a little bit more complicated, so we'll split it to several parts:

`sign_extend_32(var_14)`

Since we know var_14 is a non negative integer between 0 and 39 (including), there's no meaning to sign-extending it. Sign-extending is basically the operation of converting a shorter length value to longer, taking the sign bit into account. See this for more info about sign-extension. This is either a compiler or decompiler artifact. A more advanced decompiler might have removed this.

`(int8_t *)(sign_extend_32(var_14) + 0x6010a0)`

Add our `var_14` to a relatively long hex offset. By the looks of it, it's probably an offset to table of 40 bytes. This is learnt from experience, taking a look at value at that address might clear it up. Adding `var_14` and then casting to an int8 pointer further suggests that's the case, using `var_14` as the index in that table.

`(*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff)`

If we weren't convinced yet, by now it's pretty clear as we read a byte from the resulting offset. AND-ing it with 0xff is yet another decompiler artifact, caused by how a compiler will read a byte in 64bit intel processors.

`if ((*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff) != 0x0) {`

back to the full line, this is reading the byte from the table, and skipping the current iteraction of the inner loop.

`rax = random();`

Simple. Set a random value into `rax`.

`rcx = *(int8_t *)(sign_extend_64(var_14) + 0x6010a0) & 0xff & 0xff;`

This is actually quite identical to the condition from before, only now the value of that index in the table is stored into `rcx`.

## remaining lines of code

``````                                temp_3 = rax % rcx;
*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) = (*(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff) - temp_3 + 0x1;
var_18 = var_18 | *(int8_t *)(sign_extend_32(var_14) + 0x6010a0) & 0xff & 0xff;
*(int8_t *)(sign_extend_32(var_14) + "this_is_not_even_interesting_its_garbage") = (*(int8_t *)(sign_extend_32(var_14) + "this_is_not_even_interesting_its_garbage") & 0xff) - temp_3 + 0x1;
}
}
}
rax = *master;
rax = strcmp(rax, "this_is_not_even_interesting_its_garbage");
}
return rax;
``````