SSDT表的遍历(源码)
- //VS2005创建的工程,系统xp sp2
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //stdafx.h文件
- #ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
- #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
- #endif
- #ifdef __cplusplus
- extern "C"
- {
- #endif
- #include <ntddk.h>
- #include <ntddstor.h>
- #include <mountdev.h>
- #include <ntddvol.h>
- //注意:全局变量要在这里定义
- //系统服务描述符表-在ntoskrnl.exe中导出KeServiceDescriptorTable这个表
- #pragma pack(1)
- typedef struct _ServiceDescriptorTable
- {
- //System Service Dispatch Table的基地址
- PVOID ServiceTableBase;
- //SSDT中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
- PVOID ServiceCounterTable;
- //由 ServiceTableBase 描述的服务的数目。
- unsigned int NumberOfServices;
- //每个系统服务参数字节数表的基地址-系统服务参数表SSPT
- PVOID ParamTableBase;
- }*PServiceDescriptorTable;
- #pragma pack()
- //导出系统服务描述符表SSDT的指针
- extern PServiceDescriptorTable KeServiceDescriptorTable;
- #ifdef __cplusplus
- }
- #endif
- //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //ReadSsdtForFuntion.cpp文件
- #include "stdafx.h"
- //由SSDT索引号获取当前函数地址,如:
- //NtOpenProcess [[KeServiceDescriptorTable]+0x7A*4]
- void ReadSsdtForFuntionUnload(IN PDRIVER_OBJECT DriverObject);
- NTSTATUS ReadSsdtForFuntionCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
- NTSTATUS ReadSsdtForFuntionDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
- //1.纯汇编读取内核函数的地址
- LONG GetFunctionAddr_ASM(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex);
- //2.用指针读取内核函数的地址
- LONG GetFunticonAddr(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex);
- #ifdef __cplusplus
- extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
- #endif
- NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
- {
- UNICODE_STRING DeviceName,Win32Device;
- PDEVICE_OBJECT DeviceObject = NULL;
- NTSTATUS status;
- unsigned i;
- //SSDT表的范围
- LONG lgSsdtNumber = -1;
- RtlInitUnicodeString(&DeviceName,L"\\Device\\ReadSsdtForFuntion0");
- RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\ReadSsdtForFuntion0");
- //设置默认处理例程
- for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
- DriverObject->MajorFunction[i] = ReadSsdtForFuntionDefaultHandler;
- //设置创建例程
- DriverObject->MajorFunction[IRP_MJ_CREATE] = ReadSsdtForFuntionCreateClose;
- //设置关闭例程
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = ReadSsdtForFuntionCreateClose;
- //设置卸载例程
- DriverObject->DriverUnload = ReadSsdtForFuntionUnload;
- //创建设备对象
- status = IoCreateDevice(DriverObject,
- 0,
- &DeviceName,
- FILE_DEVICE_UNKNOWN,
- 0,
- FALSE,
- &DeviceObject);
- if (!NT_SUCCESS(status))
- return status;
- if (!DeviceObject)
- return STATUS_UNEXPECTED_IO_ERROR;
- DeviceObject->Flags |= DO_DIRECT_IO;
- DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
- //创建符号连接
- status = IoCreateSymbolicLink(&Win32Device, &DeviceName);
- if (!NT_SUCCESS(status))
- return status;
- //初始化完成,可以工作了
- DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- //设置测试断点
- __asm int 3
- //获取SSDT表的范围
- lgSsdtNumber = KeServiceDescriptorTable->NumberOfServices;
- //使用方法1.遍历SSDT
- KdPrint(("使用方法1.遍历SSDT\r\n"));
- for (i = 0; i < lgSsdtNumber; i++)
- {
- KdPrint(("Index:%04X--FunAddr:%08X\r\n", i, GetFunctionAddr_ASM(KeServiceDescriptorTable, i)));
- }
- //使用方法2.遍历SSDT
- KdPrint(("使用方法2.遍历SSDT\r\n"));
- for (i = 0; i < lgSsdtNumber; i++)
- {
- KdPrint(("Index:%04X--FunAddr:%08X\r\n", i, GetFunticonAddr(KeServiceDescriptorTable, i)));
- }
- return STATUS_SUCCESS;
- }
- //1.使用汇编的方法读取内核函数的地址
- LONG GetFunctionAddr_ASM(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex)
- {
- LONG lgSsdtFunAddr = 0;
- //lgSsdtFunAddr = [[KeServiceDescriptorTable]+lgSsdtIndex*4]
- __asm
- {
- push ebx
- push eax
- mov ebx, KeServiceDescriptorTable
- mov ebx, [ebx] //SSDT表的基地址
- mov eax, lgSsdtIndex
- shl eax, 2
- add ebx, eax
- mov ebx, [ebx]
- mov lgSsdtFunAddr, ebx
- pop eax
- pop ebx
- }
- return lgSsdtFunAddr;
- }
- //2.使用指针的方法获取函数的地址
- LONG GetFunticonAddr(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex)
- {
- LONG lgSsdtAddr = 0;
- //获取SSDT表的基址
- lgSsdtAddr = (LONG)KeServiceDescriptorTable->ServiceTableBase;
- PLONG plgSsdtFunAddr = 0;
- //获取内核函数的地址指针
- plgSsdtFunAddr = (PLONG)(lgSsdtAddr+lgSsdtIndex*4);
- //返回内核函数的地址
- return (*plgSsdtFunAddr);
- }
- void ReadSsdtForFuntionUnload(IN PDRIVER_OBJECT DriverObject)
- {
- UNICODE_STRING Win32Device;
- RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\ReadSsdtForFuntion0");
- IoDeleteSymbolicLink(&Win32Device);
- IoDeleteDevice(DriverObject->DeviceObject);
- }
- NTSTATUS ReadSsdtForFuntionCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
- {
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS ReadSsdtForFuntionDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
- {
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Irp->IoStatus.Status;
- }
- //参考资料:
- //郁金香老师讲课资料
SSDT表的遍历(源码)相关推荐
- C语言实现哈希表(附完整源码)
C语言实现哈希表 C语言实现哈希表附完整源码 C语言实现哈希表附完整源码 #include<stdio.h> #include<stdlib.h> #define SUCCES ...
- Map和Set,简单模拟实现哈希表以及哈希表部分底层源码的分析
目录 Map和Set的简单介绍 降低哈希冲突发生的概率以及当冲突发生时如何解决哈希冲突 简单模拟实现哈希表--1.key为整形:2.key为引用类型 哈希表部分底层源码的分析 1.Map和Set的简单 ...
- gh-ost大表DDL工具源码阅读
gh-ost大表DDL工具源码阅读 最终目的 开发环境与测试数据库准备 一个简单的ddl案例 debug分析程序执行过程 vscode debug配置 变量介绍 核心处理逻辑 分析我的需求 最终目的 ...
- OpenCV下设置灰度直方图的阈值来对图像进行查找(查表)变换的源码
如果图像的直方图集中在某一区间,画面表现现的是色彩单一,不利于观察分析,这个时候我们就可以通过对直方图设置上下两个阈值,找到这两个阈值对应的灰度级,分别记为iLow和iHigh,小于iLow的像素点的 ...
- C++实现skip list跳表(附完整源码)
C++实现skip list跳表 实现skip list跳表算法的完整源码(定义,实现,main函数测试) 实现skip list跳表算法的完整源码(定义,实现,main函数测试) #include ...
- C语言实现了一个顺序表(附完整源码)
C语言实现了一个顺序表 顺序表 顺序表的概念 顺序表的存储结构 C语言实现了顺序表完整源码 顺序表 顺序表的概念 顺序表是线性表的顺序存储结构,加按顺序存储方式构造的线性表的存储结构. 说明:对于n个 ...
- pos加盟申请php_ThinkPHP万能表单程序源码 报名预约加盟申请调查表单程序源码
平台声明:本商品由平台商家发布,如果本商品源码侵犯了您的利益请在上方价格右侧或联系平台客服举报. 微信表单-实现各行业的报名.预约.加盟申请.问卷调查等应用01.自定义表单模型(自定义字段支持字符串. ...
- java开发_mysql中获取数据库表描述_源码下载
功能描述: 在mysql数据库中,有两张表: data_element_config , test_table 我们需要获取表:test_table表的描述信息,然后把描述信息插入到表:data_el ...
- flink sql 知其所以然(二)| 自定义 redis 数据维表(附源码)
感谢您的关注 + 点赞 + 再看,对博主的肯定,会督促博主持续的输出更多的优质实战内容!!! 1.序篇-本文结构 背景篇-为啥需要 redis 维表 目标篇-做 redis 维表的预期效果是什么 ...
最新文章
- skycons.js 基于canvas的天气动态js插件
- 【蓝桥杯】基础练习 十进制转十六进制
- 虚拟机centos7 桥接模式
- ES6-symbol-创建symbol
- begin backup导致的故障恢复全过程
- linux rm 命令删除文件恢复_rm删除文件空间就释放了吗?天真!
- 测试显卡cpu中文软件,显卡信息检测工具(GPUinfo)
- 网络数据包的抓包(解析数据包内容)
- 大数据云端实验室项目实战-微博舆情大数据分析有感
- 10 个win10上记事本的替代品
- 谷歌/FOFA搜索引擎使用
- php 验证码一直不对,php验证码错误
- linux ap 模式,无线AP是什么,客户端模式(apclient)是什么意思?
- 【html5基础学习速成】
- kettle连接12c_kettle 链接oracle12c
- Leo的怯懦,由3000块钱而起的故事(3)大结局
- python画五角星和六角星程序_python画五角星和六角星程序
- 一个金融行业站SEO优化方案分析
- 【查找】临近省赛,Alan邀请emoji玩起了猜数字游戏活跃一下大脑。游戏规则如下:首先Alan写下几个数字让emoji猜,当emoji猜完之后,Alan会给他一个提示(java)
- utorrent无传入连接_utorrent设置教程~
热门文章
- maven常用命令(编译、测试、运行、打包、安装、部署)
- RocketMQ核心架构和概
- 常用的函数式接口_Consumer接口的默认方法andThen
- spring配置详解-三种对象创建方式_
- 设计模式之_动态代理_06
- Bootstrap组件_巨幕,页头,缩略图
- 两个iphone怎么大量传照片_手机照片删除了怎么恢复?这两个简单方法一看就会,还不收藏?...
- 实习笔记0708 https协议/ django中间件/接口测试/内网与外网/域名系统DNS
- tcp与ip协议的区别
- flask sqlalchemy一对多关系详解