# Reverse
:::danger
請愛惜共筆,勿進行惡意刪減
:::
[Slides](https://docs.google.com/presentation/d/1pnMSRhfC9tMg5CoRofIiF0VUH57Y47YF/edit?usp=sharing&ouid=101320963245090047568&rtpof=true&sd=true)
[NISRA CTF](https://class.enlightened.nisra.net/)
---
:::spoiler Table of Content
[TOC]
:::
> 虛擬機器 VirtualBox 全家桶
> 建議預留 40GB+ 硬碟空間 ~內附安裝說明~
> - [主載點](https://drive.google.com/drive/folders/14Qh5CmGSDODujndOMRWsL_LvdaCTrV-A?usp=sharing)
> - [備用載點](https://drive.google.com/drive/folders/1OLpE-aaW7gVXrlfXjL_qEe1grPZ9iysC?usp=sharing)
## Intro -Reverse
* 逆向工程 Reverse Engineering
* 分析程式邏輯
* 修改程式邏輯
* E.g.
* 破解付費軟體(Crack)
* 遊戲外掛
### 何謂逆向
* 跟著箭頭就會產生程式

* 而從下逆向上去就是Reverse
### 需要先備知識/工具
* 基礎程式概念
* 程式邏輯
* 組合語言
* 工具
* PC
* decompiler
* 堅持下去的心
* 眼睛
## 組合語言 Assembly
* 看懂它
* 沒了

- 機器語言
- 組合語言
- 剩下的語言 ~C++,\ Java,\ Fortran...~
<!--hackmd 截圖上傳真的方便OuOb-->
<!--同意。真香。-->
- Assembly language
- 副檔名: `.asm` `.s`
### 位元 bit
> **B**inary Dig**it**s
### x86 vs x64
* x86
* 32位元暫存器
* Intel以前的處理器多以86作為產品編號末兩碼 ~例如8086~
* x64
* 64位元暫存器
### 派系 Syntax
* ==Intel==
* `mov eax,16`
* 主流
==範例以此為主==
* AT&T
* `mov $16, %eax`
## Stack
* 用來放資料的容器
* **L**ast **I**n **F**irst **O**ut

- Memory Layout
- `system` 命令列參數、環境參數
- `stack` 區域變數
- ...
- `heap` 動態配置變數
- `bss` 未初始化靜態變數
- `data` 已初始化資料變數
- `text` 程式原始碼
> 由高位址長到低位址
### 副函式
[link : replit.com](https://replit.com/languages/c)
```c=
#include <stdio.h>
// 參數 Parameter
// ↓ ↓
int plus(int a, int b){
int temp = a + b;
// ↑區域變數 Local Variable
return temp;
}
int main() {
int result = plus(87, 87);
printf("%d\n", result);
return 0;
}
```
<!--為甚麼這個筆可以這麼大xDD-->
<!--資安女捷思不是我們可以質疑的(X-->
| EBP -> | 內容 |
|:------:|:------:|
| | ... |
| | 內容 |
| ESP | 最下端 |
- 呼叫慣例 Calling Convention ~的其中一種~
```c=
// 傳參數方向
// ← ← ← ← ← ← ← ← ← ← ← ←
func(int a, int b, int c){
int local_var1;
int local_var2;
}
```
↓轉成組語↓
```asm=
push c, b, a
push return address
push ebp_old
```
拉出新空間
分配空間給`local _var1, local_var2`
| Register | stack |
|:---------------------------:|:--------:|
| ^原^==**EBP**== >_ | main |
| ↓ | c |
| ↓ | b |
| ↓ | a |
| ↓ | ... |
| ↓ | ret addr |
| ^新^EBP, ^原^==**ESP**== >_ | ebp_old |
| ↓ | ... |
| ↓ | |
| ^新^ESP >_ | |
<!--ㄟ不是這個有點難表示-->
<!--小畫家搞不好會比較快ww-->

<!--大概是這樣ㄇ-->
### 暫存器
* `EAX`, `EBX`, `ECX`, `EDX`
* 32 bits
> 今天以這編為主
* `Rxx`
* 64 bits
- `EBP`
- base pointer
- 指向第一個被push進stack的東西
- `ESP`
- stack pointer
- 指向最後一個被push 進stack的東西
- stack 頂端
- `EIP`
- instruction pointer
- 指向下一行要執行的程式碼
### 基本指令
- `MOV`
- `mov eax, tmp`
- 把`tmp`放到`eax`裡
- `eax = tmp`
- `eax`和`tmp`兩個size要一樣
ex. 32bit ⇆ 32bit , 64bit ⇆ 64bit
- `MOVZX`
- `movzx eax, tmp`
- 把`tmp`放到`eax`裡
- `eax = tmp`
- `eax`和`tmp`兩個size可以不一樣
ex. 64bit ← 32bit
- `add eax, ebx`
- 相當於`eax = eax + ebx`
- `sub eax, ebx`
- 相當於`eax = eax - ebx`
### Array
|Array Elements→| 29 | 17 | 42 | 13 | 56 |
|-|:---:|:---:|:---:|:---:|:---:|
|Array Indices→| 0 | 1 | 2 | 3 | 4 |
### 組合語言-定址模式
- addressing mode定址模式
- `mov esi,offset arrA`
- `[esi]`
- arrA[0]
- `[esi + 4]`
- arrA[1] ~32\ bits~
### 進階指令
- `push`
- `push eax`
- 把 eax push 到 stack 的頂端
- `pop`
- `pop ebx`
- 把 stack 頂端的東西 `pop` 到 `ebx` 裡
- 呼叫副程式
- `call <label>`
- `push eip + 4` + `jmp <label>`
- 存回來的位置 + 跳到副程式
- `ret`
- `pop eip` 後跳到 eip 的位址
- `return`
- `cmp`
- `cmp eax, ebx`
- eax-ebx的值去調整flag
- Flags
- Zero flag `ZF`
- 當前指定進行計算後結果為0
- 則ZF=1
- Sign flag `SF`
- 當前指令進行計算後結果為負
- 則SF=1
- Overflow flag `OF`
- OF = 1 當前指令計算後 overflow
- Carry Flag `CF`
- 如果carry
- 跳轉指令
- JZ, JE
- jump if ZF=1/equal
- JNZ, JNE
- jump if ZF = 0/not equal
- JG >
- jump if greater
- JGE >=
- jump if greater or equal
- JL <
- jump if smaller
- JLE <=
- jump if smaller or equal
### Lab 0x2 (?
```asm=
mov eax, 1
mov ebx, 2
cmp eax, ebx
jz L1 ; je L1
add eax, 2
jmp after_L1
L1:
add ebx, 2
after_L1
inc eax
```
求`eax`、`ebx`的值?
> tips : `inc eax` => eax + 1
### Lab 0x3
```asm=
mov eax, 1
mov ebx, 2
cmp eax, ebx
jz L1 ; je L1
add eax, 2
L1 :
add ebx, 2
after_L1:
inc eax
```
求`eax`、`ebx`的值?
> tips : Line 5 做完接著做 L1
> 以此類推
### Lab 0x4
```asm=
; 預設 esi 裡
; 已經放了 arr 的開頭位址
; arr[0] = 0
mov eax, 0
cmp eax, [esi]
jz L1 ; je L1
add eax, 2
jmp after_L1
L1:
inc [esi]
after_L1:
...
```
求`eax`、`[esi]`的值?
> tips : \[esi\] = arr\[0\]
<!---->
## Reverse
- `file <Filename>`
- 32 / 64 bit
- dynamic / static linked
- stripped / not stripped
- 靜態分析
- 分析時沒有執行
- 分析程式碼、組合語言、static data
- Patch instruction
- Tools
- objdump
- `objdump -M Intel -d <File>`
- IDA Pro
- 貴鬆鬆
- ghidra
- National Security Agency
- JAVA
- **免費**
- 動態分析
- 邊執行邊分析
- 分析當下的 register 和 memory
- Tools
- gdb
- **G**NU **D**e**b**ugger
- peda ~~讓人生變彩色的~~
###### tags: `Enlightened` `NISRA` `2021`
<style>
.navbar-brand::after { content: " × NISRA"; }
</style>