「Window平臺」異常掛鉤大法

作者?| 榴蓮
編輯?| Racel
Windows操作系統(tǒng)中存在多種異常處理,我們現(xiàn)在需要的是其中的VEH(VectoredExceptionHandler)異常處理,也就是向量化異常處理。我們之所以可以使用VEH異常來進行HOOK的主要原因,在于兩點。其一,VEH異常處理的優(yōu)先級是高于SEH異常處理的,也就是說可以先手拿到異常,確保不會被其他異常處理流程將異常截獲而導致HOOK失敗。其二就是在VEH異常處理的回調函數(shù)中,可以獲取及修改異常發(fā)生處的上下文環(huán)境,這就意味著我們可以操作的東西會非常多,例如通過上下文環(huán)境中的ESP(棧頂指針寄存器)就可以拿到HOOK位置觸發(fā)異常時的堆棧數(shù)據(jù)。而我們設置的HOOK位置通常位于函數(shù)內部的起始位置,這就意味著我們可以直接通過堆棧里的數(shù)據(jù)獲取到被HOOK函數(shù)的參數(shù),并且可以對其進行修改。
首先,我們既然需要HOOK,那么我們大概率需要一個將代碼寫到一個DLL(動態(tài)鏈接庫)中,然后通過注入的方式加載到目標進程的體內。我這里采用的操作系統(tǒng)是Windows 10 20H2(19042.1288),集成開發(fā)環(huán)境采用的是Visual Studio 2017。那么我們先來創(chuàng)建一個DLL項目。


02選擇Windows桌面->動態(tài)鏈接庫(DLL),點擊確定




?05
在每一個case中添加break關鍵字,并且使用AddVectoredExceptionHandler函數(shù)添加一個VEH異常的回調。VEH的回調是一個鏈表,掛著很多的處理程序。AddVectoredExceptionHandler函數(shù)的第一個參數(shù)就是用來指定新增VEH處理函數(shù)位于鏈表的哪個位置。如果第一個參數(shù)的值是0,那么新增的VEH處理函數(shù)將處于整個鏈表的最后。如果第一個參數(shù)的值是一個非0值,那么新增的VEH處理函數(shù)就會位于鏈表的頭部。AddVectoredExceptionHandler函數(shù)的第二個參數(shù)就是指定新增的回調函數(shù)




06
手工在需要HOOK的位置制造異常,觸發(fā)VEH異常處理。我們這里采用軟件斷點的方式觸發(fā)異常。即是在需要HOOK的函數(shù)的第一個字節(jié)處,將其改成硬件嗎0xCC,這樣就會觸發(fā)一個int 3異常。按照異常的接管順序。此時異常將優(yōu)先被VEH異常處理攔截。那么我們此時就可以在VEH異常處理的回調函數(shù)中對其進行HOOK代碼的編寫。

6.1 ?聲明一個用來保存異常地址(HOOK地址)和被替換字節(jié)的結構體,并且聲明對象



?

選擇在VEH異常處理的回調函數(shù)中處理HOOK

也就是說,我們的斷點0xCC實際上就是改在了紅框的位置上,替換了8B,而原本的函數(shù)中,8BFF的硬編碼組成了mov edi,edi,這里實際上別沒有什么用,所以我們如果直接跳過這兩個硬編碼也并不會影響程序的正常執(zhí)行。
?

8.1 生成文件


9.1 首先寫一個目標程序,代碼如下
9.2 使用注入器(自行編寫或網(wǎng)上下載,這里我用的是自己寫的)將我們生成的模塊注入到目標進程中。




到了這里,VEH HOOK就已經完成了