-
讀取PE檔案
當一個PE檔案被執行時,Windows的建立程序函式(CreateProcess)首先被呼叫,負責為新程序建立虛擬地址空間。
作業系統從磁碟讀取PE檔案,將其頭部內容(DOS頭、PE頭和節表)載入記憶體,以獲取該檔案的結構和裝載資訊。 -
檢查PE檔案有效性
作業系統首先會檢查PE檔案的合法性,比如驗證DOS頭中的 "MZ" 簽名,接著檢查PE頭中的 "PE\0\0" 簽名。
如果檔案不符合PE格式要求,作業系統會中止載入並返回錯誤。 -
分配虛擬地址空間
根據PE頭部的資訊,作業系統會為程序分配所需的虛擬地址空間。其中包括程式的程式碼段、資料段、堆疊等。
裝載基地址:PE檔案頭中包含一個“裝載基地址”(ImageBase),指明程式希望被載入到哪個虛擬地址。如果該地址不可用(例如,衝突),則需要重定位。
作業系統使用分頁記憶體管理機制來為程式分配虛擬記憶體區域,但此時並不會將所有PE檔案的內容都立即載入到實體記憶體中。 -
載入各個段到虛擬記憶體
根據節表(Section Table)的描述,作業系統會將PE檔案中的不同段(如程式碼段、資料段等)對映到程序的虛擬地址空間中:
程式碼段(.text)通常是隻讀和可執行的。
資料段(.data)是讀寫區域,存放全域性變數和已初始化的資料。
未初始化資料段(.bss)通常被作業系統初始化為0。
匯入表(.idata)、匯出表(.edata)等特殊段也會對映到記憶體中,用於動態連結庫的管理。
作業系統在載入時會將這些段對映到虛擬地址空間中,並且可能使用惰性載入(Lazy Loading)策略,即只有在段被實際訪問時才會將其載入到實體記憶體中。 -
動態連結庫(DLL)的載入與解析
如果PE檔案有匯入表(Import Table),它會列出該可執行檔案所依賴的DLL檔案及其函式。
作業系統會讀取匯入表中的每一個DLL名稱,並嘗試載入這些DLL檔案。未載入的DLL檔案將被作業系統載入到當前程序的虛擬地址空間中。
接著,作業系統會解析匯入表中所引用的每個函式符號,並將它們對映到正確的記憶體地址上。如果函式是延遲繫結的(如使用 LoadLibrary 和 GetProcAddress 動態載入),則它們會在第一次被呼叫時載入。 -
地址重定位(Relocation)
如果PE檔案的裝載基地址被作業系統佔用,作業系統會將PE檔案載入到不同的地址空間。此時需要進行重定位,即調整PE檔案中的指標和地址,使其指向新的基地址。
重定位資訊儲存在PE檔案中的重定位表(Relocation Table)中,作業系統會根據該表修正所有與基地址相關的地址。 -
執行TLS回撥函式
如果PE檔案使用了執行緒區域性儲存(TLS),在載入過程中,作業系統會呼叫TLS回撥函式。這些回撥函式通常用於在程序或執行緒初始化時執行特定的任務,如全域性變數初始化等。 -
設定初始棧和堆
作業系統為程序分配堆疊和堆。堆疊用於儲存函式呼叫資訊和區域性變數,堆用於動態記憶體分配。
棧空間初始分配較小,隨著函式呼叫的深入,棧空間會動態增加。 -
跳轉到入口點執行
PE檔案的PE頭中有一個入口點(Entry Point),它是程式的主執行程式碼的起始地址。
作業系統透過載入器跳轉到入口點並開始執行程式。對於普通應用程式,入口點通常是 main() 函式;對於DLL檔案,則是 DllMain() 函式。 -
執行程式的主邏輯
從入口點開始,程式的執行邏輯正式執行,執行程式碼、訪問資料,並與作業系統、其他程序或裝置進行互動。
如果程式請求記憶體或與外部裝置互動,會透過系統呼叫來請求作業系統的服務。
三、程序結束和解除安裝
當程序完成後,程式會透過系統呼叫 ExitProcess() 或 exit() 通知作業系統結束執行。
作業系統會清理該程序分配的虛擬地址空間,釋放實體記憶體,並將該程序的所有資源(包括檔案控制代碼、記憶體等)返還給系統。
如果是DLL檔案,作業系統會根據需要呼叫 FreeLibrary() 函式解除安裝不再使用的DLL,並清理與該DLL相關的資源。
windows載入PE檔案的流程
相關文章
- ResHacker 用命令列方式修改 windows PE檔案版本號命令列Windows
- PE 檔案結構圖
- PE檔案結構複習
- PE檔案結構解析3
- PE檔案結構解析1
- PE檔案結構解析2
- PHP:檔案載入PHP
- 載入常量-從檔案中載入
- 21.1 Python 使用PEfile分析PE檔案Python
- PE檔案格式詳細解析(一)
- 7、靜態檔案的載入
- 再探.NET的PE檔案結構(安全篇)
- 下載 Windows 光碟映像(ISO 檔案)Windows
- properties檔案載入器
- giflib載入GIF檔案
- WKWebView載入本地檔案WebView
- MyBatis載入配置檔案MyBatis
- laravel 載入公共檔案Laravel
- Springboot載入配置檔案Spring Boot
- JavaScript 檔案載入方式JavaScript
- PE檔案格式詳細解析(二)--IAT
- 惡意軟體PE檔案重建指南
- SpringBoot是如何載入配置檔案的?Spring Boot
- Android 的 so 檔案載入機制Android
- PHP檔案的自動載入(autoloading)PHP
- 下載 Windows Server 光碟映像(ISO 檔案)WindowsServer
- Windows系統電腦不能載入本地儲存的配置檔案的解決方法Windows
- 載入Mapper對映檔案APP
- JAVA載入配置檔案方法Java
- js動態載入 js檔案和 css檔案JSCSS
- Windows Ping伺服器列表,把Ping的通寫入OK檔案,Ping不通的寫入NO檔案Windows伺服器
- SigFlip如何篡改身份認證碼簽名的PE檔案
- SpringBoot原始碼解析-配置檔案的載入Spring Boot原始碼
- JVM載入Class檔案的原理機制JVM
- SpringBoot載入子模組配置檔案的方法Spring Boot
- Spring Boot @PropertySource 載入指定配置檔案、@ImportResource 匯入Spring 配置檔案Spring BootImport
- windows下ftp定時執行批次下載檔案,windows下ftp定時執行批次下載檔案的一種方法WindowsFTP
- PE檔案結構解析 Part3 NT HeadersHeader