//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表的遍历的更多相关文章

  1. SSDT表概念具体解释

    SSDT 的全称是 System Services Descriptor Table,系统服务描写叙述符表. 这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系 ...

  2. SSDT表概念详解

    SSDT 的全称是 System Services Descriptor Table,系统服务描述符表. 这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来 ...

  3. Lua 多维表的遍历中的赋值

    说到Lua的遍历将要使用到循环:先说遍历再说循环: 遇到这样类似结构的一个table Data={ []={p1=,pa={,,}}, []={p1=,pa={,,}}, []={p1=,pa={,, ...

  4. SSDT表详解

    SSDT(system service dispatch table) 系统服务分派表 SSPT(system service parameter table) 系统服务参数表 #pragma pac ...

  5. 内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式.

    内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式. 一丶IDT解析. 我们知道.IDT表中存放着各种中断信息.比如当我们调用int 3的时候,则会调用IDT表中的第三项来进行调用. 而函数 ...

  6. 64位内核开发第四讲,查看SSDT表与showSSDT表

    目录 SSDt表与ShadowSSDT表的查看. 一丶SSDT表 1.什么是SSDT表 2.查看步骤 二丶ShadowSSDT表 1.什么是ShadowSSDT表 2.如何查看. 三丶工具介绍 SSD ...

  7. SSDT表函数Hook原理

    其实 SSDT Hook 的原理是很简单的,我们可以知道在 SSDT 这个数组中呢,保存了系统服务的地址,比如对于 Ring0 下的 NtQuerySystemInformation 这个系统服务的地 ...

  8. SSDT表结构的深入学习

    SSDT表的知识目录: A.了解SSDT结构 B.由SSDT索引号获取当前函数地址        C.如何获取索引号 D.获取起源地址-判断SSDT是否被HOOK E.如何向内核地址写入自己代码 A. ...

  9. 驱动开发:Win10内核枚举SSDT表基址

    三年前面朝黄土背朝天的我,写了一篇如何在Windows 7系统下枚举内核SSDT表的文章<驱动开发:内核读取SSDT表基址>三年过去了我还是个单身狗,开个玩笑,微软的Windows 10系 ...

随机推荐

  1. Jacobi与SOR迭代法的实现与性能比较及均匀间距与Chebyshev插值的实现、性能分析及二者生成的插值误差比较

    这篇文章给出(1)Jacobi与SOR迭代法的实现与性能比较及(2)均匀间距与Chebyshev插值的实现.性能分析及二者生成的插值误差比较,给出完整的实现代码,没有进行性能优化,仅供参考. (1)J ...

  2. 《深入浅出WPF》-刘铁猛学习笔记——XAML

    XAML是什么? XAML是微软公司创造的一种开发语言,XAML的全称是 Extensible Application Markup Language,即可拓展应用程序标记语言. 它由XML拓展而来, ...

  3. Python3+pygame实现的90坦克大战 代码完整 有演示效果

    我是一个典型的80后,年轻时玩过了特别多的游戏,所以这几天用Python3+pygame实现了一个另外小游戏"坦克大战"(其他的游戏,请翻阅我的博客) 本实例代码量有些多,完整的版 ...

  4. 自己动手实现springboot运行时新增/更新外部接口

    最近有个需求:需要让现有springboot项目可以加载外部的jar包实现新增.更新接口逻辑.本着拿来主义的思维网上找了半天没有找到类似的东西,唯一有点相似的还是spring-loaded但是这个东西 ...

  5. vue之better-scroll详解及封装

    在我们的h5或移动端网页开发中,常常会需要实现滚动加载数据,等需求,而在开发中原生开发往往会带来意想不到的问题,因此我们引入better-scroll来帮我们实现流畅的滚动效果. 什么是better- ...

  6. 使用dcmtk库读取.dcm文件并获取信息+使用OpenCV显示图像

    借助VS2013和OpenCV的绘图功能,在工程DICOMReader.sln中实现了对单张.dcm图像的读取与显示,以下是详细步骤. 前期准备工作 编译器:VS2013 库:dcmtk-3.6.0( ...

  7. python 实现输出一个等腰三角形

    这个问题实际上是一个数学问题,我们主要找出每行的规律就可以根据规律来书写代码 """ 2 代码实现输出一个等腰三角形,实际上就是一个等差数列求各项的一个数学> 问题 ...

  8. SpringBoot-03 yaml+JSR303

    SpringBoot-03 yaml+JSR303 Yaml 1.配置文件 SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的 YAML是 "YAML Ain't a Ma ...

  9. 什么是SSR SSR有什么用 如何使用使用SSR

    什么是SSR 以下信息来自维基百科: Shadowsocks(简称SS)是一种基于Socks5代理方式的加密传输协议,也可以指实现这个协议的各种开发包.当前包使用Python.C.C++.C#.Go语 ...

  10. Spring Boot MVC 单张图片和多张图片上传 和通用文件下载

    @Autowired private ServerConfig serverConfig; /** * 通用下载请求 * * @param fileName 文件名称 * @param delete ...