# 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

:::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

:::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

:::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)

- 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)

- 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 👉

:::
- ``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**

:::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

:::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

:::spoiler **LDR** and **STR**

```
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
```