Wine中PE格式文件的加載(三):PE格式文件的加載

前面分析到ntdll中加載了kernel32,然後調用了kernel32的初始化函數__wine_kernel_init。該函數的實現在dlls/kernel32/process.c中。內容較多,就不完整截圖了

首先函數開始獲取了需要加載的windows應用的路徑名,這個就是在開始執行的命令的微信的絕對路徑,在wine中一般爲“/home/username/.wine/drive_c/Programfile/Tencent/WeChat/WeChat.exe”

這個值在wine開始時將其放入全局變量,使用時還做了一些字符編碼格式的處理

__wine_main_argc = argc;

__wine_main_argv = argv;

還有需要注意的是之前創建的PEB,TEB在這個過程中會不斷的完善數據,而且需要是使用,比如這裏也將路徑寫入了PEB。

得到了可執行文件的路徑,接下來就是加載的具體實現。

 

部分函數代碼如下圖所示:

LoadLibraryExW在dlls/kernel32/module.c中實現,kernel32是加載了的,因此可以使用該函數。

最終在dlls/ntdll/loader.c中實現,實現函數爲LdrLoadDll,這也符合windows以及wine的實現結構,從kernel32到ntdll。

 

LdrLoadDll函數如下圖所示:

主要調用了load_dll實現,而load_dll中,根據native還是buitin來分別調用不同的函數load_native_dll、load_buitin_dll。

Load_native_dll函數實現用到了下面兩個函數:

先講NtCreateSection(實現在dlls/ntdll/virtual.c)。在wineserver中,發送了“create_mapping”,在wineserver中創建了一個mapping對象,數據來自file,file是在這之前打開了PE格式文件的fd對應在wine中HANDLE.在mapping創建好後分配了handle將其返回(wine中對象的管理使用handle)

create_mapping函數在server/mapping.c中,函數調用了get_image_params用來獲取PE中數據。

下面具體分析get_image_params函數

首先聲明一個dos結構體,這是對應pe文件中dos頭,這個dos頭在使用時是爲了兼容dos系統。(該結構體中有一個偏移量數據e_lfanew,爲PE頭的離文件頭部的偏移量。Windows加載器通過它可以跳過DOS Stub部分直接找到PE頭)

然後聲明瞭section頭。這兩個結構體都是在winnt.h中定義的。

還聲明一個nt結構體,對應PE頭。

其中,兩個結構體具體定義分別如下圖所示:

然後,通過下面代碼分別得到了dos頭和pe頭。

接下來,執行下面的代碼(32位執行上面部分),得到了mapping->base

最後通過上面的代碼,加載section頭。將pos指向section頭開始地址;sec的大小乘個數量得到size;最後用pread函數用lseek控制從pos開始讀。

 

上面NtCreateMapping得到了一個mapping,接下來就是將PE文件根據mapping映射到內存中,通過函數NtMapViewOfSection實現。

該函數首先調用了map_image,該函數主要作用是將可執行PE格式文件映射到內存。部分函數代碼如下圖所示:

在該函數中調用map_view函數,用來創建一個試圖並且用mmap保留一塊兒相對應的內存區域。

在這裏做了判斷,是否在預留的內存空間中switch (wine_mmap_is_in_reserved_area( base, size ))然後調用了if ((ptr = wine_anon_mmap( base, size, VIRTUAL_GetUnixProt(vprot),MAP_FIXED )) != base)實際就是做了一個匿名映射。

最後創建結構體file_view,這個結構體對象在真正映射數據時用status =create_view( view_ret, ptr, size, vprot );

map_view部分函數代碼如下圖所示:

接下來,就是具體的內存映射。調用了幾次map_file_into_view函數,先映射PE頭,再映射各個section。而映射Section時是根據每一個Section頭的sec->VirtualAddress得到數據。

如下圖所示:



發佈了28 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章