Note
  • Introduction
  • PWN
    • __libc_csu_init函数的通用gadget
    • _int_malloc源码分析
    • _IO_FILE利用思路总结
    • C++ 虚表分析
    • Fast_bin笔记
    • house_of_force
    • House_of_Roman
    • Linux_ShellCode
    • Return-to-dl-resolve原理及利用
    • Unlink利用原理
    • Unsorted_Bin_Attack
    • 获取libc方法
    • 利用main_arena泄露libc基址
    • 整数溢出
    • 重写.fini_array函数指针
    • Windows_SEH利用
  • Windows_Operating_System
    • Dll隐藏
    • Dll注入之远程线程注入
    • IAT_HOOK原理实现
    • Windows下通用ShellCode原理
    • 代码注入
    • inline_hook框架
    • 32位程序调用64位函数原理
    • 调试原理
    • Windows异常处理初探
    • Windows_SEH利用
  • Windows_Kernel
    • MSR_HOOK
    • SSDT_HOOK
  • Virus_Analysis
  • Program
    • Dll的生成与使用
  • Miscellaneous
    • ctf笔记
    • 常见算法特征总结
    • ELF文件笔记
  • Linux_Operating_System
    • 系统调用
    • 分页机制
    • 调试原理
    • linux无文件执行elf
    • egg hunter
    • 缺失的动态链接库
  • Linux_Kernel
    • KERNEL_PWN状态切换原理及KPTI绕过
  • IOT
    • IOT调试环境搭建
    • mips_arm汇编学习
    • Cisco RV160W系列路由器漏洞:从1day分析到0day挖掘
  • Symbolic_Execution
    • angr初探
    • angr_进阶
  • Fuzz
    • UAF_overflow_check
    • intel-pin
  • CVE
    • Cisco RV160W系列路由器漏洞:从1day分析到0day挖掘
  • Assembly
    • Junk_Code_Analysis
    • opcode
  • Andriod_Security
Powered by GitBook
On this page

Was this helpful?

  1. Windows_Kernel

SSDT_HOOK

由 SSDT HOOk 实现的进程保护框架

#include <ntddk.h>
#include<ntstatus.h>

//1.找到系统服务表的函数地址表

//定义一个全局变量用来存放之前的NtOpenProcess地址
ULONG uOldNtOpenProcess;


//有了地址还需要一个函数NtOpenProcess指针,用于调用原来的NtOpenProcess
typedef NTSTATUS(*NTOPENPROCESS)(
    __out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
    );

typedef struct _KSYSTEM_SERVICE_TABLE
{
    PULONG  ServiceTableBase;               // SSDT (System Service Dispatch Table)的基地址 
    PULONG  ServiceCounterTableBase;        // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数
    ULONG   NumberOfService;               // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小  
    PULONG   ParamTableBase;               // SSPT(System Service Parameter Table)的基地址  
} KSYSTEM_SERVICE_TABLE, *PKSYSTEM_SERVICE_TABLE;

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
    KSYSTEM_SERVICE_TABLE   ntoskrnl;                       // ntoskrnl.exe 的服务函数  
    KSYSTEM_SERVICE_TABLE   win32k;                         // win32k.sys 的服务函数(GDI32.dll/User32.dll 的内核支持)  
    KSYSTEM_SERVICE_TABLE   notUsed1;
    KSYSTEM_SERVICE_TABLE   notUsed2;
}KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;


//导出由 ntoskrnl所导出的 SSDT
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//这个是导出的,要到内核文件找,所以名字不能瞎起

//准备用于替换的函数
NTSTATUS NTAPI MyNtOpenProcess(__out PHANDLE  ProcessHandle,
    __in ACCESS_MASK  DesiredAccess,
    __in POBJECT_ATTRIBUTES  ObjectAttributes,
    __in_opt PCLIENT_ID  ClientId
)
{
    NTSTATUS Status;
    Status = STATUS_SUCCESS;
    if (ClientId->UniqueProcess == (HANDLE)916)//指定保护的进程ID
        {
            return STATUS_ABANDONED;
        }
    //打开原来的函数,因为这个函数也要实现原来的功能,不然就乱套了,除非你自己在自己业务里实现了
    return ((NTOPENPROCESS)uOldNtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}

void PageProtectOff() {

    __asm { //关闭内存保护
        push eax;
        mov eax, cr0;
        and eax, ~0x10000;
        mov cr0, eax;
        pop eax;
    }
}

void PageProtectOn() {

    __asm { //恢复内存保护
        push eax;
        mov eax, cr0;
        or eax, 0x10000;
        mov cr0, eax;
        pop eax;
    }
}

//3.修改函数地址,准备个函数用来修改函数地址
void HookNtOpenProcess() {
    NTSTATUS Status;
    Status = STATUS_SUCCESS;
    PageProtectOff();
    uOldNtOpenProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE];
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE] = (ULONG)MyNtOpenProcess;
    PageProtectOn();
}

//4.恢复
void UnHookNtOpenProcess() {
    PageProtectOff();
    KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE] = (ULONG)uOldNtOpenProcess;
    PageProtectOn();
}

VOID DriverUnload(PDRIVER_OBJECT pDriver) {
    UNREFERENCED_PARAMETER(pDriver);
    UnHookNtOpenProcess();

    KdPrint(("My Dirver is unloading..."));

}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pPath) {
    UNREFERENCED_PARAMETER(pPath);
    KdPrint(("->%x \n", KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0xBE]));//得到函数地址表

    HookNtOpenProcess();

    pDriver->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;
}
PreviousMSR_HOOKNextVirus_Analysis

Last updated 5 years ago

Was this helpful?

参见

进程隐藏与进程保护(SSDT Hook 实现)