pwn學習日記Day21 《程序員的自我修養》讀書筆記

Linux內核裝載ELF過程

(1)bash進程調用fork()系統調用建立一個新的進程
(2)新的進程調用execve()系統調用執行指定的ELF文件,原先的bash進程繼續返回等待剛纔啓動的新進程結束,而後繼續等待用戶輸入命令。
(3)execve()系統調用相應的入口是sys_execve(),sys_execve()進行一些參數的檢查複製後,調用do_execve()。
(4)do_execve()讀取128個字節的文件頭部,調用search_binary_handle()。
(5)search_binary_handle()經過魔數肯定文件格式,並調用相應的裝載過程:
1.檢查ELF可執行文件格式的有效性,好比說魔數、程序頭中段的數量。
2.尋找動態連接「interp.」段,設置動態連接器路徑。
3.根據ELF可執行文件的程序頭表的描述,對ELF文件進行映射,好比代碼、數據、只讀數據。
4.初始化ELF進程環境,好比進程啓動時EDX寄存器的地址應該是DT_FINI的地址。
5.將系統調用的返回地址修改爲ELF可執行文件的入口點,這個入口點取決於程序的連接方式,對於靜態連接的ELF可執行文件,這個程序入口就是ELF文件的文件頭中e_entry所指的地址;對於動態連接的ELF可執行問文件,程序的入口點是動態連接器。
(6)上訴步驟執行完,返回do_execve再返回至sys_execve()時,系統調用的返回地址改爲了被裝載的ELF程序的入口地址了,因此當sys_execve()系統調用從內核態返回到用戶態時,EIP寄存器直接跳轉到了ELF程序的入口地址,因而新的程序開始執行,ELF可執行文件裝載完成。linux

可執行文件的裝載與進程章總結

這一章中,探討了程序運行時如何使用內存空間的問題,即進程虛擬地址空間問題。接着圍繞程序如何被操做系統裝載到內存中進行運行,介紹了覆蓋裝入和頁映射的模式,分析以頁映射的方式將程序映射至進程地址空間的好處,並從操做系統的角度觀察進程如何被創建,當程序運行時發生頁錯誤該如何處理等。
還詳細介紹了虛擬地址空間分佈,操做系統如何爲程序的代碼、數據、堆、棧在進程地址空間中分配,它們是如何分佈的。最後兩個章節分別深刻介紹了Linux和Windows程序如何裝載並運行ELF個PE程序。這章中,咱們假設程序都是靜態連接的,那麼它們都只有一個單獨的可執行文件模塊。程序員

地址無關代碼總結

  • 模塊內部指令跳轉、調用:相對跳轉和調用
  • 模塊內部數據訪問:相對地址訪問
  • 模塊外部指令跳轉、調用:間接跳轉和調用(GOT)
  • 模塊外部數據訪問:間接訪問(GOT)

知識雜項:

  • bash進程:就是shell的進程,每個已登陸的用戶都有bash這個進程,當一個用戶在終端上面登陸後,Linux系統就會給這個用戶一個shell,這個shell就是bash進程(當默認shell程序是bash時),而後你接下來執行的命令都是這個bash進程的子進程,由於它是大部分命令行啓動的程序的父進程,因此不要隨便終結它。
  • fork()函數:一個進程調用fork()函數後,系統先給新的進程分配資源,例如存儲數據和代碼的空間。而後把原來的進程的全部值都複製到新的新進程中,只有少數值與原來的進程的值不一樣。至關於克隆了一個本身。
  • execve()函數:execve(執行文件)在父進程中fork一個子進程,在子進程中調用exec函數啓動新的程序。exec函數一共有六個,其中execve爲內核級系統調用,其餘(execl,execle,execlp,execv,execvp)都是調用execve的庫函數。
  • DLL(Dynamic Link Library)文件:爲動態連接庫文件,又稱「應用程序拓展」,是軟件文件類型。在Windows中,許多應用程序並非一個完整的可執行文件,它們被分割成一些相對獨立的動態連接庫,即DLL文件,放置於系統中。當咱們執行某一個程序時,相應的DLL文件就會被調用。一個應用程序可以使用多個DLL文件,一個DLL文件也可能被不一樣的應用程序使用,這樣的DLL文件被稱爲共享DLL文件。

參考

《程序員的自我修養》shell

相關文章
相關標籤/搜索