2024年3月27日發(作者:固定修復)

鉤子:(Hook)是Windows中提供的一種用以替換DOS下“中斷”的系統機制,中文
譯為“掛鉤”或“鉤子”。
鉤子在軟件中的應用可以說是很廣泛了,想當年學習鉤子那會兒,什么IAT鉤
子,INLINE鉤子......真是有點老牛啃南瓜......
看多了網上的其他一些關于此話題的文章,感覺對于剛接觸的人不適用,所
以今天把經驗與大家分享(高手就不用看了......呵呵.)
WINDOWS HOOK有什么用呢?說的明白點就是給特定的某一個事件,說的具
體點是給一個函數掛上一個鉤子(我們自己的函數),讓它在執行前先執行我們掛的鉤子(我
們掛接的函數),從而達到攔截事件和函數調用等的目的.
IAT鉤子:IAT(Import Address Table)意思是導入地址表,有的朋友看不懂了,!什
么是導入地址表.你可以去下載一個exescope,然后用它打開一個EXE文件看看導入欄,一
個程序在執行時,它所(靜態調用,即不用loadlibrary法)調用的函數,在它被編譯成為一個
可執行文件時,這些模塊的函數的地址就會被寫入導入表,IAT鉤子即是替換IAT表中的這些
地址為自己的函數地址,那么當程序調用到這個地址的時候就會跳到我們的函數里面來,在
這里替換并不是說我們要去替換文件中的IAT表,而是要去替換內存中的IAT表,一個可執行
文件運行之后,它的程序主體會做為一個模塊被加載到內存里,在需要調用函數的時候它會
去IAT表中查詢所調用的函數地址,我們只需修改內存中IAT表地址即可,具體修改方法很簡
單,這里不作介紹,那么怎么樣去修改呢,換句話說,我們怎么知道什么時候去修改?這個時候
就需要用到一個windows系統函數SetWindowsHookEx(方法當然不只這一種,比如用
遠程注入也可以,有興趣可以去網上查詢),這個函數會在運行時負責把我們的DLL文件帶
到與我們所注冊的鉤子有關的所有程序中(注意進程的用戶權限),這就是為什么用戶態的全
局鉤要做成DLL(動態鏈接庫的原因).
比如,我們用SetWindowsHookEx注冊一個鼠標鉤子,并用一個的模塊與
之掛鉤,那么在WINDOWS系統中響應鼠標事件的所有程序會先加載,在加載DLL初
始化時(執行DLLMAIN函數)我們就可以先在內存中找出IAT中的函數地址,再用
WriteProcessMemory或memcpy修改為模塊內的某個函數(我們掛鉤的函數),那
么這個程序在響應鼠標事件時會先執行我們掛好的那個在的某個函數,這個時候大
權就在我們手里了,我們可以讓它繼續執行,也可以讓它立即返回無效.同理我們可以掛鉤所
有響應鍵盤事件的程序加載我們的模塊以達到監視鍵盤記錄的作用,也可以掛鉤所有響應
消息的程序來掛鉤NtopenProcess和NtTerminateProcess來防止我們的程序被其他程
序結束.也可以掛鉤諸多的API函數來監視系統API的調用,不過在這里有個誤
區,SetWindowsHookEx只會負責把你的DLL加載到其他的執行程序(不會執行),所以我們
的替換動作必須在DLLMAIN函數中(或調用)完成.還有一點要注意IAT HOOK修改的只是
IAT表而已,并不是函數本身,而下面這中方法就是直接修改函數本身實現HOOK,同理,
都可以用SetWindowsHookEx注冊一個鉤子把我們的鉤子模塊帶到其他進程。那么它是
怎么實現HOOK的呢?我們需要準備一個5個字節的BYTE(或CHAR)變量,然后把它的
第一個字節設為0xE9(16進制),然后把(我們的函數地址-原函數地址-5)(long類型)寫
入從第2個字節開始后的4個字節,我們都知道LONG類型所占的空間剛好為4個字節(在
這眾多類型里面,不管它的類型怎么變,它都有以字節為單位的大小,在我看來,把一個
變量叫做int 也好 long 也好,純粹是為了編寫程序方便和好記,因為我們完全可以把int
x 定義為 BYTE x[2]),再把這5個字節復制到內存中以原函數(要掛鉤的那個函數)地址
為起始點的5個字節,這么做的意義是什么呢?可能有的人不知道0xE9 相當于匯編里的
Jmp指令,(當然有點反匯編基礎的人都知道如0xC3 = ret, 0xE9=Jmp,、、很多)在匯編里
jmp是一個跳轉指令,在這里就是讓它跳轉至后面的4個字節指示的位置(我們的函數地址),
從而達到HOOK的目的,這就是為什么叫INLINE HOOK為5字節跳轉法,同樣的這種方
法不僅僅適用于用戶態,它還適用于核心態,這就是SDT INLINE HOOK。
在系統內核有一個內核文件的加載的鏡像(內核模塊),NTOSKRNL或ntkrnlpa及
ntkrnlmp、ntkrnlup、ntkrpamp都是OS內核文件,它提供了一整套核心態函數,供用
戶態和核心態調用,我們在用戶態調用的函數大多數在最后都進入了核心態如
的OpenProcess,在調用OpenProcess,以后會進入中的NtOpenProcess然后調
用系統函數調用號進入核心態的NtOpenProcess,所以核心態的鉤子才是王道,核心態的鉤
子有SSDT HOOK和SDT INLINE HOOK,上面說了,內核導出了一系列的函數供用戶態調
用,那么導出的這個函數表就是SSDT(系統服務描述表),它的地址可由內核導出的一個
變量 KeServiceDescriptorTable 查詢,每4個字節(long 大小)為一個地址,在SSDT
HOOK時我們只需要修改SSDT表中的地址為我們的地址即可,相當簡單.
例:修改NtOpenProcess:
*(ULONG*)(KeServiceDescriptorTable+(0x7A*4))=(ULONG)MyOpenProcess
0x7A為NtOpenProcess的系統調用號,每個調用號占4個字節,
KeServiceDescriptorTable+(0x7A*4)就代表了NtOpenProcess地址的存放位
置,MyOpenProcess為我們自定義的函數,這樣系統在執行NtOpenProcess的時候就會
跳到MyOpenProcess里。還有一種就是Inline Hook它和用戶態的一樣直接修改函數前
5個字節即可,這里不再贅述。但是在核心態的inline hook比較危險,這涉及到多線程調
用,有興趣的朋友可以去查閱該方面資料。
已經講了這幾種HOOK 的實現原理,那么我們怎么來預防Hook呢。在用戶
態我們可以掛接(inlinehook)LoadLibraryExW來判斷,這個資料在網上很多,朋友們
可以自己去找,還有一點就是,網上的方法不能防止遠程注入HOOK,在LoadLibrary的
時候加上判斷TED或PEB就可以防止了。
本文發布于:2024-03-27 08:26:32,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/1711499193299120.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:IAT鉤子.doc
本文 PDF 下載地址:IAT鉤子.pdf
| 留言與評論(共有 0 條評論) |