SSDT hook实现进程保护

各种杀软、安全卫士等都有一个功能,在任务管理器中右键结束进程时“拒绝访问”,保护进程不被从任务管理器中结束。这里我们使用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;
}

程序执行效果:

SSDT hook实现进程保护

此时已经无法通过任务管理器关闭cmd.exe程序。

你可能感兴趣的:(SSDT hook实现进程保护)