x86 Assembly - ianchen0119/About-Security GitHub Wiki

Register

General puspose

  • rax (accumulator)
  • rbx (base)
  • rcx (count)
  • rdx (data)
  • rsi (source index)
  • rdi (destination index)
  • rbp (base pointer)
  • rsp (stack pointer)
  • rip (instruction pointer)

rip could not be dest.

用於記錄下一個要執行的instruction

r[a-d]x register layout

+----------+
|    |  |  |
+----------+
0          63
  • r[a-d]x (64 bits)
  • e[a-d]x (32 bits)
  • [a-d]x (16 bits)
  • [a-d]h (8 bits)
  • [a-d]l (8 bits)

Stack

由兩個 register (rsp 與 rbp) 指向的記憶體空間,用來記錄:

  • return address
  • local variable

一開始 rbp 與 rsp 的位址相同

    push   rbp
    mov rbp, rsp

這時如果 push 一組資料進來, rsp 會往 low address 前進 (rsp 存放的位址會越來越小)。

push and pop

  • push: 將資料放進 stack
push rax

將 rax 的 value 放進 stack 。

  • pop: 將最上層資料捨棄
pop rcx

將上層資料存到 rcx 並捨棄上層資料。

pop word [rbx]

將上層資料存到 rbx 存放的地址(也就是 *rbx) 並捨棄上層資料。

function call

假設 main() 函式呼叫了 funcA() , Stack 與相關暫存器的變化如下:

  1. 將 return address (回到 main()) 推入 stack:

  2. 接著我們會將 main() 的 rbp 推入 stack :

push rbp

  1. 將 rbp 移動到 rsp 的位址:
mov rbp, rsp

  1. 分配空間給 funcA() (也就是將 rsp 向下移動):
sub rsp, 0x10

  1. 等到 funcA() return 時,會呼叫 leave :
mov rsp, rbp
pop rbp

  1. 這時 rsp 已經指向 main 的 return address 了,接著呼叫 ret 時,rip 就會指向 return address,並且將 stack frame 的狀態回復到 main 的 stack frame 。

instruction syntax

  • syntax
mov dest, source
  • example
    • mov rax, rbx 等於 rax = rbx
    • mov rax, [rbx-4] 等於 rax = *(rbp-4)
    • mov [rax], rbx 等於 *rax = rbx
    • lea eax,[ebx+8] 等於 eax = (ebx+8)

運算指令

  • add
  • sub
  • imul 有號乘法
  • idiv 有號除法
  • and
  • or
  • xor
  • neg (x = -x)
  • not
  • inc (x = x + 1)
  • dec

型態

  • byte: 1 byts
  • word: 2 bytes
  • dword: 4 bytes
  • qword: 8 bytes

舉例:

mov byte [rcx], 0x61
mul word [rax], 0x87
inc dword [rbp]
not qword [rsp]

注意!: dest 與 source 的型態需要相同

Compare 與 Flag

cmp val1, val2

會比較 val1 與 val2 是否相等,並將結果存到 flag register 當中。

一般來說會搭配 jump 指令

system call

conditional statement

  1. if/else
if(rax < 5){
// ...
}
else if (rax >= 5 && rax < 10){
// ...
}
else{
// ...
}

轉換成 x86 組合語言:

cmp rax, 5
jae Lelseif
; do something
jmp Lend
Lelseif:
cmp rax, 10
jae Lelse
; do something
jmp Lend
Lelse:
; do something
Lend:
  1. loop
for (int i = 0; i < 10; i++){

}

轉換成 x86 組合語言:

mov rcx, 0
loop:
cmp rcx, 10
jae lend
; do something...
inc rcx
jump loop
lend:

funtion parameter (x86_64)

function 的參數會依序傳給:

  • rdi, rsi, rdx, rcx, r8, r9
  • 如果超過 6 個參數,通通丟到 Stack 內

更多資訊可以參考 x86 calling conventions

Reference