---
# System prepended metadata

title: Assembly Writeup (pwn.college)

---

---
title: 'Assembly Writeup (pwn.college)'
---

Visit Course: https://pwn.college/computing-101/

---

# Most common byte
**Problem statement:**
First of all, the concept of new register is introduced in this problem which is RBP (Stack Base Pointer). It is used to to tell us where the stack frame first initialized from which is used to construct list. 

```assembly
; setup the base of the stack as the current top
mov rbp, rsp
; move the stack 0x14 bytes (5 * 4) down
; acts as an allocation
sub rsp, 0x14
; assign list[2] = 1337
mov eax, 1337
mov [rbp-0xc], eax
; do more operations on the list ...
; restore the allocated space
mov rsp, rbp
ret
```

As you can see, the rbp save the current rsp address which is used as the highest address in the contiguous list. Then substract rsp by 0x14 in order to initialize the list size. Using displacement (offset) to interact with list element (modify it)

>[!Warning] 
>We have to restore the stack to its base initialization or it will run out. As the aforemention, substract the exact willing list size. 

Now the real problem statement is to immplement this status satisify this

```c++
most_common_byte(src_addr, size):
  i = 0
  while i <= size-1:
    curr_byte = [src_addr + i]
    [stack_base - curr_byte * 2] += 1
    i += 1

  b = 0
  max_freq = 0
  max_freq_byte = 0
  while b <= 0xff:
    if [stack_base - b * 2] > max_freq:
      max_freq = [stack_base - b * 2]
      max_freq_byte = b
    b += 1

  return max_freq_byte
```
For more information read the full problem in lieu of these summary lines.

**Solution**:

```assembly
.intel_syntax noprefix
.global _start

.most_common_byte:
    # rdi is scr_addr, rsi is size
    # init rcx as a counter
    xor rcx, rcx

    push rbp
    mov rbp, rsp
    sub rsp, 600

    .while_restore:
        cmp rcx, 512
        jnb .exit_while_restore
        
        mov rax, rbp
        sub rax, rcx
        sub rax, 8
        mov WORD PTR [rax], 0

        add rcx, 2
        jmp .while_restore

    .exit_while_restore:

    # ------------------------------
    
    xor rcx, rcx
    .while_loop_1:
        cmp rcx, rsi
        jae .exit_loop_1

        movzx eax, BYTE PTR [rdi + rcx]
        mov edx, 2
        mul edx

        mov rdx, rbp
        sub rdx, rax
        sub rdx, 8

        inc WORD PTR [rdx]
        xor rdx, rdx
        
        inc rcx
        jmp .while_loop_1

    .exit_loop_1:

    # ------------------------------


    # ------------------------------
    xor rcx, rcx # b
    xor r9, r9 # max_freq 
    xor r10, r10 # max_freq_byte 

    .while_loop_2:
        cmp rcx, 0xff
        ja .exit_loop_2

    .if:    
        mov eax, ecx
        mov edx, 2
        mul edx

        mov rdx, rbp
        sub rdx, rax
        sub rdx, 8

        cmp WORD PTR [rdx], r9w
        jna .exit_if

        movzx r9, WORD PTR [rdx]
        mov r10, rcx

    .exit_if:
        inc rcx
        jmp .while_loop_2

    .exit_loop_2:
    # ------------------------------

    mov rax, r10

    mov rsp, rbp
    pop rbp

    ret

_start:
    call .most_common_byte

```

Well, I first initialize the most_common_bytes function and call it. 
Inside the function, I divided into three part. The first is to allocate list memory on stack as well as assigning all value equal to zero for further calculation. 

In order not to against the Call Convention. We have to accept the registe RDI as the scr_addr and RSI as the size in the function parameters. During the whole assembling process. There is a few notes that you may need to notice.

>[!Note]
>* At first glance, everyone knew it a Call Convention
>* Secondly, RBP is a callee-saved register. So you must rollback to its base value
>* Furthermore, when dereference the register, you have to specify its type. For example, `BYTE PTR`, `WORD PTR`, `DWORD PTR`, `QWORD PTR` for CPU to understand it. Noticely, [register] need to judge as a bytes and each value stored in stack is considered as 2-byte data which is DWORD.
>* Lastly, don't forget RAX is our last return value and the `ret` in the end.

The final flag is: `pwn.college{4w3wgqB5EEkY_TgOeuJsNS4zGGl.dZTMywiN3UTNzEzW}`


```

```