深入理解程式的結構
程式的構成:從作業系統的角度來看
檔案頭記錄了與可執行檔案相關的一些基本資訊。
靜態分析工具大多根據程式的檔案頭獲得相關資訊。
初始化的變數進入.data段,沒有初始化的全域性變數進入.bss段。
未初始化的變數預設為0,為了儲存效率和載入效率。
沒有初始化的預設為0,在程式檔案中就不用儲存初始值了,只需在程式檔案中記錄:有幾個全域性變數,以及它們的型別。
而data段要儲存初始值。
實驗分析:
程式碼如下:
做如下編譯:
-e指明程式入口,-nostartfiles說明不使用程式自帶的那些啟動檔案。
使用objdump可以檢視程式有哪些段:
1、2這兩個段是gnu系統特有的輔助段,7這個段也是可以去掉的。 最重要的就是.text段。我們這個程式中沒有資料段。
改寫程式:
objdump結果如下:
.data和.bss段都有了。
改程式設計序:
objdump結果如下:
編譯器預設按4位元組對齊,因此bss段還是佔用8位元組。
將程式改成如下形式就佔用4個位元組了:
使用nm檢視符號:
dt_main和text段的初始地址正好對應上。
g_no_value在bss段,其中的B代表bss。g_value在data段,D代表data。
c_no_value和bss的起始地址是一致的。
c_no_value之後就是g_no_value。
用objdump檢視data段中儲存的初始值資訊:
上圖表示從8049ff4開始儲存了01000000 02000000
改造程式:
編譯之後objdump結果如下:
data段的位元組數是21,4位元組對齊之後data段的大小應該是24,圖中顯示的18是16進位制。正好等於十進位制的24。
nm檢視符號:
可以看到多了一個符號g_str。
再次改寫程式:
objdump結果和nm結果:
g_c的記憶體地址正是rodata段的起始地址。
檢視rodata段的內容: