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