---
# System prepended metadata

title: Reverse Engineering notes - x86 Course
tags: [note]

---

# Reverse Engineering notes - x86 Course
> note by y1w3n
> 從基礎開始複習+新知識學習
## 長度
* 記憶體以byte為主
    * 1 byte = 8 bits
    * 2 byte = word
    * 4 byte = 2 word = double word
    * 每==一個==16進制數字長度 4 bits
        * 開頭``0x``表示他是16進制 
* 每個 byte 在記憶體中都有自己唯一的位址
    * 32位元的記憶體位址通常是 4 byte
## x86 基本架構
* **由 CPU 、記憶體、I/O 設備組成，由系統匯流排(System bus )連接**
* CPU
    * Control Unit
        * 讀取指令
    * Execution Unit
        * 真正執行操作的地方
    * Registers 
        * 暫時存放正在處理資料
    * Flags
        * 用來記錄發生的事
### **32位元x86 CPU 運作流程**
1. CPU 從記憶體取得 4 byte 機器指令
    * 指令是一串 0 和 1 的組合
    * 這筆資料會從記憶體讀取並載入到 CPU 中的暫存區
2. 指令解碼與執行
    * Control Unit 解析
    * Execution Unit 執行
3. EIP 暫存器更新為下一條指令的地址
    * EIP 記錄下一條要執行指令位置的暫存器
    * EIP 控制流程被劫持 -> buffer overflow 常見
## 通用暫存器(General-purpose Registers)
* 長度 4 bytes
* EAX
    * 累加器
    * 保存算術運算的結果和函數傳回值
* EBX
    * 基底暫存器
    * 當作程式資料的起始位置
* ECX
    * 用於計數
    * loop 次數、字串操作
* EDX
    * 一般用途、I/O 操作
    * 將 EAX 擴展至 64 位元
        *  ||有點像「兩位數」的十位數，EAX 是個位，EDX 是進位的地方||

![image](https://hackmd.io/_uploads/HyoS9Rbxgx.png)
* ESI
    * 來源索引
    * 字串和數組操作中的偏移位址
        * ||你在複製文字，ESI 就像你拿著掃描器從哪裡開始掃||
* EDI
    * 目標索引
* EBP
    * 指向目前 Stack Frame 的最底下
    * 存局部變數
* ESP
    * 指向目前 Stack Frame 的最上面
    * push/pop 呼叫函數、回傳、儲存狀態
    
![image](https://hackmd.io/_uploads/HJsVcCWxlg.png)
## 段暫存器
* 電腦的記憶體很大，為了讓 CPU 更有效率地處理資料，記憶體會被分段
* 用於引用記憶體位置
* 幾乎所有情況下都不能直接讀取或更改
---
* CS
    * 放程式碼的位置
    * .text 段
* DS
    * 放變數或資料的位置
    * .data 段
* ES
    * 字串操作期間使用額外段暫存器
* SS
    * 放暫存資料的位置
    * 函式傳參數、區域變數
* FS
    * 額外段暫存器
* GS
    * 額外段寄存器
:::spoiler 使用範例
```
DS + offset = 要讀的資料位置
SS + ESP = 要存取的堆疊資料
```
:::
## Pointer Register
* EIP
    * 指向下一則要執行的指令
    * 當我們能夠控制 EIP，就能控制程式的執行流程
## 控制暫存器(Control Registers)
* 用來控制 CPU 的運作模式和管理系統記憶體
* 更改
    * 要先搬到 General-purpose Registers 後再搬回去
---
* CR0
    * 決定 CPU 的工作模式
* ~~CR1~~
    * 保留，目前沒用到
* CR2
    * 儲存發生記憶體錯誤（Page Fault）時出錯的記憶體位置
* CR3
    * 記住頁面目錄（Page Directory）的位置
* CR4
    * 控制與顯示 CPU 的進階功能
## Flags
* 存在 EFLAGS 暫存器
    *  32 bit 的暫存器，每一個 bit 就代表一種 flag
* 三種 flag 
    * status flags
    * control flags
    * system flags
* 流程判斷、條件跳轉、錯誤偵測
---
### Status flags
* CF（Carry Flag）
    * 無號數運算
    * 進位、借位
* PF（Parity Flag）
    * 奇偶校驗
        * 偶: 設定
        * 奇: 清除
    * 可以確定暫存器自操作以來是否已損壞
* AF（Adjust Flag）
    * 二進位編碼的十進位數學運算
    * 如果從第 3 位產生進位或借位時用
* ZF（Zero Flag）
    * 運算結果為 0 會用
* SF（Sign Flag）
    * 看正負，負會用
* OF（Overflow Flag）
    * 有號數運算
    * 正值太大或負值太小而無法在暫存器中表示時用
    * 例: 127 + 1，因為超出 8-bit 正整數範圍，會設 OF
### Control flags
* DF（Direction Flag）
    * 控制 CPU 在處理字串時，是往前還是往後走
    * 設的話是倒著處理，清掉就順著處理
### System flags
* TF（Trap Flag）
    * 一次只執行一個指令
* IF（Interrupt Enable Flag）
    * 控制能不能接收中斷
* IOPL（I/O Privilege Level）
    * 控制輸入/輸出的存取權限
* NT（Nested Task）
    * 控制目前正在執行的任務是否連結到先前執行的任務
    * 連結或中斷呼叫
* RF（Resume Flag）
    * debugging mode 下 處理器異常
* VM（Virtual 8086 Mode）
    * 表示處理器正在 virtual-8086 mode 下運行
        * 這個模式是在一般的保護模式下，模擬一個 8086 的執行環境，可以同時執行多個 8086 程式 (8086是x86第一代處理器)
* AC（Alignment Check）
    * 對齊檢查
* VIF（Virtual Interrupt Flag）
    * virtual mode 下複製 ```IF flags```
* VIP（Virtual Interrupt Pending）
    * 是否有中斷正在等處理
* ID（ID Flag）
    * 是否支援 CPUID 指令
        * 取得處理器的識別訊息，如製造商、型號、特性、性能指標等
## Stack
* ==先進後出==
* 當Functions被呼叫時，會把跟這個Functions有關的資訊放到Stack裡面

![image](https://hackmd.io/_uploads/Sy7MVtXgxe.png)
* 從較高記憶體到較低記憶體==向下增長==
* 操作
    *  push
    *  pop
## heap
* ==向上增長==
* heap變數是全域變數
* 對變數大小沒有大小限制

![image](https://hackmd.io/_uploads/HkplU34llg.png)
* 手動管理
    * ``malloc(size)``：配置一塊記憶體空間
    * ``calloc(n, size)``：配置 n 個空間並初始化為 0
    * ``realloc(ptr, new_size)``：改變已配置空間的大小
    * ``free(ptr)``：釋放不需要的記憶體
:::spoiler 什麼時候用 Heap、什麼時候用 Stack?
| 使用情境         | 選擇                   |
| ------------ | -------------------- |
| 短期使用、變數生命週期短 | Stack（函式區域變數）        |
| 長期存在、跨多個函式使用 | Heap（需要 malloc）      |
| 需要很大的空間      | Heap（Stack 空間有限）     |
| 陣列長度不固定      | Heap（用 realloc 動態調整） |

:::

