日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

简单实现了下SSDT SHADOW HOOK

發(fā)布時(shí)間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单实现了下SSDT SHADOW HOOK 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹:
?? ? ? ?SSDT SHADOW HOOK可用于安全軟件窗口保護(hù)、安全輸入、截屏保護(hù)等。例如:掛鉤NtUserFindWindowEx、NtUserGetForegroundWindow、NtUserBuildHwndList、NtUserQueryWindow、NtUserWindowFromPoint、NtUserSetParent、NtUserPostMessage、NtUserMessageCall、NtUserSetWindowLong、NtUserShowWindow、NtUserDestroyWindow、NtUserCallHwndParamLock用于窗口保護(hù),掛鉤了NtUserSendInput、NtUserGetAsyncKeyState、NtUserOpenDesktop、NtUserTranslateMessage用于安全輸入,掛鉤NtGdiBitBlt、NtGdiStretchBlt用于截屏保護(hù)。
?

??窗口保護(hù)

惡意程序通過(guò)獲取安全軟件的窗口句柄,然后通過(guò)關(guān)閉、隱藏、禁用等手段破壞其正常工作,需要掛鉤這些函數(shù)來(lái)防止惡意程序的破壞。R3和R0函數(shù)對(duì)應(yīng)關(guān)系如表1所示。

表1?????????R3-R0函數(shù)對(duì)于關(guān)系

R3

R0

作用

FindWindow

NtUserFindWindowEx

查找窗口獲取句柄

GetForegroundWindow

NtUserGetForegroundWindow

得到當(dāng)前頂層窗口

EnumWindows

NtUserBuildHwndList

枚舉所有頂層窗口

GetWindowThreadProcessId

NtUserQueryWindow

獲取句柄對(duì)應(yīng)的進(jìn)程PID

WindowFromPoint

NtUserWindowFromPoint

獲取所在位置的窗口句柄

SetParent

NtUserSetParent

改變某個(gè)子窗口的父窗

PostMessage

NtUserPostMessage

發(fā)送消息

SendMessage

NtUserMessageCall

發(fā)送消息

SetWindowLong

NtUserSetWindowLong

改變窗口屬性

ShowWindow

NtUserShowWindow

改變窗口顯示狀態(tài)

DestroyWindow

NtUserDestroyWindow

銷(xiāo)毀窗口

EnableWindow

NtUserCallHwndParamLock

禁用、啟用窗口

?

??安全輸入

掛鉤NtUserSendInput、NtUserGetAsyncKeyState、NtUserOpenDesktop、NtUserTranslateMessage分別用于防止模擬按鍵、獲取鍵盤(pán)按鍵狀態(tài)、打開(kāi)安全桌面、將虛假按鍵還原成真實(shí)的按鍵。

?

a)??????NtUserSendInput

惡意程序可以通過(guò)調(diào)用SendInput來(lái)模擬按鍵干擾正常輸入,可以?huà)煦^NtUserSendInput防止惡意操作。當(dāng)用戶(hù)正在輸入密碼等隱私信息的時(shí)候,禁止其他程序調(diào)用SendInput模擬鍵盤(pán)和鼠標(biāo)操作。

b)??????NtUserGetAsyncKeyState

惡意程序可能不停的調(diào)用NtUserGetAsyncKeyState來(lái)獲取鍵盤(pán)的按鍵狀態(tài)從而記錄鍵盤(pán)的輸入信息,可以?huà)煦^NtUserGetAsyncKeyState用來(lái)禁止此類(lèi)鍵盤(pán)記錄行為。當(dāng)用戶(hù)正在輸入密碼等隱私信息的時(shí)候,禁止其他程序調(diào)用NtUserGetAsyncKeyState,但是不會(huì)阻止當(dāng)前受保護(hù)的進(jìn)程調(diào)用(否則會(huì)影響正常的密碼輸入行為)。

c)??????NtUserOpenDesktop

在Windows操作系統(tǒng)中,消息鉤子(通過(guò)SetWindowsHookEx設(shè)置)只會(huì)當(dāng)前的桌面上的窗口有效,所以,可以建立一個(gè)安全桌面,用于運(yùn)行需要嚴(yán)密保護(hù)的進(jìn)程,這樣,非本桌面上運(yùn)行的程序無(wú)法通過(guò)消息鉤子的方式來(lái)獲取需要保護(hù)進(jìn)程窗口的信息,達(dá)到了保護(hù)目標(biāo)進(jìn)程窗口的目的(360保險(xiǎn)箱和金山密保都有一個(gè)叫安全桌面的功能,正是這樣實(shí)現(xiàn)的)。

首先調(diào)用真實(shí)的NtUserOpenDesktop函數(shù),然后獲取返回句柄的桌面名字,如果此桌面名字跟創(chuàng)建的安全桌面名字一樣,則關(guān)閉此桌面句柄,并返回一個(gè)NULL值,否則返回真實(shí)的句柄。達(dá)到保護(hù)安全桌面的目的,真正做到安全桌面不可滲透。

d)??????NtUserTranslateMessage

在輸入密碼的時(shí)候,用戶(hù)程序一般調(diào)用TranslateMessage將消息轉(zhuǎn)化為具體的按鍵信息,利用此特點(diǎn),可以構(gòu)建一個(gè)DirectInput安全輸入通道,即盡可能少的通過(guò)Windows系統(tǒng)的鍵盤(pán)按鍵傳輸通道(此通道是極度危險(xiǎn)的,惡意程序可以在任意位置添加HOOK截獲按鍵信息)。

對(duì)NtUserTranslateMessage的掛鉤用于修正虛擬鍵盤(pán)輸入的虛擬按鍵,首先需要判斷是否正在輸入密碼,虛擬鍵盤(pán)是否正在運(yùn)行,是否需要修正按鍵,這三個(gè)參數(shù)都是運(yùn)行于R3的控制程序傳遞進(jìn)來(lái)給R0驅(qū)動(dòng)的。然后判斷消息是否是鍵盤(pán)按鍵的消息,如果是,則進(jìn)一步判斷此消息是否對(duì)應(yīng)虛假按鍵,如果是,則修正為真實(shí)的按鍵。虛假的按鍵和真實(shí)的按鍵也是R3傳遞給R0驅(qū)動(dòng)的。整個(gè)輸入通道完全自己構(gòu)建,不通過(guò)Windows系統(tǒng)提供的任何通道,所有的類(lèi)型的HOOK都無(wú)法在此期間截獲虛擬鍵盤(pán)輸入的密碼(很多安全軟件提供的虛擬鍵盤(pán)的思路大致如此吧,沒(méi)有去仔細(xì)調(diào)研)。

???截屏保護(hù)

很多截屏類(lèi)的鍵盤(pán)記錄程序。當(dāng)用戶(hù)在虛擬鍵盤(pán)上按下一個(gè)鍵時(shí),惡意程序就截一次屏幕,這樣可以清楚地看到用戶(hù)輸入的密碼信息。掛鉤兩個(gè)函數(shù)NtGdiBitBlt、NtGdiStretchBlt可以用于防截屏。

卡巴斯基反病毒軟件率先推出截屏保護(hù),即當(dāng)虛擬鍵盤(pán)運(yùn)行的時(shí)候,阻止程序進(jìn)行截屏操作,在一定程度上可以阻止此類(lèi)鍵盤(pán)記錄工具的工作。但是卡巴斯基有一個(gè)很大的缺陷,它只能阻止全屏的截圖,不能阻止部分屏幕的截圖。



簡(jiǎn)單實(shí)現(xiàn):
首先定位到SSDT SHADOW的地址
使用的硬編碼,根據(jù)相同版本下與SSDT地址存在的偏移獲取的SSDT SHADOW的地址
windbg下
kd> ?KeServiceDescriptorTable-KeServiceDescriptorTableShadow
Evaluate expression: 64 = 00000040
我只裝了XP的虛擬機(jī)

[cpp]?view plaincopy

  • switch?(dwVersion)??
  • ????{??
  • ????case?VERSION_2K:??
  • ????????KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0xE0;??
  • ????????break;??
  • ????case?VERSION_2K3:?????
  • ????????break;??
  • ????case?VERSION_XP:??
  • ????????KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable-0x40;??
  • ????????break;??
  • ????case?VERSION_VISTA:??
  • ????????break;??
  • ????case?VERSION_WIN7:??
  • ????????break;??
  • ????}??

  • 方法其實(shí)好多,參考http://bbs.pediy.com/showthread.php?t=56955
    然后就是HOOK了

    [cpp]?view plaincopy

  • typedef?BOOL?(__stdcall?*PNtUserDestroyWindow)(HWND?hwnd);??
  • //定義原來(lái)和當(dāng)前的函數(shù)地址??
  • PNtUserDestroyWindow?Old_NtUserDestroyWindow,Cur_NtUserDestroyWindow;??
  • ??
  • BOOL?__stdcall?MyNtUserDestroyWindow(HWND?hwnd)??
  • {???
  • ????if?(hwnd==hProctecHwnd)???
  • ????{??
  • ????????KdPrint(("被保護(hù)窗口hwnd=%d?\n",hwnd));??
  • ????????return?FALSE;//如果是被保護(hù)窗口的句柄直接返回錯(cuò)誤??
  • ????}??
  • ????else??????
  • ????????return?Old_NtUserDestroyWindow(hwnd);//調(diào)用原來(lái)的函數(shù)??
  • }??
  • ??
  • //SSDT?SHADOW?HOOK??
  • VOID?HookNtUserDestroyWindow()??
  • {??
  • ????DWORD?SSDTShadowBaseAddr=GetSSDTShadowAddr()+0x10;//表基址所在地址??
  • ????DWORD?TableCount=SSDTShadowBaseAddr+0x8;//函數(shù)數(shù)量所在地址??
  • ????DWORD?dwCount=*((PDWORD)TableCount);??
  • ????PDWORD?Fun_Addr=(PDWORD)(*((PDWORD)SSDTShadowBaseAddr));??
  • ????PDWORD?NtUserDestroyWindowAddr=Fun_Addr+355;??
  • ????//保存原函數(shù)地址,SSDT?HOOK是根據(jù)ZW函數(shù)地址硬編碼得出的索引得到的函數(shù)地址??
  • ????Old_NtUserDestroyWindow=(PNtUserDestroyWindow)(*NtUserDestroyWindowAddr);??
  • ????KdPrint(("ssdt?shadow?addr:0x%X",SSDTShadowBaseAddr));??
  • ????KdPrint(("數(shù)量是:%d",dwCount));??
  • ????KdPrint(("原函數(shù)地址:%X\n",*NtUserDestroyWindowAddr));??
  • ????KdPrint(("新函數(shù)地址:%X\n",MyNtUserDestroyWindow));??
  • ????__asm?//去掉頁(yè)面保護(hù)??
  • ????{??
  • ????????cli??
  • ????????????mov?eax,cr0??
  • ????????????and?eax,not?10000h?//and?eax,0FFFEFFFFh??
  • ????????????mov?cr0,eax??
  • ??
  • ????}??
  • ??
  • ????*NtUserDestroyWindowAddr=MyNtUserDestroyWindow;?????//指向HOOK地址??
  • ????__asm???
  • ????{???
  • ????????mov??eax,?cr0???
  • ????????or???eax,?10000h???
  • ????????mov??cr0,?eax???
  • ????????sti???
  • ????}???
  • ????KdPrint(("hook?ok"));??
  • }??
  • ??
  • VOID?UNHOOKNtUserDestroyWindow()?//還原HOOK??
  • {???
  • ????DWORD?SSDTShadowBaseAddr=GetSSDTShadowAddr()+0x10;????
  • ????PDWORD?Fun_Addr=(PDWORD)(*((PDWORD)SSDTShadowBaseAddr));??
  • ????PDWORD?NtUserDestroyWindowAddr=Fun_Addr+355;??
  • ??????
  • ????__asm?//去掉頁(yè)面保護(hù)??
  • ????{??
  • ????????cli??
  • ????????????mov?eax,cr0??
  • ????????????and?eax,not?10000h?//and?eax,0FFFEFFFFh??
  • ????????????mov?cr0,eax??
  • ??
  • ????}??
  • ????*NtUserDestroyWindowAddr=Old_NtUserDestroyWindow;??
  • ??
  • ????__asm???
  • ????{???
  • ????????mov??eax,?cr0???
  • ????????????or???eax,?10000h???
  • ????????????mov??cr0,?eax???
  • ????????????sti???
  • ????}???
  • ????KdPrint(("unhook..."));??
  • }??
  • 總結(jié)

    以上是生活随笔為你收集整理的简单实现了下SSDT SHADOW HOOK的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。