監控應用層通訊_hook_kifastcallentry(系統服務呼叫)
阿新 • • 發佈:2019-02-19
#include"ntddk.h" #pragma pack(1) //寫這個記憶體以一位元組對齊 如果不寫是以4位元組的對齊的 typedef struct ServiceDescriptorEntry {//這個結構就是為了管理這個陣列而來的 核心api所在的陣列 才有這個結構的 這個是ssdt unsigned int *ServiceTableBase;//就是ServiceTable ssdt陣列 unsigned int *ServiceCounterTableBase; //僅適用於checked build版本 無用 unsigned int NumberOfServices;//(ServiceTableBase)陣列中有多少個元素 有多少個項 unsigned char *ParamTableBase;//引數表基址 我們層傳過來的api的引數 佔用多少位元組 多大 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; #pragma pack(1) _declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;//(名字不要寫錯) //匯入ssdt表 ULONG sosuohookdiandizhi(); void yebaohuguanbi(); void yebaohukaiqi(); unsigned int lao_ntopenfile;//老的ntopenfile函式的地址 ULONG dizhi1 = 0;//KiFasetCallEntry彙編程式碼中的 (call ntcreatefile)下一句的地址 ULONG dizhi2 = 0;//KiFasetCallEntry彙編程式碼中要hook的地址 typedef NTSTATUS(*hanshuzhizhen1)( __out PHANDLE FileHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __out PIO_STATUS_BLOCK IoStatusBlock, __in_opt PLARGE_INTEGER AllocationSize, __in ULONG FileAttributes, __in ULONG ShareAccess, __in ULONG CreateDisposition, __in ULONG CreateOptions, __in_bcount_opt(EaLength) PVOID EaBuffer, __in ULONG EaLength ); VOID xiezai1(PDRIVER_OBJECT qudongduixiang) { yebaohuguanbi();//頁保護關閉 KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lao_ntopenfile;//還原ntcreatefile yebaohukaiqi();//頁保護開啟 UCHAR tezhengma[5] = { 0x2b, 0xe1, 0xc1, 0xe9, 0x02 }; yebaohuguanbi();//頁保護關閉 RtlCopyMemory((PVOID)dizhi2, tezhengma, 5);//還原kifastcallentry yebaohukaiqi();//頁保護開啟 KdPrint(("已經執行到驅動解除安裝歷程\n")); } void yebaohuguanbi()//頁保護關閉 { __asm{//去掉記憶體保護 cli mov eax, cr0 and eax, not 10000h mov cr0, eax } } void yebaohukaiqi()//頁保護開啟 { __asm{//恢復記憶體保護 mov eax, cr0 or eax, 10000h mov cr0, eax sti } } void lisaisaide_guolvhanshu(ULONG ServiceTableBase, ULONG NumberOfServices)//李賽賽的過濾函式 注意不要在這裡加 __declspec (naked)這個不是彙編程式碼 注意傳過來的引數是ulong型別 { //KdPrint(("進入到我的的過濾函式來了 歐耶 可以監控應用層傳過來的請求(呼叫nt函式的資訊)\n")); if (ServiceTableBase == (ULONG)KeServiceDescriptorTable.ServiceTableBase) { if (NumberOfServices==190) { KdPrint(("看那些進入KiFasetCallEntry呼叫ntopenkey程序名是%s\n", (char*)PsGetCurrentProcess() + 0x16c)); } } } __declspec (naked) VOID lisaisaide_KiFasetCallEntry()//李賽賽的KiFasetCallEntry { __asm { pushad pushfd push eax push edi call lisaisaide_guolvhanshu //呼叫我們的過濾函式 popfd popad pop eax sub esp,ecx //call lisaisaide_KiFasetCallEntry 替換掉的5個位元組的程式碼 shr ecx,2 jmp eax } } VOID hook_KiFasetCallEntry()//inlinehookKiFasetCallEntry { ULONG pianyi1 = 0; UCHAR tezhengma[5]; pianyi1 = (ULONG)lisaisaide_KiFasetCallEntry - 5 - dizhi2; tezhengma[0] = 0xe8; *(ULONG*)&tezhengma[1] = pianyi1; //KdPrint(("李賽賽的KiFasetCallEntry地址%x 計算出來的 偏移%x\n", (ULONG)lisaisaide_KiFasetCallEntry, pianyi1)); yebaohuguanbi();//頁保護關閉 RtlCopyMemory((PVOID)dizhi2, tezhengma, 5);//inlinehook_KiFasetCallEntry yebaohukaiqi();//頁保護開啟 } NTSTATUS lisaisaide_NtCreateFile( //李賽賽的_NtCreateFile函式 __out PHANDLE FileHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __out PIO_STATUS_BLOCK IoStatusBlock, __in_opt PLARGE_INTEGER AllocationSize, __in ULONG FileAttributes, __in ULONG ShareAccess, __in ULONG CreateDisposition, __in ULONG CreateOptions, __in_bcount_opt(EaLength) PVOID EaBuffer, __in ULONG EaLength ) { __asm { pushad mov eax, [ebp + 0x4] mov dizhi1, eax popad } //KdPrint(("通過核心棧得到地址call ebx下一句的地址%x\n", dizhi1));//得到地址正確 sosuohookdiandizhi();//搜尋hook KiFastCallEntry //yebaohuguanbi();//頁保護關閉 //KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lao_ntopenfile;//還原ntcreatefile //yebaohukaiqi();//頁保護開啟 hook_KiFasetCallEntry(); //開始hook return ((hanshuzhizhen1)lao_ntopenfile)(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength); } ULONG sosuohookdiandizhi()//搜尋hook KiFastCallEntry { UCHAR *p = (UCHAR *)dizhi1; for (ULONG i = 0; i < 300;i++) { if (*p==0x2b&&*(p+1)==0xe1&&*(p+2)==0xc1&&*(p+3)==0xe9&&*(p+4)==0x02) { //KdPrint(("找到地址kifastcallentry的hook點地址 %x\n",(ULONG)p)); dizhi2 = (ULONG)p; return (ULONG)p; } p--; } //KdPrint(("沒有找到hook點的地址%x 是錯誤的", (ULONG)p)); return 0; } NTSTATUS DriverEntry(PDRIVER_OBJECT qudongduixiang,PUNICODE_STRING zhucebiao) { lao_ntopenfile = KeServiceDescriptorTable.ServiceTableBase[66];//儲存老的ntopenfile函式地址 yebaohuguanbi();//頁保護關閉 KeServiceDescriptorTable.ServiceTableBase[66] = (unsigned int)lisaisaide_NtCreateFile;//ssdthook_ntopenfile 屬於ssdthook yebaohukaiqi();//頁保護開啟 qudongduixiang->DriverUnload = xiezai1; return STATUS_SUCCESS; }