---
# System prepended metadata

title: Reverse
tags: [Enlightened, NISRA, '2021']

---

# 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)
    * 遊戲外掛

### 何謂逆向

* 跟著箭頭就會產生程式
![程式產生](https://i.imgur.com/GwjBEWa.png)
* 而從下逆向上去就是Reverse

### 需要先備知識/工具

* 基礎程式概念
    * 程式邏輯
* 組合語言
* 工具
    * PC
    * decompiler
* 堅持下去的心
* 眼睛

## 組合語言 Assembly

* 看懂它
* 沒了

![](https://i.imgur.com/9S9fgED.png)
- 機器語言
- 組合語言
- 剩下的語言 ~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
![](https://i.imgur.com/uG7Vazz.png)

- 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-->
![Imgur](https://imgur.com/o6fATFr.gif)
<!--大概是這樣ㄇ-->

### 暫存器

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