日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健)

發布時間:2025/6/17 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SHADOW?SSDT?HOOK

????HOOK?和?UNHOOK?SHADOW?SSDT?跟之前的?HOOK/UNHOOK?SSDT?類似,區別是查找SSSDT的特征碼,以及根據索引計算函數地址的公式,還有一個就是吧跳轉函數寫在什么位置,SSDT的時候是寫在藍屏函數里了。

一、獲得?w?KeServiceDescriptorTableShadow的地址

????這個跟獲得?KeServiceDescriptorTable?差不多,唯一不同就是特征碼:

?

ULONGLONG GetKeServiceDescriptorTableShadow64() { PUCHAR StartSearchAddress = (PUCHAR)__readmsr(0xC0000082);PUCHAR EndSearchAddress = StartSearchAddress + 0x500; PUCHAR i = NULL; UCHAR b1=0,b2=0,b3=0; ULONG templong=0; ULONGLONG addr=0; for(i=StartSearchAddress;i<EndSearchAddress;i++) { if( MmIsAddressValid(i) && MmIsAddressValid(i+1) && MmIsAddressValid(i+2) ) { b1=*i; b2=*(i+1); b3=*(i+2); if( b1==0x4c && b2==0x8d && b3==0x1d ) //4c8d1d { memcpy(&templong,i+3,4); addr = (ULONGLONG)templong + (ULONGLONG)i + 7; return addr; } } } return 0; }

?

?

?

二、根據?X?INDEX??獲得?T?SSSDT??函數在內核里的地址

????原理跟獲得?SSDT?函數在在內核里的地址差不多,先獲得?W32pServiceTable的地址,然后再獲得每個函數的偏移地址,在把偏移地址與?W32pServiceTable相加。為什么下面的計算公式是?W32pServiceTable?+?4?*?(index-0x1000)呢?其實這只是個理解上的問題。SSDT?函數的起始?INDEX?是?0x0,SSSDT?函數的起始?INDEX?是?0x1000,但函數地址在?W32pServiceTable?是從基址開始記錄

的(假設?W32pServiceTable?的地址是?0xfffff800~80000000,第?0?個函數的地址就記錄在?0xfffff800~80000000,第?1?個函數的地址就記錄在0xfffff800~80000004,第?2?個函數的地址就記錄在?0xfffff800~80000008,以此類推)。

?

ULONGLONG GetSSSDTFuncCurAddr64(ULONG64 Index) { ULONGLONG W32pServiceTable=0, qwTemp=0; LONG dwTemp=0; PSYSTEM_SERVICE_TABLE pWin32k; pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE)); W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase); ul64W32pServiceTable = W32pServiceTable; qwTemp = W32pServiceTable + 4 * (Index-0x1000); //這里是獲得偏移地址的位置,要HOOK的話修改這里即可 dwTemp = *(PLONG)qwTemp; dwTemp = dwTemp >> 4; qwTemp = W32pServiceTable + (LONG64)dwTemp; return qwTemp; }

三、修改SSSDT里的地址

?

? ? 還是跟?SSDT?類似,修改?W32pServiceTable+4*index?地址的?DWORD?值(偏移地址值)。

?

VOID ModifySSSDT(ULONG64 Index, ULONG64 Address) {ULONGLONG W32pServiceTable=0, qwTemp=0;LONG dwTemp=0;PSYSTEM_SERVICE_TABLE pWin32k;KIRQL irql;pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE)); //4*8W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase);qwTemp = W32pServiceTable + 4 * (Index-0x1000);dwTemp = (LONG)(Address - W32pServiceTable);dwTemp = dwTemp << 4; irql=WPOFFx64();*(PLONG)qwTemp = dwTemp;WPONx64(irql); }

?

? ? 第一個代理函數用機器碼寫成,總共就 14 個字節,前 6 字節為 ff 25 00 00 00 00,后 8 字節為第二個代理函數的地址(JMP QWORD PTR)。

?

VOID ModifySSSDT(ULONG64 Index, ULONG64 Address) { ULONGLONG W32pServiceTable=0, qwTemp=0; LONG dwTemp=0; PSYSTEM_SERVICE_TABLE pWin32k; KIRQL irql; pWin32k = (PSYSTEM_SERVICE_TABLE)((ULONG64)KeServiceDescriptorTableShadow + sizeof(SYSTEM_SERVICE_TABLE)); //4*8 W32pServiceTable=(ULONGLONG)(pWin32k->ServiceTableBase); qwTemp = W32pServiceTable + 4 * (Index-0x1000); dwTemp = (LONG)(Address - W32pServiceTable); dwTemp = dwTemp << 4; irql=WPOFFx64(); *(PLONG)qwTemp = dwTemp; WPONx64(irql); }

代理函數地址:

?

?

ULONG64 ProxyNtUserPostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { if( NtUserQueryWindow(hWnd,0)==MyProcessId && PsGetCurrentProcessId()!=(HANDLE)MyProcessId ) { DbgPrint("Do not fuck with me!"); return 0; } else { DbgPrint("OriNtUserPostMessage called!"); return NtUserPostMessage(hWnd,Msg,wParam,lParam); } }

?

注意UnHOOK就是把真正的函數地址給填寫回去

?

VOID UNHOOK_SSSDT() { ModifySSSDT(IndexOfNtUserPostMessage, (ULONG64)NtUserPostMessage); DbgPrint("UNHOOK_SSSDT OK!"); }

?

?

?

執行效果測試
以下是窗口攻擊函數:

?

int main2() { DWORD pid, wpid, i, j; HWND hWnd; gogogo: printf("pid: "); scanf("%ld", &pid); for (i = 100; i<0xffffff; i += 2) { GetWindowThreadProcessId((HWND)i, &wpid); if (wpid == pid && IsWindowVisible((HWND)i) == 1) { hWnd = (HWND)i; for (j = 0; j<0x10000; j++) { PostMessage(hWnd, j, 0, 0); } } } printf("Ok!"); getchar(); getchar(); goto gogogo; return 0; }

通過HOOK PostMessage 來保護自己不被干掉:

?

?

?

? ? 至于Un SSSDT HOOK 是和SSDT思路一樣的,也是自己加載相關內核模塊,得到一些地址,然后在通過驅動通訊,在內核里獲得一些地址,最后計算出來函數的真正地址,然后把原地址填寫回去(這個地方就是繼續hook一遍)就行了。直接把資料相關代碼粘貼過來吧:

?

?

R3的代碼:

?

#include <stdio.h> #include <direct.h> #include <Windows.h> #include "EnumDrv.h" #include "DrvCtrl.h"HANDLE hMyDrv;void PrintAddressByIndex() { LONG64 id=0; ULONG64 addr=0; st: printf("Input index (HEX without \"0x\" like: 1000, input -1 to exit): "); scanf("%llx",&id); if (id<0) return; IoControl(hMyDrv ,CTL_CODE_GEN(0x807), &id, 8, &addr, 8); printf("%llx\n",addr); getchar(); goto st; }DWORD FileLen(char *filename) { WIN32_FIND_DATAA fileInfo={0}; DWORD fileSize=0; HANDLE hFind; hFind = FindFirstFileA(filename ,&fileInfo); if(hFind != INVALID_HANDLE_VALUE) { fileSize = fileInfo.nFileSizeLow; FindClose(hFind); } return fileSize; }CHAR *LoadDllContext(char *filename) { DWORD dwReadWrite, LenOfFile=FileLen(filename); HANDLE hFile = CreateFileA(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (hFile != INVALID_HANDLE_VALUE) { PCHAR buffer=(PCHAR)malloc(LenOfFile); SetFilePointer(hFile, 0, 0, FILE_BEGIN); ReadFile(hFile, buffer, LenOfFile, &dwReadWrite, 0); CloseHandle(hFile); return buffer; } return NULL; }ULONG64 GetWin32kImageBase() { PIMAGE_NT_HEADERS64 pinths64; PIMAGE_DOS_HEADER pdih; char *NtosFileData=NULL; NtosFileData=LoadDllContext("c:\\win32k.dll"); pdih=(PIMAGE_DOS_HEADER)NtosFileData; pinths64=(PIMAGE_NT_HEADERS64)(NtosFileData+pdih->e_lfanew); return pinths64->OptionalHeader.ImageBase; }void GetOriAddress() { ULONG64 W32pServiceTable, Win32kBase, Win32kImageBase, Win32kInProcess=0, retv; IoControl(hMyDrv ,CTL_CODE_GEN(0x806), NULL, 0, &W32pServiceTable, 8); Win32kBase = GetWin32kBase(); CopyFileA("c:\\windows\\system32\\win32k.sys","c:\\win32k.dll",0); Win32kImageBase = GetWin32kImageBase(); printf("W32pServiceTable: %llx\n", W32pServiceTable); printf("WIN32K.SYS base: %llx\n", Win32kBase); printf("WIN32K.SYS image base: %llx\n\n\n", Win32kImageBase); ULONG index=0; if ( Win32kInProcess==0 ) Win32kInProcess = (ULONGLONG)LoadLibraryExA("c:\\win32k.dll",0, DONT_RESOLVE_DLL_REFERENCES); for(index=0;index<825;index++) //825是WIN7X64上SSSDT的函數個數 { ULONGLONG RVA=W32pServiceTable-Win32kBase; ULONGLONG temp=*(PULONGLONG)(Win32kInProcess+RVA+8*(ULONGLONG)index); ULONGLONG RVA_index=temp-Win32kImageBase; retv = RVA_index+Win32kBase; printf("Shadow SSDT Function[%ld]: %llx\n",index,retv); if(index % 100 ==0) { printf("Press any key to continue......\n"); getchar(); } } }int main() { hMyDrv=openDriver(); GetOriAddress(); uninstallDriver(); return 0; }

宋孖健,13

?

總結

以上是生活随笔為你收集整理的Win64 驱动内核编程-22.SHADOW SSDT HOOK(宋孖健)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。