Tags: begginner friendly indepth 

Rating: 5.0

# ARMssembly 0

Category: Reverse Engineering

AUTHOR: DYLAN MCGUIRE

## Description
```
What integer does this program print with arguments 4134207980 and 950176538? File: chall.S
Flag format: picoCTF{XXXXXXXX} -> (hex, lowercase, no 0x, and 32 bits. ex. 5614267 would be picoCTF{0055aabb})
```

## Understanding the basics

I would say that I am somewhat comfortable with classic `x86` assembly, but I had to learn about `ARM` for this challenge (which I love! Learning new stuff is more than cool). So we can break down the first function, step by step:
```arm
func1:
sub sp, sp, #16
str w0, [sp, 12]
str w1, [sp, 8]
ldr w1, [sp, 12]
ldr w0, [sp, 8]
cmp w1, w0
bls .L2
ldr w0, [sp, 12]
b .L3
```
So here we go. `sp` stands for the stack pointer, and the `sub` instruction is a substraction with three components:
```
sub x,y, #z
```
Substract `#z` (# denotes a constant value) fro `y` and store it in `x`. Why is this instruction even here? It makes space on the stack for variables, and since we have two, substracting `16` should be just enough. In the next two lines we have some essential instructions:
```
str w0, [sp, 12]
str w1, [sp, 8]
```
`str` stands for `store`, and `w0` and `w1` are the user input variables. So we `store` the values in `w0` and `w1` on the stack (`sp`). The number denotes the offset on the stack. So `str w0, [sp, 12]` means `store w0 on the stack at offset 12`. Pretty neat.
```
ldr w1, [sp, 12]
ldr w0, [sp, 8]
```
Here we load the values from the stack at a given offset into a variable. So `load the value at offset 12 on the stack into w1` is equal to `ldr w1, [sp, 12]`. Also neat! And very important.
```
cmp w1, w0
```
Compare the values by substracting `w0` from `w1`. So basically a `sub` except that we do not store the value. Next!
```
bls .L2
```
Right, this is a `branch if less` instruction, if `w0` is smaller than `w1` `branch` or `jl` (for the x86 guys) to `.L2`. And at the end load a value again and `b` (simple branch `jmp` in x86). Very nice!

## Remaining functions

```
.L2:
ldr w0, [sp, 8]
.L3:
add sp, sp, 16
ret
.size func1, .-func1
.section .rodata
.align 3
```
At `.L2` we load a value from the `stack at offset 8` into the variable w0 and continue execution back in `func1`. In `.L3` we just `add` 16 back to `sp`, ie. we fill the stack back again.

## Main

```
main:
stp x29, x30, [sp, -48]!
add x29, sp, 0
str x19, [sp, 16] # 4134207980
str w0, [x29, 44] # 950176538
str x1, [x29, 32]
ldr x0, [x29, 32]
add x0, x0, 8
ldr x0, [x0]
bl atoi
mov w19, w0
ldr x0, [x29, 32]
add x0, x0, 16
ldr x0, [x0]
bl atoi
mov w1, w0 # w1 -> 950176538
mov w0, w19 # w0 -> 4134207980
bl func1
mov w1, w0
adrp x0, .LC0
add x0, x0, :lo12:.LC0
bl printf
mov w0, 0
ldr x19, [sp, 16]
ldp x29, x30, [sp], 48
ret
```
Here is the main function with my added "comments". So if we add everything together, what happens? If we just skip to the important bit, before branching to `.L3` the value from `[sp, 12]` is loaded and printed! So what is the flag?
```
picoCTF{f66b01ec}
```
Convert `4134207980` into a 32 bit hex string and that is it.

Original writeup (https://github.com/xnomas/PicoCTF-2021-Writeups/tree/main/ARMssembly-0).