《Linux及安全》實踐3.1

《Linux及安全》實踐三 ELF格式文件分析

1、基礎操做

1.查看大小端、32仍是64

  • 由此能夠看出,本人實踐所用到的是32位Ubuntu,數據存儲採用小端法。linux

2.編寫hello.c文件

3.查看文件類型、大小

  • 能夠看到是可重定位文件,大小爲1028比特安全

4.以16進制形式輸出hello.o文件

5.經過ELF headers table閱讀文件各個段的信息

  • 能夠看到,Size of this header(文件頭部)52byteside

2、ELF文件格式分析

1.查看ELF頭部定義

  • ELF頭部的定義在/usr/include/elf.h中:
    • - (爲不一樣位數設置)
    • - (ELF頭結構體定義)

2.分析hello 的ELF頭部

  • 已知頭部大小52字節
    • 0000000 457f 464c 0101 0001 0000 0000 0000 0000
        0000010 0002 0003 0001 0000 8320 0804 0034 0000
        0000020 1174 0000 0000 0000 0034 0020 0009 0028
        0000030 001e 001b
    • 第一行分析:
      • 其前16個字節(第一行,對應e_ident[EI_NIDENT])實際表示內容爲7f45 4c46 0101 0100 0000 0000 0000 0000,前四個字節7f454c46(0x45,0x4c,0x46是'e','l','f'對應的ascii編碼)是一個魔數(magic number),表示這是一個ELF對象。接下來的一個字節01表示是一個32位對象,接下來的一個字節01表示是小端法表示,再接下來的一個字節01表示文件頭版本。剩下的默認都設置爲0。
    • 第二行分析:
      • e_type(兩個字節)值爲0x0002,表示可執行文件。
      • e_machine(兩個字節)值爲0x0003,表示是intel80386處理器體系結構。
      • e_version(四個字節)值爲0x00000001,表示是當前版本。
      • e_entry(四個字節)值爲0x83200804,表示程序進入點。
      • e_phoff(四個字節)值爲0x00340000,表示結頭表偏移量。
    • 第三行分析:
      • e_shoff(四個字節)值爲0x1174,表示段表的偏移地址。
      • e_flags(四個字節)值爲0x00000000,表示未知處理器特定標誌(#define EF_SH_UNKNOWN 0x0)。
      • e_ehsize(兩個字節)值爲0034,表示elf文件頭大小(正好是52個字節)。
      • e_phentsize(兩個字節)爲0x0020,表示程序頭表中每一個條目的大小爲32.
      • e_ehentsize(兩個字節)值爲0x0028表示段頭大小爲40個字節。
      • e_shnum(兩個字節)值爲0x001e,表示段表入口有28個。e_shstrndx(兩個字節)值爲0x001b,表示段名串表的在段表中的索引號爲27。

3.分析hello.o的section header table

  • 由上圖可見,section header table中包括了各段的偏移地址(off)和大小(size),能夠由此找到各段的位置。this

4.分析各段

  1. .text段分析編碼

    • Hello.o中.text大小爲0X1c,即十進制的28。
    • 對hello.o進行反彙編
      • 能夠看到.text段跨越0x0到0x1b,剛好共0x1c(即28)個字節3d

  2. .strtab段分析
    • 該段的offset是0x3d8(正好在.symtab段以後),size是0x13,即到0x2ea爲止。
      對應字符串爲:「\0hello.c\0main\0puts\0」code

  3. .symtab段分析
      • 上圖是.symtab所擁有的入口數量
    • 從上面的分析已經知道,.symtab的偏移量爲0x328(即808),大小爲0xb0(即十進制176)。於是數據即上圖中標爲黃色的部分
    • 該結構大小爲16個字節,而整個符號表段大小爲176個字節,因此總共能夠分紅11個符號。
    • 這11個符號恰好和前面objdump輸出的符號表(10個符號,第一個符號爲空,因此被忽略)結果相對應;也和使用readelf中符號表相關內容對應(readelf命令輸出結果比objdump輸出結果看起來更易懂一些):對象

  4. rodata段分析
    • 由於位於.rodata段上面的.bss段size爲0x00,因此.bss和.rodata偏移量同樣(都是0x50),.rodata段大小爲0xd,也就是13個字節。即:
      68 65 6c 6c 6f 20 2c 20 35 32 31 36 00。
      • 對照ACII碼錶 ,能夠拼出其正好對應HELLO,5216

5.補充blog

  • 從前面對ELF頭的解析能夠知道段表的地址是從0x1174(e_shoff項)開始,而上面的.shstrtab的開始地址爲0xc0,大小爲0x5f,因此此處段表應該是從0x11f開始(0xc0+0x5f)。再根據e_shnum=23和ehentsize=28可知,有23個段,每一個段佔28個字節大小,總共佔據644個字節(16進製爲0x284)。段入口的類型定義以下(/usr/include/elf.h):
    • 從0x1174開始有13個段,每一個段佔28個字節大小。
  • 第一個段,其中內容所有爲0,因此不表示任何段。內容以下:
  • 第二個段對應內容爲:
    • 段中每一個成員均爲4個字節,因此分析起來相對簡單一些。
    • sh_name值爲0x0000001f,它表示該段名稱在.shstrtab中偏移量,經過計算可知該名稱爲.text。
    • sh_type值爲0x00000001(對應SHT_PROGBITS),表示這個段擁有程序所定義的信息,其格式和含義徹底有該程序肯定。
    • sh_flags值爲0x00000006(對應於SHF_ALLOC和SHF_EXECINSTR)。
    • sh_addr值爲0x00000000,表示這個段不會出如今進程的地址鏡像中。
    • sh_offset值爲0x00000034(偏移地址),
    • sh_size值爲0x00000017,表示代碼段大小爲23(0x17)個字節。
    • sh_link值爲0x00000000,表示沒有連接信息。
    • sh_info值爲0x00000000,表示沒有輔助信息。
    • sh_addalign值爲0x00000004,表示4個字節對齊
    • sh_entsize值爲0x00000000,表示沒有入口。
  • 第三個段爲:
    • 該段爲.rel.text段(偏移量爲0x0000001b),sh_type爲0x00000009(對應SHT_REL),sh_offset爲0x000003ec,sh_size爲0x00000010(16個字節)。sh_link和sh_info分別爲b和1,分別表示相關符號表索引和重定位應用段的段頭索引。其他段的內容再也不詳細分析,能夠本身分析並於前面readelf輸出結果相對照。
      ……索引

  • 第23個段
相關文章
相關標籤/搜索