可執行程式的裝載

2021-07-11 02:53:36 字數 2040 閱讀 9653

elf檔案頭部有一些重要的資訊:例如:entry point address:0x8048000 是可執行檔案載入到記憶體中開始執行的第一行**。

裝載時動態鏈結(load-time dynamic linking):這種方法的前提是在編譯之前已經明確知道要呼叫的動態庫的哪些函式,編譯時在目標檔案中只保留必要的鏈結資訊,而不含動態庫函式**;當程式執行時,呼叫函式的時候利用鏈結資訊載入動態庫函式**並在記憶體中將其鏈結入呼叫程式的執行空間中(全部函式載入進記憶體),其主要目的是便於**共享。(動態引導程式,處在載入階段,主要為了共享**,共享**記憶體)

執行時動態鏈結(run-time dynamic linking):這種方式是指在編譯之前並不知道將會呼叫哪些動態庫函式,完全是在執行過程中根據需要決定應呼叫哪個函式,將其載入到記憶體中(只載入呼叫的函式進記憶體);並標識記憶體位址,其他程式也可以使用該程式,並獲得動態庫函式的入口位址。(動態庫在記憶體中只存在乙份,處在執行階段)

乙個程序在建立的時候是完全複製父程序的內容資訊,此時呼叫execv系統呼叫的時候,此時新程序的執行環境把父程序的環境覆蓋掉了,使用者態堆疊清空了。那麼命令列引數和環境變數是如何進入新程式的堆疊的呢?答:shell程式->execve->sys_execve,然後在初始化新程式堆疊時拷貝進去。

shell會呼叫execve將命令列引數和環境引數傳遞給可執行程式的main函式

int execve(const char * filename,char * const argv[ ],char * const envp[ ]);

庫函式exec*都是execve的封裝例程

裝載程式

我們在 sys_execve 處設定斷點開始追蹤分析,如下圖:

我們發現 execve 是比較特殊的系統呼叫,exec_binprm 在儲存了 bprm 後呼叫該函式來進一步操作,execve 載入的可執行檔案會把當前的程序覆蓋掉,返回之後就不是原來的程式而是新的可執行程式起點。這個函式除了儲存 pid 以外,還執行了 search_binary_handler 來查詢能夠處理相應可執行檔案格式的處理器,並呼叫相應的load_binary 方法以啟動新程序。

search_binary_handler:

int search_binary_handler(struct linux_binprm *bprm)

load_elf_binary:

static int load_elf_binary(struct linux_binprm *bprm)

...//如果需要裝入直譯器,並且直譯器的映像是elf格式的,就通過load_elf_interp()裝入其映像,並把將來進入使用者空間時的入口位址設定成load_elf_interp()的返回值,那顯然是直譯器的程式入口。而若不裝入直譯器,那麼這個位址就是目標映像本身的程式入口。

if (elf_interpreter)

if (bad_addr(elf_entry))

reloc_func_desc = interp_load_addr;

allow_write_access(interpreter);

fput(interpreter);

kfree(elf_interpreter);

} else }}

5.總結

linux 系統通過使用者態 execve 函式呼叫核心態 sys_execve 系統呼叫,負責將新的程式**和資料替換到新的程序中,開啟可執行檔案,載入依賴的庫檔案,申請新的記憶體空間,最後執行 start_thread 函式設定 new_ip 和 new_sp,完成新程序的**和資料替換,然後返回並執行新的程序**。

python 執行可執行程式

python do exe.pyw coding utf 8 import os exe dir c program files q dir exe file q dir.exe def do cmd dir,file if os.access dir,os.f ok os.chdir dir if...

Android可執行程式

最近應用了android kernel下高通的乙個security patch,各種方式出log,也沒有走到patch處。通過網上查詢,看到有人寫了個main函式,呼叫此patch所在的module。但是建立出執行檔案,push到某家手機的 system bin下,告訴是唯讀檔案系統,不能push進...

可執行程式的組成

上一節分析了c語言應用程式中各段的情況,實際的c語言可執行程式,將由各個檔案經過連線生成。目標檔案是由每乙個c語言源程式 c 經過編譯器生成,目標檔案 o 的主要組成部分即 段 唯讀資料段和讀寫資料段三個段。未初始化資料段 堆和棧不會占用目標檔案的空間。可執行程式是由各個目標檔案經過連線而成。其主體...