自我檢查事項(sandbox)
===
## 何謂Cross compiler(交叉編譯器)?
Cross Compiler主要在資源較豐富的電腦上執行,而編譯出能在別的電腦上執行的目的碼(Object Code)。
- 例如,當我們想寫個C程式,讓它能在Android手機裡跑。
Android手機的ARM-CPU及記憶體容量都很小,我們無法在資源有限的Android/ARM裡進行編輯及編譯C程式。
可行的方法是:在X86 PC環境裏編輯C程式,然後使用Cross Compiler去編譯出適合ARM-CPU裡執行的目的碼。這稱為Cross Compiler。
## ELF 執行檔格式包含哪些 section 呢?又在哪裡可見到詳細描述?
### object file
- object code(目的碼):
指電腦科學中編譯器或組譯器處理原始碼後所生成的代碼,它一般由機械碼或接近於機器語言的代碼組成。
- object file(目的檔)
即存放目的碼的電腦檔案,它常被稱作二進制檔案(binaries)。
![](https://i.imgur.com/RWUrwqA.png)
### ELF(Executable and Linking Format)格式
Executable Format 主要有:
- Windows 下的 PE(Portable Executable)
- Linux 下的 ELF(Executable Linkable Format)
現在Linux和Windows上的可執行檔,基本上是基於COFF格式演變而來。
- COFF最重要的觀念在於引入了section的機制,讓不同的obj file可以擁有不同的section。
---
ELF 標準中將使用 ELF 格式的檔案分成:
| ELF file type | Example |
| -------- | -------- |
| Relocatable File | Linux 的 .o、Windows 的 .obj |
| Executable File | /bin/bash、Windows 的 .exe |
| Shared Object File | Linux 的 .so、Windows 的 .dll |
| Core Dump File | Linux 的 core dump |
---
### ELF file structure
ELF 檔是由 header、一堆 section 及一堆 table 組成的,各 table 也是 section。
![](https://i.imgur.com/78RcKSh.png)
- File Header
描述該文件的屬性,例如該文件是否可以執行、是靜態連結還是動態連結、target 硬體、target OS等
- Section Table: 紀錄了該份文件有哪些Section, 有哪些屬性
- .text section
instruction通常都保存在這裡
- .data section
通常用於紀錄初始化的global variable和local static variable
- .bss section
通常用於紀錄未被初始化的global variable和static variable,通常只是紀錄符號和留一段空間
#### 實際觀察
透過readelf / objdump 工具
可用 readelf -h XXX.elf ,觀察描述整個 ELF 檔的屬性。
##### sha256 Header
```clike=
ELF Header:
Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Moxie
Version: 0x1
Entry point address: 0x1000
Start of program headers: 52 (bytes into file)
Start of section headers: 38760 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 3
Size of section headers: 40 (bytes)
Number of section headers: 22
Section header string table index: 21
```
##### 觀察/usr/include/elf.h header struct
```clike=
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf64_Half e_type; /* Object file type */
Elf64_Half e_machine; /* Architecture */
Elf64_Word e_version; /* Object file version */
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags; /* Processor-specific flags */
Elf64_Half e_ehsize; /* ELF header size in bytes */
Elf64_Half e_phentsize; /* Program header table entry size */
Elf64_Half e_phnum; /* Program header table entry count */
Elf64_Half e_shentsize; /* Section header table entry size */
Elf64_Half e_shnum; /* Section header table entry count */
Elf64_Half e_shstrndx; /* Section header string table index */
} Elf64_Ehdr;
```
##### Section Header Table
可用 readelf -S XXX.elf ,觀察各section的屬性
##### sha256 各section
```clike=
There are 22 section headers, starting at offset 0x9768:
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00001000 000094 000a2c 00 AX 0 0 2
[ 2] .init PROGBITS 00001a2c 000ac0 00000e 00 AX 0 0 2
[ 3] .fini PROGBITS 00001a3a 000ace 000008 00 AX 0 0 2
[ 4] .rodata PROGBITS 00001a44 000ad8 00010c 00 A 0 0 4
[ 5] .data PROGBITS 00001c50 000be4 000428 00 WA 0 0 4
[ 6] .eh_frame PROGBITS 00002078 00100c 000004 00 WA 0 0 4
[ 7] .ctors PROGBITS 0000207c 001010 000008 00 WA 0 0 4
[ 8] .dtors PROGBITS 00002084 001018 000008 00 WA 0 0 4
[ 9] .bss NOBITS 0000208c 001020 000094 00 WA 0 0 4
[10] .comment PROGBITS 00000000 001020 00003b 01 MS 0 0 1
[11] .debug_aranges PROGBITS 00000000 00105b 000150 00 0 0 1
[12] .debug_info PROGBITS 00000000 0011ab 003d87 00 0 0 1
[13] .debug_abbrev PROGBITS 00000000 004f32 000f8a 00 0 0 1
[14] .debug_line PROGBITS 00000000 005ebc 0014ef 00 0 0 1
[15] .debug_frame PROGBITS 00000000 0073ac 0002fc 00 0 0 4
[16] .debug_str PROGBITS 00000000 0076a8 000a92 01 MS 0 0 1
[17] .debug_loc PROGBITS 00000000 00813a 000d3d 00 0 0 1
[18] .debug_ranges PROGBITS 00000000 008e77 0000a8 00 0 0 1
[19] .symtab SYMTAB 00000000 008f20 000540 10 20 54 4
[20] .strtab STRTAB 00000000 009460 00023e 00 0 0 1
[21] .shstrtab STRTAB 00000000 00969e 0000c7 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
```
##### section descriptor
```clike=
typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf64_Section st_shndx; /* Section index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Symbol size */
} Elf64_Sym;
```
## 閱讀 Moxie 處理器架構
## 是否已操作 remote GDB 呢?如何在執行時期檢驗載入的 ELF 執行檔裡頭 .text 和 .data section 內容呢?
### 操作 remote GDB
依照 [隔離執行環境的建構與應用](https://hackmd.io/s/Hk9HLRbkf) 的步驟觀察 tests/sha256
#### 終端機 A
$ src/sandbox -e tests/sha256 -g 9999
#### 終端機 B
$ moxie-none-moxiebox-gdb -q tests/sha256
### 尋找 .text 和 .data section 位置
終端機 B 進入 remote GDB 後透過 compare-sections 來尋找對應的 sections 位置
```clike=
(gdb) compare-sections .text
Section .text, range 0x1000 -- 0x1a2c: matched.
(gdb) compare-sections .data
Section .data, range 0x1c50 -- 0x2078: matched.
```
或者透過 info files 印出所有 sections 的位置
```clike=
(gdb) info files
Symbols from "/home/uscca22/sysprog/homework_team/moxiebox/tests/sha256".
Remote serial target in gdb-specific protocol:
Debugging a target over a serial line.
While running this, GDB does not access memory from...
Local exec file:
`/home/uscca22/sysprog/homework_team/moxiebox/tests/sha256', file type elf32-littlemoxie.
Entry point: 0x1000
0x00001000 - 0x00001a2c is .text
0x00001a2c - 0x00001a3a is .init
0x00001a3a - 0x00001a42 is .fini
0x00001a44 - 0x00001b50 is .rodata
0x00001c50 - 0x00002078 is .data
0x00002078 - 0x0000207c is .eh_frame
0x0000207c - 0x00002084 is .ctors
0x00002084 - 0x0000208c is .dtors
0x0000208c - 0x00002120 is .bss
```
### 檢驗 .text 和 .data section 內容
透過 Examining memory 指令搭配剛剛找到的位置來檢驗 .text 和 .data section 內容
(gdb)x/nfu addr
x : Examining memory
n : Repeat count
f : Display format
u : Unit size
#### 檢驗 .text
.text section 存放指令,因此 display format 選擇 instruction format
```clike=
(gdb) x/5i 0x00001000
0x1000 <__start>: xor $fp, $fp
0x1002 <__start+2>: gsr $sp, 0x7
0x1004 <__start+4>: ldi.l $r0, 0x208c
0x100a <__start+10>: xor $r1, $r1
0x100c <__start+12>: ldi.l $r2, 0x2120
(gdb)
0x1012 <__start+18>: sub $r2, $r0
0x1014 <__start+20>: jsra 0x14b0 <memset>
0x101a <__start+26>: gsr $r0, 0x6
0x101c <__start+28>: sta.l 0x211c, $r0
0x1022 <__start+34>: xor $r0, $r0
(gdb)
0x1024 <__start+36>: xor $r1, $r1
0x1026 <__start+38>: jsra 0x1a2c <_init>
0x102c <__start+44>: ldi.l $r0, 0x1a3a
0x1032 <__start+50>: jsra 0x116c <atexit>
0x1038 <__start+56>: jsra 0x13e0 <main>
...
...
...
```
#### 檢驗 .data
.data section 存放不同大小的資料, display format 使用 instruction format 沒有太大的意義,因此選擇以十六進制顯示
```clike=
(gdb) x/5xh 0x1c50
0x1c50 <_impure_ptr>: 0x1c54 0x0000 0x0000 0x0000 0x1f40
(gdb)
0x1c5a <impure_data+6>: 0x0000 0x1fa8 0x0000 0x2010 0x0000
(gdb)
0x1c64 <impure_data+16>: 0x0000 0x0000 0x0000 0x0000 0x0000
(gdb)
0x1c6e <impure_data+26>: 0x0000 0x0000 0x0000 0x0000 0x0000
(gdb)
0x1c78 <impure_data+36>: 0x0000 0x0000 0x0000 0x0000 0x0000
...
...
...
```
## 自我檢查項目
- [ ] Trusted Execution Environment (TEE) 的應用為何?(舉出共筆以外的真實世界案例)
- [ ] 是否已詳細閱讀 [Moxie](http://moxielogic.org/blog/) 處理器架構的 [Architecture](http://moxielogic.org/blog/pages/architecture.html) 文件?能否用 Moxie 組合語言寫出迴圈版本的 Fibonacci 數列程式?
- [ ] binutils, gcc, glibc, qemu 到 [libffi](https://sourceware.org/libffi/) 這些專案的作用為何?
- [ ] Intel 的 [Software Guard Extensions](https://software.intel.com/en-us/sgx) 關鍵特性為何?並舉出共筆以外的應用案例
- [ ] [moxiebox](https://github.com/sysprog21/moxiebox) 打造出隔離執行 (sandbox) 的運作環境該如何與外界溝通?列出對應的程式碼並解讀
* 提示: `mmap` 系統呼叫
- [x] 是否已詳閱文件 [sandbox execution environment](https://github.com/sysprog21/moxiebox/blob/master/sandbox-design.md) 呢?解釋 法國的加密貨幣硬體錢包公司 [Ledger](https://www.ledgerwallet.com/) 的 BOLOS 運作原理
- [ ] 何謂 cross compiler 呢?我們為何需要?
- [ ] ELF 執行檔格式包含哪些 section 呢?又在哪裡可見到詳細描述?
- [ ] 是否已掌握 GNU gprof 的使用?運作原理為何?
* 提示: 參閱 [raytracing](https://hackmd.io/s/HyuBWDwYl) 作業規範和共筆成果
- [x] 是否已操作 remote GDB 呢?如何在執行時期檢驗載入的 ELF 執行檔裡頭 `.text` 和 `.data` section 內容呢?
- [ ] 是否詳讀文件 [遠端除錯](http://www.study-area.org/cyril/opentools/opentools/x1265.html) 並記錄心得呢?是否在 GNU/Linux 實際照著操作?又,遇到什麼問題呢?
* 提示: 硬體架構以不同,文章提及 IA32,但現在已是 x86_64 架構
- [ ] GDB 命令如 `step` 是如何透過 GDB stub 傳遞到 [moxiebox](https://github.com/sysprog21/moxiebox) 裡頭呢?兩邊的通訊協定又為何?
* 提示: 需要對照看 [moxiebox](https://github.com/sysprog21/moxiebox) 的 `src/sandbox.cc` 檔案內容和 [GDB Remote Serial Protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html)
- [ ] 是否理解 GDB Macro 和 [Command Files](https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html) 呢?能否透過 [moxiebox](https://github.com/sysprog21/moxiebox) 進行練習呢?
## 參考網站
- [[期末報告]-Cross compiler-95441069](http://aiplab.net/forum/index.php?topic=160.0;wap2)
- [Executable Format(可執行檔格式) | cjwind's note](http://www.cjwind.idv.tw/Executable-Format/)
- [[程序員的自我修養-linker, loader & library] 閱讀筆記(一) « Opass's Blog](http://opass.logdown.com/posts/248172-linker-loader-library)
- [Executable and Linking Format (ELF) Specification Version 1.2]( http://refspecs.linuxbase.org/elf/elf.pdf)