---
# System prepended metadata

title: Reverse Class 2 (Windows reverse)
tags: [CTF]

---

# Reverse Class 2 (Windows reverse)

[toc]

## MSDN
微軟官方文件，建議查詢相關事項
* PE format
* API 使用方式
* Windows 機制

**But** 不是所有東西公開 ex: PEB_LDR_DATA structure
[`Vergilius Project`](https://www.vergiliusproject.com/) <- 好幫手！是個開源專案，收集部分微軟未公開的資訊



## Tools
* DIE(Detect It Easy) : 用來查看檔案類型、特徵、是否被加過殼？
* PE-bear : 查看 PE 結構
    * 作 Raw address (file offset)的換算
* x64-dbg : Windows debugger(開源Now)
    * ~~ScyllaHide : 可使用插件繞過 Anti-debug 之檢查機制(此堂課不教)~~
    * Implement
        * 右方預設，可更改 syscall 方法
        * 指令行右鍵[在記憶體映射中跟隨]，可追蹤到該指令行在記憶體映射中位置
        * 指令行右鍵[在資料視窗中跟隨]，可看到檔案資料



## Calling convention
* 什麼是 Calling convention?
    用於規範 subprocess 過程中如何獲取參數，以及如何 return 的方案，通常宇架構和編譯器有關(ex: x86, x86-64, Linux or Windows)
* cdecl (Windows x86)
    * 參數 : 放 stack 上
    * 回傳值 : eax
    * Stack cleanup : ==Caller==
* stdcall (Windows x86)
    * Win32 API
    * 參數 : 放 stack 上
    * 回傳值 : eax
    * Stack cleanup : ==Callee==
* Microsoft x64 (Windows x86-64)
    * 參數 : rcx, rdx, r8, r9, 其餘放 stack 上
    * 回傳值 : rax
    * Stack cleanup : ==Caller==

## Coding Style Convention
* Coding style convention
    * 變數前綴代表資料型態     ex: 
    * **lp**LibFileName(lp表 Long Pointer)
    * **h**File(表 Handle)
    * **dw**Flags(表 DWORD)
* Function Prototype Convention
    * Function name 後面可能會有大寫字母     ex:
    * oadLibrary**A**(字串參數使用 ASCII)
    * LoadLibrary**W**(字串參數使用 UNICODE)
    * LoadLibrary**EX**(擴展 extended)

## VA v.s. RVA
* Physical Address
    * 真正的記憶體位置
    * 由 OS 管理，平常用不太到
* Virtual Address(VA)
    * Process 透過 virtual address 來存取記憶體
    * physical address -> virtual address 由 OS 進行處理
* Relative Virtual Address(RVA)
    * 相對於 image base 的位置 
        → VA = image base + RVA
* Example
    ![](https://i.imgur.com/mZsOc6n.png)


## Packer(在程式外加殼)
* 加密殼
* 壓縮殼 -> UPX
* Executable, DLL, driver
    * DLL(Dynamic Linker Library)
        * 導出函式給程式使用 ex: kernelBase.dll
        * DLL 的 main function 叫做 DLLMain
            * 載入、卸載時會執行

## API
由於 Windows 的 system call number 會隨著版本改變，因此程式通常會透過呼叫 API 執行 system call。因此 Call API 在 Windows 會十分常見，而對 reverse 來說，可透過觀察程式行為，來推測其呼叫了那些 API；抑或是拓過特定 API 來推測程式想做什麼 -> **通靈**

[常用 API 整理 →](https://sensei-infosec.netlify.app/forensics/windows/api-calls/2020/04/29/win-api-calls-1.html)
## PE
介紹 : Linux 上執行檔格式為 ELF，Windows 上則為 PE(Portable Executable)
* 完整圖
    ![](https://i.imgur.com/3vUEePX.png)

* PE File format
![](https://i.imgur.com/Ulj2NFv.png)
* Header
![](https://i.imgur.com/IMQFizF.png)
    
    * DOS Header 
        * 初始為 e_magic -> "MZ"
        * 結束為 e_lfanew -> 指向 NT_Headers
    * DOS Stub : For 向下兼容
    * NT Headers(以下開始較重要) : 資料結構名稱[IMAGE_NT_HEADERS]，包含下列 2 Headers
        * File Header(aka COFF Header) : 資料結構名稱[IMAGE_FILE_HEADER]
            * Signature : 實際上在 File_Header 上，不包含在其裡面 -> `PE\x00\x00`
            * NumberOfSections : 之後 [Sections](#PE-Headers) 的數量
            * Characteristics : about some 檔案屬性
        * Optional Header : 資料結構名稱[IMAGE_OPTIONAL_HEADER]
            * AddressOfEntryPoint : 指向 entry point(RVA)
            * DataDirectory[16] : 位於 Optional Header 最下方
            ![](https://i.imgur.com/8eDB7o3.png)

            * ImageBase(VA) : virtual address 指向 exe run 起來時 process 的 imagebase
            * SectionAlignment
            * FileAlignment
    * Section Headers : 資料結構名稱[IMAGE_SECTION_HEADER[] ] -> 由多個 [IMAGE_SECTION_HEADERS] 組成
        * 位於 NT Headers 後面，共 NumberOfSections 個
        * Section Example
        ![](https://i.imgur.com/tX5dBcF.png)

        * 設定每個 Section 的映射方式及權限(部分)
            
            * Process 一開始值皆會放在 ImageBase(VA)
            * PointerToRawData (file offset) : 指向檔案中該 section 的起始位置
            * SizeOfRawData : PE File 中該 section 實際占的大小，包含 FileAlignment 所用的 null padding
            * VirtualAddress (RVA) : 指向進程中該 section 的起始位置
            * VirtualSize : 該 section 在 virtual memory 中占的大小，不包含 FileAlignment 所用的 null padding
            * Map PointerToRawData to VirtualAddress
            :::info
            **VA** : 全域位址
            **RVA** : 相對於 ImageBase 位址
            
            ![](https://i.imgur.com/Shwy4Ki.png)

            :::
        * 映射實例
        ![](https://i.imgur.com/koanqag.png)
            :::info
            **SizeOfRawData**           : 0x200     ->   表示此 Section 在文件中占了 0x200 字節 
            **PointerToRawData**     : 0x400     ->   表示此 Section 在文件中的偏移量是 0x400
            :::

## IAT : 全名為 Import Address Table
* 程式要如何呼叫外部 function？
    載入DLL後直接 Call function？程式如何得知 function 的位置？
    -> 透過 IAT 查找
    
* 程式載入前後存甚麼資料？
    * 程式載入前相當於 INT(指向 IMAGE_IMPORT_BY_NAME)
    * 程式載入後儲存外部引入 function 位置
    
* 儲存在 .idata section 內的 table
    ![](https://i.imgur.com/FhHO6oP.png)

## EAT : 全名為 Export Address Table

* For 導出函式所使用的表
    ![](https://i.imgur.com/nxqVqmH.png)
    
* 應用
    ![](https://i.imgur.com/WkDhlvh.png)

    
## PEB : 全名為 Process Environment Block
用於儲存一些 Process 相關資訊

* 需先透過 _TEB(Thread Environment Block)取得，透過 offset操作。
    
    * x86 下 : _TEB 位於 fs:[0]
    * x86-64 下 : _TEB 位於 gs:[0]

    ![](https://i.imgur.com/y2jOGsE.png)

* 應用
    ![](https://i.imgur.com/KBSGK9I.png)

    ![](https://i.imgur.com/Y5oPuPG.png)

