自我檢查事項(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)