在本文的這個部分,針對 Linux 系統是如何來辨別這些不同的可執行檔,以及整體的執行流程來作一個說明。
程序啟動的流程
在 linux 的環境中最常見的可執行檔的種類包括了 Script 檔、Aout 格式的執行檔、ELF 格式的執行檔。在本文的這個部分,我會針對 Linux 系統是如何來辨別這些不同的可執行檔,以及整體的執行流程來作一個說明。
我在此大略說明一下程序啟動的流程,當我們在 shell 中輸入指令時,會先去系統的路徑中來尋找是否有該可執行檔存在,如果找不到的話,就會顯示出找不到該可執行檔的訊息。如果找到的話,就會去呼叫 execve()來執行該檔案,接下來 execve() 會呼叫 System Call sys_execv(),這是在Linux 中 User Mode 透過 80 號中斷(int 80 ah=11)進入 Kernel Mode 所執行的第一個指令,之後在 Kernel 中陸續執行 do_exec()、 prepare_binprm()、read_exec()、search_binary_handler(),而在 search_binary_handler() 函式中,會逐一的去檢查目前所執行檔案的型態(看看是否為Script File、aout 或 ELF 檔),不過 Linux 所采用的方式是透過各個檔案格式的處理程序來決定目前的執行檔所屬的處理程序。
如下圖,會先去檢驗檔案是否為 Script 檔,若是直進入 Script 檔的處理程序。若不是,則再進入 Aout 檔案格式的處理程序,若該執行檔為 Aout 的檔案格式便交由 Aout檔案格式的處理程序來執行。如果仍然不是的話,便再進入 ELF 檔案格式的處理程序,如果都找不到的話,則傳回錯誤訊息。
由這種執行的流程來看的話,如果 Linux Kernel 想要加入其他的執行檔格式的話,就要在 search_binary_handler() 加入新的執行檔的處理程序,這樣一旦新的執行檔格式產生後,在 Linux 下要執行時,因為在do_load_script、do_load_aout_binary、do_load_elf_binary都會傳回錯誤,因此只有我們自己的 do_load_xxxx_binary 函式可以正確的接手整個執行檔的處理流程,因此便可以達成新的檔案格式置入的動作哩。
在函式 do_load_elf_binary () 執行時,首先會去檢視目前的檔案是否為 ELF 格式,如下程序碼
if (elf_ex.e_ident[0] != 0x7f' '
strncmp(&elf_ex.e_ident[1], "ELF", 3) != 0)
goto out;
if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
goto out;