Windows驱动开发学习笔记(五)—— SSDT HOOK

  • 系统服务表
  • 系统服务描述符表
  • 实验一:通过代码获取SSDT表地址
  • 通过页表基址修改页属性
    • 方法1:修改页属性
    • 方法2:修改CR0寄存器
  • 实验二:SSDT HOOK
    • 第一步:编译如下代码
    • 第二步:查看PCHunter(未HOOK)
    • 第三步:运行驱动程序
    • 第四步:查看PCHunter(已HOOK)

系统服务表

描述

  1. 全称:SystemServiceTable(系统服务表)
  2. 可以通过系统服务描述符表访问系统服务表

系统服务描述符表

描述

  1. 全称:System Services Descriptor Table(SSDT)
  2. 位于内核文件中,可以通过其导出表找到该表

    在WinDbg中查看

    函数地址表(ServiceTable)

    参数个数表(ArgmentTable)

实验一:通过代码获取SSDT表地址

#include <ntddk.h>
#include <ntstatus.h>typedef struct _KSYSTEM_SERVICE_TABLE
{  PULONG  ServiceTableBase;                                // 服务函数地址表基址  PULONG  ServiceCounterTableBase;                      // SSDT函数被调用的次数ULONG   NumberOfService;                             // 服务函数的个数  PULONG   ParamTableBase;                                // 服务函数参数表基址
} 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;// KeServiceDescriptorTable 是 ntoskrnl.exe 所导出的全局变量 申明一下就可以直接使用了
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{DbgPrint("驱动程序已停止.\r\n");
}//驱动程序入口函数,相当于控制台的main函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{DbgPrint("驱动程序已运行.\r\n");KdPrint(("--> %x \n", KeServiceDescriptorTable->ntoskrnl.ServiceTableBase));//设置一个卸载函数  便于退出DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}


通过页表基址修改页属性

描述:SSDT所在的物理页是只读的,如果要修改,要先修改页属性为可写

方法1:修改页属性

if(RCR4 & 0x00000020)
{//说明是2-9-9-12分页KdPrint(("2-9-9-12分页 %p\n",RCR4));KdPrint(("PTE1 %p\n",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8))));*(DWORD64*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8)) |= 0x02; KdPrint(("PTE1 %p\n",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 9) & 0x007FFFF8))));
}
else
{//说明是10-10-12分页KdPrint(("10-10-12分页\n"));KdPrint(("PTE1 %p\n",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC))));*(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC)) |= 0x02;KdPrint(("PTE2 %p\n",*(DWORD*)(0xC0000000 + ((HookFunAddr >> 10) & 0x003FFFFC))));
}

方法2:修改CR0寄存器

描述:CR0寄存器的第16位叫做保护属性位,控制着页的读/写属性

VOID PageProtectOn()
{__asm{mov  eax,cr0or   eax,10000hmov  cr0,eaxsti}
}VOID PageProtectOff()
{__asm{cli                  mov  eax,cr0and  eax,not 10000hmov  cr0,eax}
}

实验二:SSDT HOOK

第一步:编译如下代码

#include <ntddk.h>
#include <ntstatus.h>ULONG uOldNtOpenProcess;         //存储原来的NtOpenProcess地址typedef NTSTATUS (*NTOPENPROCESS)(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId);VOID PageProtectOn()
{__asm{//开启内存保护mov  eax,cr0or   eax,10000hmov  cr0,eaxsti}
}VOID PageProtectOff()
{__asm{//关闭内存保护cli                  mov  eax,cr0and  eax,not 10000hmov  cr0,eax}
}//1. 找到系统服务表:函数地址表
typedef struct _KSYSTEM_SERVICE_TABLE
{  PULONG  ServiceTableBase;            // 服务函数地址表基址  PULONG  ServiceCounterTableBase;      // SSDT函数被调用的次数ULONG   NumberOfService;         // 服务函数的个数  PULONG   ParamTableBase;            // 服务函数参数表基址
} 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;// KeServiceDescriptorTable 是 ntoskrnl.exe 所导出的全局变量 申明一下就可以直接使用了
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;//2. 准备用于替换的函数
NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId
){//自己的业务..各种过滤,或者修改返回结构NTSTATUS status;status = STATUS_SUCCESS;KdPrint(("%x %x %x %x \n", ProcessHandle, DesiredAccess, ObjectAttributes, ClientId));return ((NTOPENPROCESS)uOldNtOpenProcess)(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}//3. Hook
NTSTATUS HookNtOpenPRocess()
{NTSTATUS status;status = STATUS_SUCCESS;PageProtectOff();uOldNtOpenProcess = KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7A];KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7A] = (ULONG)MyNtOpenProcess;PageProtectOn();return status;
}//4. 恢复
NTSTATUS UnHookNtOpenPRocess()
{NTSTATUS status;status = STATUS_SUCCESS;PageProtectOff();KeServiceDescriptorTable->ntoskrnl.ServiceTableBase[0x7A] = (ULONG)uOldNtOpenProcess;PageProtectOn();return status;
}//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{UnHookNtOpenPRocess();DbgPrint("驱动程序已停止.\r\n");
}//驱动程序入口函数,相当于控制台的main函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{DbgPrint("驱动程序已运行.\r\n");HookNtOpenPRocess();//设置一个卸载函数  便于退出DriverObject->DriverUnload = DriverUnload;return STATUS_SUCCESS;
}

第二步:查看PCHunter(未HOOK)

第三步:运行驱动程序


第四步:查看PCHunter(已HOOK)

Windows驱动开发学习笔记(五)—— SSDT HOOK相关推荐

  1. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  2. Windows驱动开发学习笔记(七)—— 多核同步内核重载

    Windows驱动开发学习笔记(七)-- 多核同步 基础知识 并发与同步 分析 InterlockedIncrement 原子操作相关API 内核文件 多核同步 临界区 示例一:错误的临界区 示例二: ...

  3. Windows驱动开发学习笔记(三)—— 内核空间内核模块

    Windows驱动开发学习笔记(三)-- 内核空间&内核模块 内核空间 实验 第一步:编译如下代码 第二步:将 .sys 文件拷贝到虚拟机中 第三步:部署 .sys 文件并运行 第四步:创建一 ...

  4. Windows驱动开发学习笔记(四)—— 3环与0环通信(常规方式)

    Windows驱动开发学习笔记(四)-- 3环与0环通信(常规方式) 设备对象 创建设备对象 设置数据交互方式 创建符号链接 IRP与派遣函数 IRP的类型 其它类型的IRP 派遣函数 派遣函数注册位 ...

  5. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础

    Windows驱动开发学习笔记(二)-- 驱动调试&内核编程基础 基础知识 驱动调试 PDB(Program Debug Database) WinDbg 加载 PDB 实验:调试 .sys ...

  6. Windows驱动开发学习笔记(一)—— 环境配置第一个驱动程序

    Windows驱动开发学习笔记(一)-- 环境配置&第一个驱动程序 环境配置 第一个驱动程序 环境配置 安装VS2010:https://pan.baidu.com/s/1uZWWxCtB60 ...

  7. windows内核开发学习笔记十五:IRP结构

    windows内核开发学习笔记十五:IRP结构   IRP(I/O Request Package)在windows内核中,有一种系统组件--IRP,即输入输出请求包.当上层应用程序需要访问底层输入输 ...

  8. windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互

    windows内核开发学习笔记十七:IRP 和 IO_STACK_LOCATION 的交互 前面两篇学习笔记分别介绍了IRP和IO_STACK_LOCATION,整个设备栈来处理这个IRP,但是每个设 ...

  9. Android深度探索(卷1)HAL与驱动开发学习笔记(8)

    Android深度探索(卷1)HAL与驱动开发学习笔记(8) 第八章 蜂鸣器驱动   L i n u x驱动的代码重用有很多种方法.可以采用标准C程序的方式.将要重用的代码放在其他的文件(在头文件中声 ...

最新文章

  1. linux 内核 call,在Linux Kernel內新增一个System Call(转)
  2. Spark MLlib 机器学习
  3. mysql服务器端口cpu_mysql导致服务器cpu100%的问题一例
  4. 程序员究竟该如何提高效率
  5. CEO 赠书 | 节省 50% 的人生,终止“瞎忙”式勤奋
  6. CImageList类Create函数参数解析
  7. Java命令行界面(第27部分):cli-parser
  8. 在51单片机上使用递归的注意事项
  9. java 图片压缩100k_java实现图片压缩
  10. 怎么做批注_BIM平台是什么?有何用?怎么用?
  11. java super.getclass_Java Class 类 getSuperClass()方法及示例
  12. 机器学习十大经典算法之决策树
  13. Atitit 架构的艺术 目录 1. 按照技术站分类 1 1.1. LAMP架构,到IOE架构,再到分布式架构 1 1.2. Ssh ssm 1 2. Bs cs web hybrid架构 1 3.
  14. java.text.ParseException: Unparseable date:
  15. android整合极光im与极光推送,极光IM + 极光推送,集成中遇到的问题
  16. CTF知识总结--MISC
  17. .Net Core Pdf 转图片
  18. Unity背包系统(二)背包UI设计
  19. 盘古搜索--实例解析
  20. latex安装后运行报错:系统找不到指定的文件,试试这样吧

热门文章

  1. 成功解决A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,co
  2. 成功解决:连接sql server时插入数据库内容为乱码,并且输出也为乱码
  3. ML之SVM:利用SVM算法(超参数组合进行单线程网格搜索+3fCrVa)对20类新闻文本数据集进行分类预测、评估
  4. CV之OD:计算机视觉之目标检测(Object Detection)方向的简介、使用方法、案例应用之详细攻略
  5. hyperopt中文文档:Recipes
  6. 完全卸载oracle11g教程、Oracle11g的卸载方法和步骤
  7. vs2017 不能加载.vdproj
  8. 五分钟搞定 Linux 文档全部知识,就看这篇文章
  9. CentOS7安装xfce桌面环境
  10. ###STL学习--标准模板库