Challenge RE #9
Published: 2023-09-19 15:54:50

Hi there, here we are again. This time with the [9th RE Challenge](https://challenges.re/9/) from [Dennis Yurichev](https://yurichev.com/). Let's see what we have this time, the [8th one](https://challenges.re/8/) I found it extremely instructive, specially because I saw in first hand how a structure it's declare or manage at the end.

By the way, if you found any error in my explanations feel free to reach out. Typos will be a lot, normally I don't pay attention to them, mainly because as long as you understand the idea an 's' at the end of a verb is not such big thing. Enough of silly talk, let's try to understand what this assembly code does.

## Analysis

The assembly code to understand is the following:

```asm
.LC0:
	.string	"error!"
f:
	sub	rsp, 8
	movzx	eax, BYTE PTR [rdi]
	cmp	al, 89
	je	.L3
	jle	.L21
	cmp	al, 110
	je	.L6
	cmp	al, 121
	jne	.L2
.L3:
	mov	eax, 1
	add	rsp, 8
	ret
.L21:
	cmp	al, 78
	je	.L6
.L2:
	mov	edi, OFFSET FLAT:.LC0
	call	puts
	xor	edi, edi
	call	exit
.L6:
	xor	eax, eax
	add	rsp, 8
	ret
```

First thing that we encountered is a null terminated string, with the word "error!"...no mystery here. As always let's try to figure out the signature of `f`, I find this step extremely useful, and from our previous challenge another thing that's useful is to identify a **struct** in the code. If there's any of course. Let's do that, and as always let's analyze by chunks of code:

```asm
f:
	sub	rsp, 8
	movzx	eax, BYTE PTR [rdi]
	cmp	al, 89
	je	.L3
	jle	.L21
    ;; ... more down in the code
.L3:
	mov	eax, 1
	add	rsp, 8
	ret
.L21:
	cmp	al, 78
	je	.L6
```

Here something to notice, is the comparison to numbers like **89**. This number it's expressed in decimal. Also previous to that comparison we got the read of one byte from `rdi` which it's compared to **89**. Mmm...no so hard to assume that in `rdi` we have our first parameter which it's a string. The code **89**  represents letter **Y** in ASCII code, so you are comparing the first letter in the string to **Y**. 

Depending on the result of the comparison, we jump to **.L3** or **.L21**, the first case when we have a equal case and the second one when our letter it's less than **Y**. For checking the ASCII table you can use this [link](https://www.ascii-code.com/).

Now, what we have in **.L3**? This is interesting, we basically return the function with `eax` equal **1**, and add 8 to the `rsp` register. Why this is needed? Easy, take into account that `rsp` is the __Stack pointer register__, at the start of the program we have the following instruction `sub rsp,8` and at the end we have `add rsp,8`. With these two instruction, first we allocate space on the stack and later de allocate it(how to write deallocate? Is it correct?).

Why we need 8 bits on the stack? This can be a pointer to **char** in C. Let's continue, the rest of the program can give us more clues.

In **.L21** we compare the character with **N** in ASCII code, in case it's equal to it we return **0** and deallocate the byte on stack that we allocated at the start of the program.

Let's put this into C code, this program seems fairly simple, just a couple of comparison to characters but still we need to see it by our own eyes. Given our previous discussion, we can infer that we receive a string on `rdi` and return an **int**. Fairly simple signature of f: 

```C
int f(char *str)
{
    char *result;

    if (*str == 'Y') {
        // mov	eax, 1
        // add	rsp, 8
        // ret
        return 1;
    }

    if (*str < 'Y') {
        if (*str == 'N') {
            return 0;
        }
    }
}
```

As always I'll clean this code later. The rest of the code, it's also comparisons to characters. For example:

```asm
	cmp	al, 110
	je	.L6
	cmp	al, 121
	jne	.L2
    ;; later down in the code...
    ;; ...
.L2:
	mov	edi, OFFSET FLAT:.LC0
	call	puts
	xor	edi, edi
	call	exit
.L6:
	xor	eax, eax
	add	rsp, 8
	ret
```

Here we compare this first byte with letter **n**, in case it's equal we jump to **.L6**, returning 0. Later a comparison to **y**, in this case if it's __not equal__ we print the string defined at the beginning, **error!**, and exit the program cleaning `edi` register where we stored our string.

I think we have everything to construct our code, let's do that.

```C
int f(char *str)
{
    char *result;

    if (*str == 'Y')
    {
        return 1;
    }

    if ((*str < 'Y') && (*str == 'N'))
    {
        return 0;
    }

    if (*str == 'n')
    {
        return 0;
    }

    if (*str != 'y')
    {
        puts("error!");
        exit(0);
    }

    return 1;
}
```

Kind of silly program to be honest 😂. One thing here to notice, is that the **result** variable that we saved in the stack was never used, at all.
This one doesn't deserve a formal description, too silly.

## Conclusion

I think this is the less interesting of all, to be fair the author warn you that the problems are not enumerated according to difficulty.