版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
DLL注入5.1Windows系統(tǒng)編程基礎(chǔ)5.2DLL注入的概念5.3DLL注入的基本方法5.4DLL卸載5.5通過修改PE裝載DLL5.6代碼注入5.7思考與練習(xí)
5.1Windows系統(tǒng)編程基礎(chǔ)
5.1.1數(shù)據(jù)類型首先,我們介紹一些WindowsAPI聲明中常用的類型,這些類型既可以用于API的參數(shù)類型,也可以用于API的返回值類型,具體類型含義如表5-1所示。
5.1.2Unicode和字符編碼
在進(jìn)行具體編程方法介紹之前,還需要介紹Windows是如何處理字符編碼,如何區(qū)分8位和16位字符的。Windows支持8位字符(CHAR)以及16位寬字符(WCHAR)。Windows提供的寬字符集支持UnicodeUTF-16的編碼方式。Unicode是一種雙字節(jié)編碼機(jī)制的字符集,使用0~65535之間的雙字節(jié)無符號整數(shù)對每個(gè)字符進(jìn)行編碼。
從WindowsNT開始,系統(tǒng)的核心就是完全采用Unicode函數(shù)的。雖然其API既有支持ANSI字符串的API(以-A為后綴),也有支持Unicode的API(以-W為后綴),但實(shí)際上,當(dāng)調(diào)用任一系統(tǒng)函數(shù)并傳入ANSI字符串時(shí),系統(tǒng)會首先將該字符串轉(zhuǎn)換為Unicode字符串;如果希望系統(tǒng)返回ANSI字符串,系統(tǒng)也會先將Unicode字符串轉(zhuǎn)換為ANSI字符串,然后再返回給應(yīng)用程序。
由于Windows也支持標(biāo)準(zhǔn)C語言運(yùn)行庫,因此我們首先看一下C語言是如何支持Unicode的。C語言中的8位ANSI字符類型定義為char,16位的寬字符類型定義為wchar_t。實(shí)際上,標(biāo)準(zhǔn)的C語言運(yùn)行時(shí)字符串函數(shù)(如strcpy、strchr和strcat等)只能處理ANSI字符串,無法處理Unicode字符串。為此,ANSIC也加入了一些Unicode操作函數(shù),這些函數(shù)均以wcs-前綴起始,如表5-2所示。可見,若要調(diào)用Unicode操作函數(shù),只需用寬字符串前綴wcs-替換ANSI字符串前綴str-即可。這些Unicode操作函數(shù)也是在頭文件string.h中聲明的。
首先,應(yīng)包含tchar.h代替string.h。tchar.h的功能是幫助創(chuàng)建ANSI/Unicode通用的源代碼文件。在實(shí)際編程時(shí),應(yīng)使用tchar.h中定義的宏。編譯器會根據(jù)我們的代碼是否定義宏_UNICODE,來決定到底是選擇ANSI字符串操作函數(shù)還是Unicode字符串操作函數(shù)。在定義字符時(shí),使用TCHAR作為字符類型。如果定義了宏_UNICODE,則TCHAR的定義為
typedefwchar_tTCHAR;
如果沒有定義宏_UNICODE,則TCHAR定義為
typedefcharTCHAR;
對于字符串字面常量,需要加L-前綴才能作為Unicode字符串處理,例如“string”是ANSI字符串,而L“string”是Unicode字符串。使用_TEXT宏(亦即_T宏)可以統(tǒng)一二者的差別。
還要注意,上述的宏_UNICODE和宏UNICODE是兩個(gè)不同的宏,宏_UNICODE用于C運(yùn)行時(shí)頭文件,而宏UNICODE用于Windows頭文件。因此,當(dāng)同時(shí)使用windows.h和tchar.h中的類型且需要用到Unicode編碼時(shí),應(yīng)同時(shí)定義宏_UNICODE和宏UNICODE。
關(guān)于Unicode下函數(shù)的定義,有如下基本原則:
(1)C語言的main,應(yīng)被宏_tmain代替。_tmain在tchar.h中定義。因此,典型的主函數(shù)樣式如下:
#include<windows.h>
#include<tchar.h>
int_tmain(intargc,LPTSTRargv[]){
…
}
(2)宏UNICODE也會決定調(diào)用Windows頭文件中的哪個(gè)函數(shù)版本。在DLL中,一般會包含兩個(gè)功能相同但分別接受ANSI字符串和Unicode字符串的函數(shù)版本,例如CreateWindowEx的兩個(gè)實(shí)現(xiàn)版本分別為CreateWindowExA和CreateWindowExW。以-A為后綴的實(shí)現(xiàn)接受ANSI字符串,以-W為后綴的實(shí)現(xiàn)接受Unicode字符串。通常,-A版本的函數(shù)也是通過字符串轉(zhuǎn)換后調(diào)用-W版本的函數(shù)加以實(shí)現(xiàn)的。
(3)使用C運(yùn)行時(shí)字符串操作函數(shù)(無論是ANSI字符串版本還是Unicode字符串版本)都是相對低效的,應(yīng)使用Windows自己提供的ANSI/Unicode字符串操作函數(shù)。這些函數(shù)的功能如表5-3所示。這些函數(shù)也是以宏的形式定義的,并由宏UNICODE決定到底調(diào)用-A版本的函數(shù)實(shí)現(xiàn)還是-W版本的函數(shù)實(shí)現(xiàn)。舉例來說,表5-3中的wsprintf()函數(shù)是WindowsAPI版本的格式化字符串函數(shù),支持ANSI/Unicode通用的字符串處理。
該函數(shù)是一個(gè)宏定義,根據(jù)宏UNICODE決定到底調(diào)用wsprintfA()還是wsprintfW()。本章后續(xù)API形參聲明中的_In_、_Out_、_Inout_、_In_opt_、_Out_opt_、_Inout_opt_分別是代表輸入?yún)?shù)、輸出參數(shù)、輸入輸出參數(shù)、可選輸入?yún)?shù)、可選輸出參數(shù)、可選輸入輸出參數(shù)的宏。
5.1.3常用Windows核心API簡介
本小節(jié)將介紹一些在本書后續(xù)章節(jié)會用到的WindowsAPI的用法,其中的主要內(nèi)容來自微軟MSDN網(wǎng)站。這一介紹顯然不可能涵蓋Windows系統(tǒng)編程中的所有重要API。如果讀者希望更深入地學(xué)習(xí)Windows系統(tǒng)編程的方法,可以參考JeffreyRichter的《Windows核心編程》。
表5-4中列出了典型的與進(jìn)程和線程操作相關(guān)的API。
表5-5中列出了典型的與內(nèi)存、對象或模塊操作相關(guān)的API。
表5-6中列出了典型的與鉤子過程相關(guān)的API。
5.1.4制作用于注入的DLL
在學(xué)習(xí)如何進(jìn)行DLL注入之前,我們先要學(xué)習(xí)如何通過編程得到一個(gè)用于注入的DLL。在進(jìn)行DLL開發(fā)時(shí),將VisualStudio的項(xiàng)目配置類型選為.dll,將其字符集改為使用Unicode字符集。
進(jìn)一步看ThreadProc線程具體做了什么。簡單地講,ThreadProc線程會使用URLDownloadToFile()函數(shù)對URL為“”的網(wǎng)頁進(jìn)行下載,下載到的文件路徑為“當(dāng)前DLL被裝載到的進(jìn)程的可執(zhí)行文件所在的完整路徑\index.html”。由于GetModuleFileName()函數(shù)的第一個(gè)參數(shù)為NULL,因此會返回當(dāng)前進(jìn)程可執(zhí)行文件所在的完整路徑,該路徑被存放在參數(shù)szPath所指向的內(nèi)存緩沖區(qū)中。此后,通過_tcsrchr()函數(shù)和lstrcpy()函數(shù)構(gòu)造目標(biāo)文件的路徑,并最終通過URLDownloadToFile()函數(shù)進(jìn)行頁面的下載。
第二個(gè)DLL的源代碼如表5-8所示。GetModuleFileName()函數(shù)的第一個(gè)參數(shù)為NULL,指明szPath中存放的是當(dāng)前DLL被裝載到的進(jìn)程的可執(zhí)行程序文件所在路徑。DLL判斷這一可執(zhí)行程序是否為notepad.exe,如果不是,則什么都不做;如果是,則創(chuàng)建一個(gè)進(jìn)程,該進(jìn)程通過IE瀏覽器訪問頁面。
5.2DLL注入的概念
DLL中可以有DllMain()函數(shù)。當(dāng)程序裝載DLL時(shí),會調(diào)用該DLL的DllMain()函數(shù)。DllMain()函數(shù)的一般框架如表5-9所示,其參數(shù)hinstDLL是DLL實(shí)例的句柄,即DLL映射到進(jìn)程地址空間后,在進(jìn)程地址空間中的位置。如果我們將希望執(zhí)行的代碼放入DllMain()中,那么每當(dāng)該DLL被裝載時(shí),這些代碼即得到執(zhí)行。這一機(jī)制可用于修復(fù)bug或向程序增加新功能。進(jìn)程向自己的地址空間裝載DLL時(shí),通常會調(diào)用LoadLibrary()函數(shù)。
DLL注入指的是,向運(yùn)行中的其他進(jìn)程強(qiáng)制插入特定的DLL文件。亦即,需要從進(jìn)程的外部向目標(biāo)進(jìn)程發(fā)出調(diào)用LoadLibrary()函數(shù)的命令,裝載我們指定的DLL文件,強(qiáng)制調(diào)用執(zhí)行該DLL的DllMain()函數(shù)。DLL被裝載到目標(biāo)進(jìn)程地址空間以后,即具有訪問該進(jìn)程內(nèi)存的合法權(quán)限。
5.3DLL注入的基本方法
DLL注入的基本方法分為以下三種:
(1)調(diào)用CreateRemoteThread()函數(shù)創(chuàng)建遠(yuǎn)程線程;
(2)使用注冊表的AppInit_DLLs值;
(3)通過SetWindowsHookEx()函數(shù)進(jìn)行消息鉤取。
5.3.1遠(yuǎn)程線程創(chuàng)建
注入DLL的第一種方法是通過調(diào)用CreateRemoteThread()函數(shù),驅(qū)使目標(biāo)進(jìn)程調(diào)用LoadLibrary()函數(shù),從而裝載指定DLL。
CreateRemoteThread()函數(shù)的功能和參數(shù)已在表5-4中列出。該函數(shù)的lpStartAddress參數(shù)是一個(gè)線程函數(shù)的指針,表示目標(biāo)進(jìn)程中線程函數(shù)的起始地址,此處即LoadLibrary()函數(shù)在目標(biāo)進(jìn)程中的地址;該函數(shù)的lpParameter參數(shù)是要傳入線程函數(shù)的參數(shù)的地址,此處即要注入的DLL的路徑字符串的地址。注意這兩個(gè)參數(shù)地址都應(yīng)是目標(biāo)進(jìn)程的虛擬地址空間中的地址。
表5-10中列出了執(zhí)行注入操作的InjectDll進(jìn)程的代碼片段。InjectDll()函數(shù)接收兩個(gè)參數(shù),dwPID即要被注入DLL的目標(biāo)進(jìn)程的ID,szDllPath即指向被注入DLL的完整路徑名字符串。首先,使用OpenProcess()函數(shù),通過dwPID獲得目標(biāo)進(jìn)程的句柄;然后,在目標(biāo)進(jìn)程地址空間中為DLL路徑名szDllPath開辟一塊存儲空間,將szDllPath路徑字符串寫入該空間;第三步是獲得目標(biāo)進(jìn)程地址空間中LoadLibraryW()函數(shù)的地址,該地址取決于kernel32.dll在目標(biāo)進(jìn)程地址空間中的裝入地址。
由于Windows系統(tǒng)中,各個(gè)進(jìn)程裝入kernel32.dll的地址都是相同的,因此可以通過獲得當(dāng)前進(jìn)程(而非目標(biāo)進(jìn)程)中LoadLibraryW()函數(shù)的地址來代替;第四步,即調(diào)用CreateRemoteThread()函數(shù),在目標(biāo)進(jìn)程中創(chuàng)建線程執(zhí)行LoadLibraryW()函數(shù),裝載由路徑字符串指定的DLL。
用ProcessExplorer查看MyDll.dll注入notepad.exe的效果如圖5-1所示。在MyDll.dll的所在路徑下,會出現(xiàn)下載的index.html頁面文件。
圖5-1MyDll.dll注入notepad.exe的效果
5.3.2修改注冊表
使用注冊表注入DLL的原理是,當(dāng)User32.dll被裝載到進(jìn)程中時(shí),會自動讀取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Windows下的AppInit_DLLs注冊表項(xiàng),如果該表項(xiàng)保存的是一個(gè)DLL的完整路徑,那么進(jìn)程會調(diào)用LoadLibrary()API裝載該項(xiàng)DLL。
5.3.3消息鉤取
通過消息鉤取機(jī)制,也可以向進(jìn)程注入DLL。在這里,我們需要先了解一下Windows的消息鉤取機(jī)制的原理。
Windows的GUI以事件驅(qū)動的方式工作,鍵盤和鼠標(biāo)的操作大都會引起事件的產(chǎn)生,產(chǎn)生事件時(shí),操作系統(tǒng)會將預(yù)先定義好的消息發(fā)送給相應(yīng)的應(yīng)用程序,應(yīng)用程序收到消息后,根據(jù)消息的內(nèi)容執(zhí)行相應(yīng)的動作?!跋^子”就是在事件消息從操作系統(tǒng)向應(yīng)用程序傳遞的過程中,獲取、查看、修改和攔截這些消息的機(jī)制。
應(yīng)用程序可以通過調(diào)用SetWindowsHookEx()函數(shù)來安裝鉤子過程。鉤子過程可以存在于一個(gè)DLL中。應(yīng)用程序需要裝載該DLL文件,然后調(diào)用SetWindowsHookEx()函數(shù)安裝該鉤子過程,安裝好鉤子過程后,由操作系統(tǒng)將該DLL(含有鉤子過程)強(qiáng)制注入發(fā)生相應(yīng)事件的所有進(jìn)程的地址空間。
TestHook程序的實(shí)現(xiàn)代碼如表5-11所示。從這段代碼我們似乎看不出對SetWindowsHookEx()函數(shù)的調(diào)用。但實(shí)際上,對該函數(shù)的調(diào)用是在HkStart()函數(shù)的內(nèi)部完成的,而HkStart()函數(shù)又是由HookDll.dll提供的一個(gè)導(dǎo)出函數(shù)。同理,在導(dǎo)出函數(shù)HkStop()中,也包含著對鉤子過程的撤銷函數(shù)UnhookWindowsHookEx()的調(diào)用。
在表5-12中,給出了HookDll.dll的源代碼實(shí)現(xiàn)。在這部分源代碼中,就可以看到對SetWindowsHookEx()函數(shù)和UnhookWindowsHookEx()函數(shù)的調(diào)用了。特別地,SetWindowsHookEx()函數(shù)的4個(gè)參數(shù)中,WH_KEYBOARD指明了與鉤子過程對應(yīng)的事件類型,第二個(gè)參數(shù)為指向鉤子過程的指針,第三個(gè)參數(shù)為鉤子過程所在DLL的句柄,第四個(gè)參數(shù)0說明該鉤子過程是一個(gè)全局鉤子過程。
這樣,我們就知道了鉤子過程是被如何安裝及撤銷的。剩下的問題就是鉤子過程內(nèi)部的處理邏輯。分析表5-12中的KeyboardProc()回調(diào)函數(shù)實(shí)現(xiàn)代碼,參數(shù)code的典型取值包括HC_ACTION(wParam和lParam包含按鍵消息)或HC_NOREMOVE(wParam和lParam包含按鍵消息且按鍵消息不能從消息隊(duì)列中移除)。wParam參數(shù)獲得鍵盤按鍵的虛擬鍵值。
lParam參數(shù)的各個(gè)位可以作為狀態(tài)標(biāo)識,用于指定擴(kuò)展鍵、掃描碼、按鍵次數(shù)等信息,其中第31位用于指定轉(zhuǎn)變狀態(tài):該位為0時(shí),按鍵正在被按下;該位為1時(shí),按鍵正在被釋放。KeyboardProc()函數(shù)的邏輯是,如果鍵正在被按下,那么看裝載本DLL的進(jìn)程是否為notepad,如果是,就返回1且不再調(diào)用CallNextHookEx()告知下一鉤子過程;如果不是notepad,則調(diào)用CallNextHookEx(),將消息傳遞給下一鉤子過程。
5.4DLL卸載
DLL卸載的概念是將強(qiáng)制裝入進(jìn)程地址空間的DLL移出。對于通過修改注冊表的方式進(jìn)行的注入,將注冊表鍵值改回默認(rèn)值,即可保證在修改動作執(zhí)行之后啟動的進(jìn)程即使裝載User32.dll,也不會再裝載我們指定的DLL。對于通過消息鉤取實(shí)現(xiàn)的DLL注入,我們也已經(jīng)在上一節(jié)看到了,當(dāng)調(diào)用UnhookWindowsHookEx()函數(shù)之后,操作系統(tǒng)就不再將指定的回調(diào)函數(shù)放入特定事件的鉤鏈中。
然而以上兩種情況都不能說明目標(biāo)地址空間中被裝載的DLL已經(jīng)卸載了。一方面,那些在注冊表鍵值被改回默認(rèn)值之前啟動的進(jìn)程(裝載User32.dll),仍然被注入著DLL。另一方面,調(diào)用UnhookWindowsHookEx()之后,還需要顯式地調(diào)用FreeLibrary()函數(shù)卸載DLL(如表5-11所示)。
因此,DLL卸載只有通過強(qiáng)制目標(biāo)進(jìn)程調(diào)用FreeLibrary()函數(shù)來實(shí)現(xiàn),這是DLL卸載的基本原理。實(shí)現(xiàn)的具體方法,可以如表5-11所示的TestHook代碼那樣調(diào)用,也可以將FreeLibrary()函數(shù)的地址傳給CreateRemoteThread()的lpStartAddress參數(shù)。
表5-13給出了卸載DLL的一個(gè)例子。略去函數(shù)體的FindProcessID()函數(shù)用于查找由參數(shù)指定名稱的進(jìn)程是否存在,如果存在,則返回進(jìn)程ID,如果不存在,則返回0xFFFFFFFF。EjectDll()函數(shù)被調(diào)用時(shí),首先根據(jù)notepad的進(jìn)程ID,調(diào)用CreateToolhelp32Snapshot()獲得notepad所裝載的所有模塊,遍歷這些模塊,逐一比較每個(gè)模塊的名稱或路徑名是否與EjectDll()函數(shù)參數(shù)szDllName所指定的模塊名(實(shí)際上是MyDll.dll)相同。
如果相同,則說明找到了要被卸載的DLL,這時(shí)調(diào)用CreateRemoteThread()函數(shù)在notepad進(jìn)程中創(chuàng)建遠(yuǎn)程線程,該線程調(diào)用FreeLibrary()函數(shù),傳入的參數(shù)me.modBaseAddr是這個(gè)要被卸載的DLL在notepad進(jìn)程地址空間中的基址。
5.5通過修改PE裝載DLL
我們首先構(gòu)造一個(gè)用于注入的DLL文件(MyDll3.dll),該DLL的源代碼可通過修改第5.1.4節(jié)MyDll.dll的源代碼獲得,見表5-14。該源代碼中加入了一個(gè)導(dǎo)出函數(shù)dummy(),該函數(shù)內(nèi)部沒有任何功能,添加這個(gè)導(dǎo)出函數(shù)的目的,是讓MyDll3.dll能夠順利地添加到PE文件的導(dǎo)入表(由PE頭的DataDirectory[1]指向的IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)體數(shù)組)中。
在PE文件中導(dǎo)入DLL的目的,本質(zhì)上是在PE文件代碼中調(diào)用該DLL提供的導(dǎo)出函數(shù),因此,DLL就必須提供至少1個(gè)導(dǎo)出函數(shù),以使得DLL保持完整性,故需要加入dummy()這一導(dǎo)出函數(shù)。將我們指定的DLL加入到PE文件的導(dǎo)入表中,則PE文件運(yùn)行時(shí)就會自動裝載該DLL文件。
假定我們想通過更改notepad.exe來注入MyDll3.dll,則需要向notepad的PE文件導(dǎo)入表中加入一個(gè)IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)。我們先通過PEview看一下notepad當(dāng)前的導(dǎo)入表地址,如圖5-2所示。目前導(dǎo)入表所在的范圍是RVA=7604H~76CBH,對應(yīng)的RAW偏移量范圍為6A04H~6ACBH,共計(jì)200字節(jié),其內(nèi)容如圖5-3所示。每一個(gè)IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)長度為20個(gè)字節(jié),共9個(gè)有效IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)(最后一個(gè)為空IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu))。
圖5-2
notepad.exe原有的導(dǎo)入表信息圖5-3
notepad.exe導(dǎo)入表的十六進(jìn)制內(nèi)容
從圖5-3可以看出,想簡單地向當(dāng)前導(dǎo)入表的后面加入一個(gè)IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)是很難實(shí)現(xiàn)的,因?yàn)槟壳暗膶?dǎo)入表后面是有數(shù)據(jù)的,覆蓋這些數(shù)據(jù)可能導(dǎo)致PE文件不合法。因此,首先需要將導(dǎo)入表移動到一塊更大的空白區(qū)域中,然后再向其末尾加入一個(gè)IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)。這些空白區(qū)域通常會位于節(jié)區(qū)或文件的末尾。因?yàn)槲覀冃枰砑右粋€(gè)IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)到導(dǎo)入表中,因此需要的空間會是200+20=220字節(jié)。
在第4章的表4-12,可以查到notepad.exe的?.rsrc節(jié)區(qū)在外存和內(nèi)存中的長度分別為8000H和7F20H,長度之差E0H大于220字節(jié),因此?.rsrc節(jié)區(qū)的最后E0H個(gè)字節(jié)空間能夠容納我們的導(dǎo)入表。這段空間在notepad.exe的?.rsrc節(jié)區(qū)中的起始RAW=8400H+7F20H=10320H,這段空間的RAW范圍即10320H~103FCH。將RAW范圍6A04H~6ACBH的內(nèi)容先復(fù)制到這里,如圖5-4所示。由于.rsrc節(jié)區(qū)的起始RVA地址為B000H,因此需更改DataDirectory[1]的內(nèi)容,使其指向RVA=B000H+7F20H=12F20H。修改后用PEview分析的結(jié)果如圖5-5所示。
(a)移動前
圖5-4導(dǎo)入表移動到RAW=10320H的目標(biāo)位置
(b)移動后
圖5-4導(dǎo)入表移動到RAW=10320H的目標(biāo)位置圖5-5導(dǎo)入表移動后的PEview分析結(jié)果
這時(shí),我們需要構(gòu)造MyDll3.dll對應(yīng)的IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)的數(shù)據(jù),如下:
我們首先需要在PE文件中找到空白區(qū)域構(gòu)造INT、IAT并存放字符串“MyDll3.dll”,然后分別將IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)的OriginalFirstThunk、FirstThunk和Name字段指向它們。如何尋找足夠的空白區(qū)域?再看到.text節(jié)區(qū)的末尾,文件中存在7800H–7748H=B8H長的空白區(qū)域可以用來構(gòu)造INT、IAT并存儲字符串“MyDll3.dll”。這段區(qū)域由PEview分析如圖5-6所示。
圖5-6
PEview分析的用于存儲IAT、INT和“MyDll3.dll”字符串的空白區(qū)域
由于MyDll3.dll只有一個(gè)導(dǎo)出函數(shù)dummy(),因此INT和IAT中有效的IMAGE_
THUNK_DATA32結(jié)構(gòu)只有一個(gè)(第二個(gè)結(jié)構(gòu)為空結(jié)構(gòu),代表INT和IAT結(jié)束),該結(jié)構(gòu)的內(nèi)容作為指針指向一個(gè)IMAGE_IMPORT_BY_NAME結(jié)構(gòu),該結(jié)構(gòu)的內(nèi)容為
將“MyDll3.dll”字符串放在RAW=7B60H起始的位置(對應(yīng)RVA=8760H);將IMAGE_IMPORT_BY_NAME的內(nèi)容放在RAW=7B80H起始的位置(對應(yīng)RVA=8780H);將INT的IMAGE_THUNK_DATA32結(jié)構(gòu)列表放在RAW=7B50H起始的位置(對應(yīng)RVA=8750H),將IAT的IMAGE_THUNK_DATA32結(jié)構(gòu)列表放在RAW=7B70H起始的位置(對應(yīng)RVA=8770H),INT和IAT的第一個(gè)4字節(jié)均存放8780H,如圖5-7所示。
圖5-7對“MyDll3.dll”字符串、INT、IAT的構(gòu)建
而INT和IAT的起始RVA地址(對INT為8750H,對IAT為8770H),分別就是上述IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)的OriginalFirstThunk字段和FirstThunk字段的內(nèi)容?!癕yDll3.dll”字符串的起始RVA地址8760H,則為上述IMAGE_IMPORT_DESCRIPTOR結(jié)構(gòu)的Name字段的內(nèi)容。對IMAGE_IMPORT_DESCRIPTOR內(nèi)容的添加如圖5-8所示。
圖5-8添加IMAGE_IMPORT_DESCRIPTOR內(nèi)容
注意,最后對IMAGE_OPTIONAL_HEADER導(dǎo)出表長度,從原來的C8H改為DCH。修改完的PE文件用PEview觀察其導(dǎo)出表的效果如圖5-9所示。
圖5-9導(dǎo)出表修改完成后用PEview分析的效果
將PE文件裝載到內(nèi)存時(shí),PE裝載器會修改IAT,因此保存IAT的節(jié)區(qū)(.text)應(yīng)具有寫(WRITE)權(quán)限。而使用PEview查詢?.text節(jié)區(qū)頭的權(quán)限可知,.text節(jié)區(qū)本身并不包含寫權(quán)限(Characteristic值為60000020H),因此需要向該值加上寫權(quán)限值80000000H,得到新的權(quán)限值E0000020H。向RAW=1FCH的位置寫入新的權(quán)限值。
這時(shí),運(yùn)行notepad程序是否已經(jīng)能夠幫助我們執(zhí)行頁面下載工作了呢?實(shí)際運(yùn)行效果是否定的。原因在于,PE文件的綁定導(dǎo)入表(BOUNDIMPORTTable)沒有正確設(shè)置。實(shí)際上,將該表項(xiàng)的內(nèi)容清空即可,因?yàn)檫@一項(xiàng)并不是PE文件所必需的。刪除綁定導(dǎo)入表前后PE文件的差異如圖5-10(a)和圖5-10(b)所示。至此,PE文件已經(jīng)修改完成,運(yùn)行notepad.exe即可實(shí)現(xiàn)頁面的下載。
(a)清除前
圖5-10清除綁定導(dǎo)入表
(b)清除后
圖5-10清除綁定導(dǎo)入表
5.6代碼注入
通過前面學(xué)習(xí)可知,調(diào)用CreateRemoteThread()函數(shù)能夠迫使目標(biāo)進(jìn)程調(diào)用LoadLibrary()或FreeLibrary()以裝載和卸載DLL。實(shí)際上,CreateRemoteThread()函數(shù)能夠更一般化地向目標(biāo)進(jìn)程插入獨(dú)立運(yùn)行的代碼并使之運(yùn)行,即以遠(yuǎn)程線程的形式運(yùn)行指定的代碼。這一技術(shù)稱為代碼注入,也稱為線程注入。
在代碼注入過程中,代碼以線程函數(shù)的形式插入目標(biāo)進(jìn)程,代碼所使用的數(shù)據(jù)則以線程參數(shù)的形式傳入。這與DLL注入是有明顯差別的。使用DLL注入時(shí),DLL程序代碼所使用的數(shù)據(jù)存在于DLL的數(shù)據(jù)節(jié)區(qū),由于整個(gè)DLL被裝載到目標(biāo)進(jìn)程,因而數(shù)據(jù)和代碼被一同注入。相比而言,使用代碼注入時(shí),代碼所使用的數(shù)據(jù)需要預(yù)先注入并告知被注入代碼??梢姡a注入需要考慮的事項(xiàng)更多更為復(fù)雜,但其優(yōu)點(diǎn)在于占用內(nèi)存少且難以被檢測,因此在要被注入的代碼量較小時(shí)經(jīng)常被采用,也在惡意代碼中大量被使用。
下面看一個(gè)代碼注入的實(shí)際例子,見表5-15。
表5-15中程序通過InjectCode()函數(shù),將ThreadProc()函數(shù)注入目標(biāo)進(jìn)程中執(zhí)行,目標(biāo)進(jìn)程的名稱為notepad.exe。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《初中作文結(jié)構(gòu)篇圖》課件
- 《標(biāo)準(zhǔn)作業(yè)SOP》課件
- 《營銷策劃策劃書》課件
- 2024年標(biāo)準(zhǔn)建筑工程合作合同范本版B版
- 2025工地施工合同模板
- 2024年標(biāo)準(zhǔn)化辣椒買賣合同模板一
- 2024年書畫衍生品開發(fā)合作協(xié)議及買賣合同3篇
- 食品行業(yè)產(chǎn)品質(zhì)量保密協(xié)議
- 公路交通信號燈維護(hù)合同模板
- 研發(fā)項(xiàng)目延期還款協(xié)議
- 高中物理教科版高中選修-磁場心形電磁場習(xí)題
- 華醫(yī)網(wǎng)繼續(xù)教育公共課必修選修課抗菌藥物臨床應(yīng)用指導(dǎo)原則考試或補(bǔ)考題庫及答案word檢索版
- 國內(nèi)CAR-T研發(fā)公司及進(jìn)展一覽CAR
- 靜脈輸血技術(shù)
- 《商務(wù)溝通與談判》
- 小學(xué)數(shù)學(xué)六年級數(shù)學(xué)難題(含詳細(xì))
- 2023版中國近現(xiàn)代史綱要課件第一專題歷史是最好的教科書PPT
- 耳尖放血課件完整版
- 漂流項(xiàng)目設(shè)計(jì)書
- 《酒泉市中心城區(qū)高鐵片區(qū)控制性詳細(xì)規(guī)劃》B-2-19地塊用地調(diào)整論證報(bào)告
- 烹飪學(xué) 講義教案
評論
0/150
提交評論