//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. vue封装一个弹框组件

    这是一个提示框和对话框,例:   这是一个组件 eject.vue <template> <div class='kz-cont' v-show='showstate'> &l ...

  2. 记一次Drone无法触发构建的问题

    问题 好巧不巧,当你晚上准备上线的时候,在下午临近下班的时候CI&CD工具出问题了,提交代码不能触发构建,不能上线了,Drone平台那边也下班了,正好CICD依赖的公司git仓库也出问题了(就 ...

  3. 04----python入门----文件处理

    一.大致介绍 我们在计算机上进行的操作,归根结底是对文件的操作,其实质是由操作系统发送请求,将用户或者应用程序对文件读写操作转换成具体的硬盘指令. 众所周知,内存中的数据是无法永久保存的.在计算机硬件 ...

  4. 反射的常用API

    反射的常用API 加载程序集 Assembly assembly = Assembly.Load("程序集名称"); // 从前目录加载程序集,提供程序集名称,无后缀 Assemb ...

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

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

  6. CloudQuery v1.3.4 版本更新

    Hello,大家好久不见! 上一个版本(v1.3.3)发布已是春节前的事情了,此次 v1.3.4 是 CloudQuery 社区版在辛丑牛年的第一个版本发布.本次更新增加了新功能,优化了原有功能点.同 ...

  7. FreeBSD 13 显卡支持

    On FreeBSD 13, using drm-devel-kmod, support is the same as on Linux 5.4. This includes support for ...

  8. webpack4.x 从零开始配置vue 项目(一)基础搭建项目

    序 现在依旧记得第一次看到webpack3.x 版本配置时候的状态  刚开始看到这些真的是一脸懵.希望这篇文章能帮到刚开始入门的同学. webpack 是什么? webpack是一个模块化打包工具,w ...

  9. 一本关于HTTP的恋爱日记

    1991年 8月 我叫客户端,英文名字 client. 她叫服务端,英文名字 server. 这一年,我们出生了. 是的,我们都是90后. 我爱她,可是她却远在天边. 为了和她可以互诉衷肠,我同时发明 ...

  10. JS基础学习第三天

    条件分支语句switch语句语法: 1234567891011121314 switch(条件表达式){ case 表达式: 语句... break; case 表达式: 语句... break; c ...