//方式1:MSR Hook #include <ntifs.h> UINT32 oldaddr = 0; UINT32 pidtoprotect = 3792; PCLIENT_ID pid = 0; PUINT32 accessmask = 0; UINT32 ssdtindex = 0; VOID MyKiFastCallEntry(); //#pragma alloc_text(NONE_PAGE,MyKiFastCallEntry) VOID OnHook() { __asm { pushad pushfd mov ecx, 0x176 rdmsr mov oldaddr, eax mov ecx, 0x176 xor edx, edx mov eax, MyKiFastCallEntry wrmsr popfd popad } } VOID OffHook() { __asm { pushad pushfd mov ecx,0x176 xor edx,edx mov eax,oldaddr wrmsr popfd popad } } VOID UnloadMe(PDRIVER_OBJECT pdo) { OffHook(); } __declspec(naked) VOID MyKiFastCallEntry() //原来裸函数内不能使用auto或register变量的 { __asm { mov ssdtindex, eax; } if (ssdtindex == 0xbe) { _asm { push dword ptr[edx + 4 * 5]; pop pid; push edx; add dword ptr[esp], 12; pop accessmask; //这里得注意,这种方式,得到的是accessmask的地址..太阴险了 pushad; } if ((pid->UniqueProcess == pidtoprotect) && (*accessmask&0x0001)) { KdPrint(("I'm Here2!\n")); *accessmask &= ~0x0001; } _asm popad; } __asm { jmp oldaddr; } } NTSTATUS DriverEntry(PDRIVER_OBJECT pdo, PUNICODE_STRING ppath) { OnHook(); pdo->DriverUnload = UnloadMe; return STATUS_SUCCESS; } //不知为何,虽然保护成功了,但是在任务管理器多次结束任务,那么那个进程还是被结束了..
//方式2:SSDT Hook #include <ntifs.h> #pragma pack(1) typedef struct _ServiceDescriptorEntry { ULONG *ServiceTableBase; ULONG *ServiceCounterTableBase; ULONG NumberOfServices; UCHAR *ParamTableBase; }SSDTEntry, *PSSDTEntry; #pragma pack() NTSYSAPI SSDTEntry KeServiceDescriptorTable; VOID OnHook(); VOID OffHook(); VOID OffMemProtect() { __asm { push eax; mov eax, CR0; and eax, ~0x10000; mov CR0, eax; pop eax; } } VOID OnMemProtect() { __asm { push eax; mov eax, CR0; or eax, 0x10000; mov CR0, eax; pop eax; } } VOID UnloadMe(PDRIVER_OBJECT pdo) { OffHook(); } ULONG pidtoprotect = 1796; typedef NTSTATUS(NTAPI *NTOPENPROCESS)(__out PHANDLE ProcessHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes, __in_opt PCLIENT_ID ClientId ); NTOPENPROCESS oldaddr; NTSTATUS MyZwOpenProcess( _Out_ PHANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_opt_ PCLIENT_ID ClientId ); NTSTATUS MyZwOpenProcess( _Out_ PHANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_opt_ PCLIENT_ID ClientId ) { if ((ClientId->UniqueProcess == pidtoprotect) && (DesiredAccess & 0x0001)) { KdPrint(("IM in")); return STATUS_ACCESS_DENIED; } else return oldaddr(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); } VOID OnHook() { DbgBreakPoint(); OffMemProtect(); PULONG pssdtbase = KeServiceDescriptorTable.ServiceTableBase; ULONG uIndex = 0xbe; oldaddr = pssdtbase[uIndex]; pssdtbase[uIndex] = MyZwOpenProcess; OnMemProtect(); } VOID OffHook() { OffMemProtect(); PULONG pssdtbase = KeServiceDescriptorTable.ServiceTableBase; ULONG uIndex = 0xbe; pssdtbase[uIndex] = oldaddr; OnMemProtect(); } NTSTATUS DriverEntry(PDRIVER_OBJECT pdo, PUNICODE_STRING ppath) { OnHook(); pdo->DriverUnload = UnloadMe; return STATUS_SUCCESS; }