Try   HackMD

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

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。

  • 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
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
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
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
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

依照 隔離執行環境的建構與應用 的步驟觀察 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 位置

(gdb) compare-sections .text Section .text, range 0x1000 -- 0x1a2c: matched. (gdb) compare-sections .data Section .data, range 0x1c50 -- 0x2078: matched.

或者透過 info files 印出所有 sections 的位置

(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

(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 沒有太大的意義,因此選擇以十六進制顯示

(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 處理器架構的 Architecture 文件?能否用 Moxie 組合語言寫出迴圈版本的 Fibonacci 數列程式?
  • binutils, gcc, glibc, qemu 到 libffi 這些專案的作用為何?
  • Intel 的 Software Guard Extensions 關鍵特性為何?並舉出共筆以外的應用案例
  • moxiebox 打造出隔離執行 (sandbox) 的運作環境該如何與外界溝通?列出對應的程式碼並解讀
    • 提示: mmap 系統呼叫
  • 是否已詳閱文件 sandbox execution environment 呢?解釋 法國的加密貨幣硬體錢包公司 Ledger 的 BOLOS 運作原理
  • 何謂 cross compiler 呢?我們為何需要?
  • ELF 執行檔格式包含哪些 section 呢?又在哪裡可見到詳細描述?
  • 是否已掌握 GNU gprof 的使用?運作原理為何?
    • 提示: 參閱 raytracing 作業規範和共筆成果
  • 是否已操作 remote GDB 呢?如何在執行時期檢驗載入的 ELF 執行檔裡頭 .text.data section 內容呢?
  • 是否詳讀文件 遠端除錯 並記錄心得呢?是否在 GNU/Linux 實際照著操作?又,遇到什麼問題呢?
    • 提示: 硬體架構以不同,文章提及 IA32,但現在已是 x86_64 架構
  • GDB 命令如 step 是如何透過 GDB stub 傳遞到 moxiebox 裡頭呢?兩邊的通訊協定又為何?
  • 是否理解 GDB Macro 和 Command Files 呢?能否透過 moxiebox 進行練習呢?

參考網站