各种杀软、安全卫士等都有一个功能,在任务管理器中右键结束进程时“拒绝访问”,保护进程不被从任务管理器中结束。这里我们使用SSDT hook实现这个功能。
SSDT是System Services Descriptor Table的缩写,即系统服务描述符表。“这个表就是把 RING 3的 Win32 API 和 RING 0的内核 API 联系起来。”
我们知道ntdll.dll是Windows系统从RING 3到RING 0的门户,位于kernel32.dll和user32.dll中的所有Win32 API 最终都是调用ntdll.dll中的函数实现的,而ntdll.dll 中的函数都只不过是一个简单的包装函数,它在进行完参数检查后,通过SYSENTER进入RING 0。
过程中,会将所要调用的服务号(也就是在SSDT 数组中的索引值)存放到EAX中,将参数地址放到EDX中,参数复制到内核地址空间中。
接着执行系统服务分发函数 KiSystemService,这个函数根据EAX寄存器中的索引值,在SSDT中找到索引值为EAX寄存器值的SSDT项,最后就是根据这个SSDT项中所存放的系统服务例程的地址来调用这个系统服务了。
以上是系统调用使用SSDT的一般过程。
SSDT hook原理也很简单,就是把SSDT表中的系统服务例程地址替换成我们的地址,并在hook结束时进行还原。
任务管理器中结束进程是通过TerminateProcess函数实现,下面我们hook这个函数,实现进程保护功能,为了描述简洁,没有实现驱动的unload函数,未恢复hook。
#include "ntddk.h" typedef struct _KSYSTEM_SERVICE_TABLE { PULONG ServiceTableBase; PULONG ServiceCounterTableBase; ULONG NumberOfService; ULONG ParamTableBase; } KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE; typedef struct _KSERVICE_TABLE_DESCRIPTOR { KSYSTEM_SERVICE_TABLE ntoskrnl; KSYSTEM_SERVICE_TABLE win32k; KSYSTEM_SERVICE_TABLE notUsed1; KSYSTEM_SERVICE_TABLE notUsed2; } KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR; extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable; #define SYSCALL_INDEX(ServiceFunction) (*(PULONG)((PUCHAR)ServiceFunction + 1)) #define SYSCALL_FUNCTION(ServiceFunction) KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[SYSCALL_INDEX(ServiceFunction)] NTSTATUS HookNtTerminateProcess() { return STATUS_ACCESS_DENIED; } VOID DisableWriteProtect(ULONG oldAttr) { _asm { mov eax, oldAttr; mov cr0, eax; sti; } } VOID EnableWriteProtect(PULONG pOldAttr) { ULONG uAttr; _asm { cli; mov eax, cr0; mov uAttr, eax; and eax, 0FFFEFFFFh; mov cr0, eax; }; *pOldAttr = uAttr; } NTSTATUS InstallSysServiceHook(ULONG oldService, ULONG newService) { ULONG uOldAttr = 0; EnableWriteProtect(&uOldAttr); SYSCALL_FUNCTION(oldService) = newService; DisableWriteProtect(uOldAttr); return STATUS_SUCCESS; } NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) { InstallSysServiceHook((ULONG)ZwTerminateProcess, (ULONG)HookNtTerminateProcess); return STATUS_SUCCESS; }
程序执行效果:
原文:http://my.oschina.net/cve2015/blog/510818