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 與相關暫存器的變化如下:
-
將 return address (回到
main()
) 推入 stack: -
接著我們會將
main()
的 rbp 推入 stack :
push rbp
- 將 rbp 移動到 rsp 的位址:
mov rbp, rsp
- 分配空間給
funcA()
(也就是將 rsp 向下移動):
sub rsp, 0x10
- 等到
funcA()
return 時,會呼叫 leave :
mov rsp, rbp
pop rbp
- 這時 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
- 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:
- 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 。