常用的分析ELF文件的命令(readelf、objdump及od)


readelf:
-h:文件頭
-S:段表
-s:符號表
-d: 查看依賴庫
-p:查看某個段內容,非常重要。如:readelf -p .comment libc.so (通過-p對只讀段的查看就可以替代strings命令)

objdump:
-d:反匯編(objdump我基本只用這一個)
-h:段表,同readelf -S,所以可以不用記
–s:代碼段、數據段、只讀數據段,各個段二進制
-a:看一個.a靜態庫文件中包含了哪些目標文件

od:
如:十六進制輸出數據並且地址以十進制打印:od -A d -t xCc 文件

命令中各選項的含義:
- A 指定地址基數,包括:
d 十進制
o 八進制(系統默認值)
x 十六進制
n 不打印位移值
- t 指定數據的顯示格式,主要的參數有:
c ASCII字符或反斜杠序列
d 有符號十進制數
f 浮點數
o 八進制(系統默認值為02)
u 無符號十進制數
x 十六進制數

以下為ELF文件各個表的描述,供以后復習

文件頭:描述文件的基礎信息以及找到段表
文件頭查看:readef -h

 

 

 

1)模數
第1個字節:DEL控制符,固定的
第2、3、4個字節:ELF三個字母
第5個字節:文件位數(0:無效、1:ELF32、2:ELF64)
第6個字節:大小端(0:無效、1:小端、2:大端)
第7個字節:ELF文件的主版本號,一般為1
后面的為預留字段。
2)文件類型:REL (Relocatable file)、DYN (Shared object file)、EXEC (Executable file)
3)Machine:   Intel 80386 :硬件平台,此文件適合在哪個硬件平台下運行        
4)程序入口地址
  Entry point address:               0x8048310
代表程序入口的虛擬地址,只有可執行文件跟共享庫有入口(共享庫的入口地址有什么用呢?)
5)Start of program headers:   52 (bytes into file) : (readelf -l ), 程序表頭,裝載時用到,因為目標文件不需要裝載,所以為0。
6)Start of section headers:          2000 (bytes into file)
      段表在文件中的偏移,也就是說段表從文件中的2000個字節開始的
      2000是10進制,用計算器轉換成16進制后就可以在那個,這個特別重要,找到段表,就代表了什么都有了
7)Size of section headers:           40 (bytes)
段表描述符的大小,猜測:會根據平台的不同,這個是固定的,因為在同一個平台下不同代碼編出來的目標文件,結果是一樣的
8)Number of section headers:         11
段表描述符數量,elf文件中,擁有的段的數量(所以說,一個段表描述符就是在描述一個段唄)
證明(readelf -S )
9)Size of this header:     52 (bytes)
ELF文件頭本身的大小,猜測:會根據平台的不同,這個是固定的
10)Section header string table index: 8
段表字符串表所在的段在段表中的下標

總結:通過文件頭找段表,之后在段表里面找到段表字符串表,段表中就能找到段表字符串標在文件中的偏移,之后就能生成整個段表。

段表:描述每個段的詳細信息
段表查看:readelf –S, 如果gcc –g的話,還會有很多調試信息段 

 

 

 

Name:在段表描述符里存了一個整形,這個整形是段名在段表字符串表(.shstrtab)中的偏移。
Type:段的類型,如下表
Addr:如果可以被加載,代表了該段在虛擬內存空間的地址,否則為0,可以看出來,段表字符串表、符號表、字符串表都不會被加載的
Off:如果該段在文件中,則代表了在文件中的偏移
Size:段長
Flags:標志
Lk跟Inf:段的鏈接信息
Al:段地址對齊,代表這個段是幾字節對齊的
ES:項的長度:如果該段的每一項的長度是固定的,那么就代表每一項的長度,如符號表的每個符號的信息長度都是0x10個字節。對於變化的就是0。符號表里存的符號名,只是符號在字符串表中的索引,符號表里不是直接存的符號。

 

 


Flags字段:段的標志,表示該段在進程虛擬空間中的屬性,可讀/可寫/可執行,這個標志比較重要,因為在加載的時候,會根據段的標志進行加載的,大概是只讀放在一個區域,可讀可寫放在一個區域等

 

 

 

Lk跟Inf:段的鏈接信息,與鏈接、重定位相關的段,這兩個信息才有意義

 

 

 

重要段:代碼段、數據段、只讀數據段、BSS段
代碼段、數據段、只讀數據段:objdump –s
代碼段:程序指令,objdump -d反匯編
數據段:已經初始化了全局變量和局部靜態變量
只讀數據段:只讀變量以及字符串常量
BSS段:存放了未初始化的全局變量和局部靜態變量,通過符號表可以看出

 

 

 

字符串表:符號名等

 

 

段表字符串表:段名

 

 


注釋提示段

 

 


符號表: readelf -s / nm / objdump -x
符號名:該符號在字符串表中的下標
符號值:目標文件中:非COMMON類型表示該符號在所在段中的偏移,common類型表示對齊屬性;可執行文件中:代表虛擬地址(動態鏈接器如何用它?)
符號大小:非0代表該符號值的數據類型的大小,0代表未知或0
符號類型和綁定信息:符號類型:數據?函數?段?文件?符號綁定信息:局部符號(外部不可見)?全局符號(外部可見)?弱引用?低4位表示符號的類型,高28位表示符號的綁定信息,看下表
其他:目前沒用,為0
符號所在的段:如果非0數字,代表了是在本文件中定義的符號,並且代表了對應的段,其余含義為:UND:本目標文件未定義;ABS:絕對的值,如文件名;COMMON:COMMON塊類型(未初始化的全局變量)

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM