zoukankan      html  css  js  c++  java
  • Rootkit之SSDT hook(通过CR0)

    SSDT即System Service Dispath Table,它是一个表,这个表中有内核调用的函数地址。
    KeServiceDescriptorTable:是由内核(Ntoskrnl.exe)导出的一个表,这个表是访问SSDT的关键,具体结构是
    typedef struct ServiceDescriptorTable {
    PVOID ServiceTableBase;
    PVOID ServiceCounterTable(0);
    unsigned int NumberOfServices;
    PVOID ParamTableBase;
    }

    其中,
    ServiceTableBase System Service Dispatch Table 的基地址。
    NumberOfServices 由 ServiceTableBase 描述的服务的数目。
    ServiceCounterTable 此域用于操作系统的 checked builds,包含着 SSDT 中每个服务被调用次数的计数器。这个计数器由 INT 2Eh 处理程序 (KiSystemService)更新。
    ParamTableBase 包含每个系统服务参数字节数表的基地址。

    CR0当中有一个写保护位,是保护内存不可写属性的,为了能够写入内核,只能把它的保护给咔嚓掉了,不过……如果做完了手脚但不还原写保护属性的话,极有可能会BOSD.

    代码实例如下:

    #include <NTDDK.h>

    #pragma pack(1)
    typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase; //Used only in checked build
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
    } ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
    #pragma pack()

    _declspec(dllimport) ServiceDescriptorTableEntry 

    KeServiceDescriptorTable;

    NTSYSAPI NTSTATUS ZwOpenProcess(OUT PHANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PCLIENT_ID ClientId);

    typedef NTSTATUS (*ZWOPENPROCESS)(OUT PHANDLE ProcessHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN PCLIENT_ID ClientId);

    #define SYSTEMSERVICE(_function) 

    KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function + 1)]

    ZWOPENPROCESS OldZwOpenProcess;

    NTSTATUS MyZwOpenProcess(PHANDLE ProcessHandle,
    ACCESS_MASK DesiredAccess,
    POBJECT_ATTRIBUTES ObjectAttributes,
    PCLIENT_ID ClientId)
    {
    NTSTATUS ntStatus = STATUS_SUCCESS;

    KdPrint(("MyZwOpenProcess "));

    //调用原来的NtOpenProcess;
    ntStatus = OldZwOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

    return ntStatus;
    }

    VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
    {
    __asm{//去掉内存保护
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
    }

    (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = OldZwOpenProcess;//恢复HOOK SSDT

    __asm{//恢复内存保护 
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
    }

    KdPrint(("驱动卸载完毕! "));
    }

    NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING pRegistryPath)
    {
    NTSTATUS status = STATUS_SUCCESS;
    KdPrint(("The driver begin loading. "));
    DriverObject->DriverUnload = DriverUnload;
    OldZwOpenProcess = (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess);

    __asm{//去掉内存保护
    cli
    mov  eax,cr0
    and  eax,not 10000h
    mov  cr0,eax
    }

    (ZWOPENPROCESS)SYSTEMSERVICE(ZwOpenProcess) = MyZwOpenProcess;    

    //HOOK SSDT

    __asm{//恢复内存保护 
    mov  eax,cr0
    or   eax,10000h
    mov  cr0,eax
    sti
    }
    KdPrint(("The driver ends loading "));
    return status;
    }
  • 相关阅读:
    Docker-compose编排微服务顺序启动解决方案
    在笔记本上使用virtualbox搭建lvs dr 实验遇到的问题
    MongoDB安装配置(RedHat/CentOS)
    wget 用法
    Ubuntu查看crontab运行日志
    CentOS-6.5安装Zabbix 3.0.4
    centos 6 安装vsftpd与PAM虚拟用户
    python socket常用接口说明
    cmake 构建工程
    std::vector的下标访问和迭代器访问的效率
  • 原文地址:https://www.cnblogs.com/vcerror/p/4289219.html
Copyright © 2011-2022 走看看