---
# System prepended metadata

title: ARM
tags: [arm]

---

# ARM
- luyện tập trên 2 kiến trúc 'i386' và 'amd64' cũng đã nhiều
- nên blog này sẽ nghiên cứu về kiến trúc ARM là chủ yếu
> không lạ cũng không mới, khả năng gặp nhiều trong các bài CTF-pwnable
## overview
- ARM Cortex – Mx là vi xử lý được sử dụng phổ biến nhất hiện nay trong lĩnh vực hệ thống nhúng
- **ARM** (viết cách điệu là **arm**) full name là **Advanced RISC Machine**
- là một họ kiến trúc dạng [RISC](https://vi.wikipedia.org/wiki/RISC) cho các [vi xử lý máy tính](https://vi.wikipedia.org/wiki/CPU), được cấu hình cho các môi trường khác nhau

## registers
### :open_file_folder: ARM 32-bits
#### 1. Thanh ghi cơ bản
![image](https://hackmd.io/_uploads/ByG8-jxWkg.png)
:::info
- thanh ghi từ **`R0`** tới **`R10`** (trừ **`R7`**) là  **general purpose register** .
- Lưu trữ dữ liệu của các phép tính toán, lưu trữ địa chỉ.
- có độ rộng 32bit.
- Ngoài ra, **`R0`**-**`R5`** sẽ dùng để setup hàm system call
:::
#### 2.  Thanh ghi quan trọng
![image](https://hackmd.io/_uploads/rJRlfsx-Jl.png)
:::info
- **`R7`** sẽ là **`syscall number`** :  [system call table in ARM ](https://arm.syscall.sh/)
- **`R13`** được gọi là **`Stack Pointer`** (SP) sẽ trỏ tới thành phần nằm trên đỉnh của stack
- **`R14`** được gọi là **`Link Register (LR)`** sử dụng để lưu và trả lại vị trí của hàm
    - Ngoài ra, **`R14`** còn lưu thông tin của subroutines, function call và exceptions
- **`R15`** được gọi là **`Program Counter (PC`**) sẽ trỏ tới tập lệnh tiếp theo được lấy từ bộ nhớ, bộ xử lý sẽ thực hiện lệnh này sử dụng PC sau đó sẽ tăng PC lên
    - :point_right: Thanh ghi này chứa địa chỉ câu lệnh sẽ được thực thi
:::
##### :key: So sánh giữa x86 và ARM 32-bit
![image](https://hackmd.io/_uploads/HJhkNjx-Jg.png)

:::spoiler 👉 More information
- Với cấu trúc của ARM là **AAPCS** (**A**RM **A**rchitecture **P**rocedure **C**all **S**tandard), một phần của **ABI** (**A**pplication **B**inary **I**nterface) sẽ sử dụng các thanh ghi R0, R1, R2 để đưa các tham số đầu vào vào hàm C, các tham số được trả lại nằm trong thanh ghi R0
- giả định **SP** sẽ luôn là **MSP** (**M**ain **S**tack **P**ointer) chứ không phải là **PSP** (**P**rocess **S**tack **P**ointer)
:::
- có 3 trạng thái của thanh ghi là:
    -  **APSR** (**A**pplication **P**rogram **S**tatus **R**egister)
    -  **IPSR** (**I**nterrupt **P**rogram **S**tatus **R**egister)
    -  **EPSR** (**E**xecution **P**rogram **S**tatus **R**egister)

![image.png](https://hackmd.io/_uploads/S1B75OU7T.png)

- ngoài ra còn có 1 trạng thái thường thấy nhất khi debug ARM32 là **CPRS** (**C**urrent **P**rogram **S**tatus **R**egister)

![image](https://hackmd.io/_uploads/rkTbxtRXa.png)

- các bit ``N,Z,V,C,Q`` đưa thông tin về kết quả của quá trình tính toán ALU trước đó
    - ``N`` bit được set sau một phép tính số học hoặc logic để xác định kết quả có là âm hay không
    > identicial to **SF** in EFLAG register on x86
    - ``Z`` bit được set nếu kết quả là 0
    > identicial to **ZF** in EFLAG register on x86
    - ``C`` bit được set khi tràn giá trị unsigned
    > identicial to **CF** in EFLAG register on x86
    - ``V`` bit được set khi tràn giá trị signed
    > identicial to **OF** in EFLAG register on x86
    - ``Q`` bit khi trạng thái “bão hòa” xảy ra
    - ``T`` bit luôn là 1 thực hiện các tập lệnh Thumb® của ARM®Cortex™-M
:::spoiler more info 👉
![image](https://hackmd.io/_uploads/H1NZWY0Q6.png)
:::

- ``ISR_NUMBER`` cho thấy ngắt nào đang được xử lý
> cái này liên quan đến "ngắt" - là thành phần rất quan trọng trong một hệ thống nhúng
> là phần mềm kích hoạt phần cứng hoạt động


### :open_file_folder: ARM 64-bits
#### Thanh ghi cơ bản
- còn 1 cái tên khác là **aarch64**
![image](https://hackmd.io/_uploads/r1Dx8colA.png)
:::info
- Từ **`X0-X28`** : là **general purpose register**
- Trừ **`X8`** : `Syscall number` khi gọi hệ thống
- Ngoài ra, **`X0-X5`** để setup system call
:::

#### Thanh ghi quan trọng
![image](https://hackmd.io/_uploads/HJL8DaeWJx.png)
:::info
- **`X29`** : Giống RBP (frame pointer)
- **`SP`** : giống RSP (Stack pointer)
- **`X30`** : lưu saved RIP của hàm (LR-Link Register)
- **`PC`** : giống RIP (program counter)
- **`X8`** : syscall number 
:::

## Intructions
- xem [link](https://hocarm.org/lap-trinh-hop-ngu-voi-arm/)
### ARM32
- có một số lệnh cơ bản như:
    - ``MOV R0, #1`` : đưa 1 vào R0
    - ``ADD R1, R2, R3`` : cộng R2 với R3 và đưa vào R1
    - ``LDR R3, [R8]`` : đưa giá trị trong R8 vào R3
    - ``POP {R3,PC}`` : đưa PC (trên stack hiện tại) vào R3
### ARM64
- tương đồng ARM32 nhưng có 1 số minor change

| Opcode | Purpose                                                    |
|--------|------------------------------------------------------------|
| MOV    | Used to copy values.                                       |
| MOVN   | Used to copy negative values.                              |
| LSL/LSR| Logical shift left, Logical shift right.                   |
| LDR    | Load data from the memory to the register.                 |
| STR    | Store data from the register to the memory.                |
| LDP    | Load a pair of values to the registers.                    |
| STP    | Store a pair of values to memory.                          |
| ADR    | Loads an address within a certain range, without performing a data load. | 
| CMP    | Compare two values, flags are updated automatically.       |
| B      | ``B <label>`` performs a direct, PC-relative, branch to ``<label>``. |
| BR     | `BR` performs an indirect, or absolute, branch to the address specified. |
| BLR    | Branch to a register and stores the address of the next instruction into the link register (x30).  |

### example
![image](https://hackmd.io/_uploads/SkeibKAQT.png)

:::spoiler **LDR** and **STR**
![image](https://hackmd.io/_uploads/Sk-WMF0X6.png)
```
LDR R2, [R0]   @ [R0] - origin address is the value found in R0.
STR R2, [R1]   @ [R1] - destination address is the value found in R1.
```
- **LDR** operation: loads the value at the address found in **R0** to the destination register **R2**
- **STR** operation: stores the value found in **R2** to the memory address found in **R1**

```asm
# Offet form:  Immediate value as the offset
STR    Ra, [Rb, imm]
LDR    Ra, [Rc, imm]
```

```asm
# Offset form: Register as the offset
STR    Ra, [Rb, Rc]
LDR    Ra, [Rb, Rc]
```

```asm
# Offset form: Scaled register as the offset
LDR    Ra, [Rb, Rc, <shifter>]
STR    Ra, [Rb, Rc, <shifter>]
```
:::
## document
- [ARM-32 Intrucction Set](https://docs.google.com/viewerng/viewer?url=https://iitd-plos.github.io/col718/ref/arm-instructionset.pdf)
- [ARM-64 Course · Reverse Engineering](https://0xinfection.github.io/reversing/pages/arm-64-course.html)
- [ARM64 Assembly Language Notes](https://cit.dixie.edu/cs/2810/arm64-assembly.html)

## DEBUG ARM 
### 1. Set up
```terminal
$ sudo apt-get install qemu
$ sudo apt-get install gdb-multiarch
$ sudo apt install qemu-system-arm
$ git clone https://git.qemu.org/git/qemu.git
$ cd qemu
$ #gỡ rối BEGIN
$ sudo apt-get install sphinx
$ pip install sphinx_rtd_theme==1.1.1
$ sudo apt-get install ninja-build
$ sudo apt-get install libpixman-1-dev 
$ sudo add-apt-repository ppa:gnome3-team/gnome3-staging
$ sudo apt-get update
$ sudo apt update
$ sudo dpkg --add-architecture i386
$ sudo apt install libc6:i386
$ sudo apt-get install libgvnc-1.0-dev
$ sudo apt-get install device-tree-compiler
$ sudo apt-get install libfdt-dev
$ sudo apt-get install libcapstone-dev
$ #nếu còn nhiều lỗi hiện 'NO' khi cài, cứ quăng hỏi chatgpt =))))
$ #gỡ rối END
$ ./configure --target-list=arm-softmmu,aarch64-softmmu && make
```
### 2. Debug tĩnh (static)
#### 2.1 Set up
```terminal
$ sudo apt-get install libc6-dev-armhf-cross
$ sudo apt-get install gcc-arm-linux-gnueabihf
```
#### 2.2 Debug


|          Terminal 1           |             Terminal 2              |
|:-----------------------------:|:-----------------------------------:|
| $ qemu-aarch64 -g <port> <binary> |    $ sudo gdb-multiarch <binary>    |
|                               | gef➤ target remote localhost:<port> |

### 3. Debug động (dynamic)
#### 3.1 Set up tools
```c
$ sudo apt-get install qemu-user
$ sudo apt-get install qemu-user-static
$ sudo apt-get install libc6-arm64-cross
$ apt-cache search 'libstdc++' | grep arm64
$ sudo mkdir /etc/qemu-binfmt
$ sudo ln -s /usr/aarch64-linux-gnu /etc/qemu-binfmt/aarch64
```

#### 3.2 Set-up DEBUG
##### 3.2.1 Script exploit
```py
context.binary = exe = ELF('./chall',checksec=False)
# p = process(exe.path)
p = process(['qemu-aarch64', '-g' ,'1234' ,'./chall'])
context.log_level = 'debug' 
raw_input('DEBUGING...')
```

##### 3.2.2 File debug.dbg (set-up breakpoint)
- Bản chất file này thay vì set bp trong gdb thì mình ghi nó vào file để giảm thời gian
```
file chall
set architecture aarch64
target remote localhost:9999
b*<bp>
c
```
#### 3.3 Debug


| Terminal 1 | Terminal 2 |
| ---------- | ---------- |
| $ ./solve.py DEBUG       |$ gdb-multiarch -q -x debug.dbg       |
    
## Build ARM
- Cài đặt 
    ```
    sudo apt update
    sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
    ```
- Build binary
    ```
    aarch64-linux-gnu-gcc program.c -o program_arm64
    ```
    