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表的遍历的更多相关文章
- SSDT表概念具体解释
SSDT 的全称是 System Services Descriptor Table,系统服务描写叙述符表. 这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系 ...
- SSDT表概念详解
SSDT 的全称是 System Services Descriptor Table,系统服务描述符表. 这个表就是一个把 Ring3 的 Win32 API 和 Ring0 的内核 API 联系起来 ...
- Lua 多维表的遍历中的赋值
说到Lua的遍历将要使用到循环:先说遍历再说循环: 遇到这样类似结构的一个table Data={ []={p1=,pa={,,}}, []={p1=,pa={,,}}, []={p1=,pa={,, ...
- SSDT表详解
SSDT(system service dispatch table) 系统服务分派表 SSPT(system service parameter table) 系统服务参数表 #pragma pac ...
- 内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式.
内核知识第12讲,SSDT表.以用户模式到系统模式的两种方式. 一丶IDT解析. 我们知道.IDT表中存放着各种中断信息.比如当我们调用int 3的时候,则会调用IDT表中的第三项来进行调用. 而函数 ...
- 64位内核开发第四讲,查看SSDT表与showSSDT表
目录 SSDt表与ShadowSSDT表的查看. 一丶SSDT表 1.什么是SSDT表 2.查看步骤 二丶ShadowSSDT表 1.什么是ShadowSSDT表 2.如何查看. 三丶工具介绍 SSD ...
- SSDT表函数Hook原理
其实 SSDT Hook 的原理是很简单的,我们可以知道在 SSDT 这个数组中呢,保存了系统服务的地址,比如对于 Ring0 下的 NtQuerySystemInformation 这个系统服务的地 ...
- SSDT表结构的深入学习
SSDT表的知识目录: A.了解SSDT结构 B.由SSDT索引号获取当前函数地址 C.如何获取索引号 D.获取起源地址-判断SSDT是否被HOOK E.如何向内核地址写入自己代码 A. ...
- 驱动开发:Win10内核枚举SSDT表基址
三年前面朝黄土背朝天的我,写了一篇如何在Windows 7系统下枚举内核SSDT表的文章<驱动开发:内核读取SSDT表基址>三年过去了我还是个单身狗,开个玩笑,微软的Windows 10系 ...
随机推荐
- vue封装一个弹框组件
这是一个提示框和对话框,例: 这是一个组件 eject.vue <template> <div class='kz-cont' v-show='showstate'> &l ...
- 记一次Drone无法触发构建的问题
问题 好巧不巧,当你晚上准备上线的时候,在下午临近下班的时候CI&CD工具出问题了,提交代码不能触发构建,不能上线了,Drone平台那边也下班了,正好CICD依赖的公司git仓库也出问题了(就 ...
- 04----python入门----文件处理
一.大致介绍 我们在计算机上进行的操作,归根结底是对文件的操作,其实质是由操作系统发送请求,将用户或者应用程序对文件读写操作转换成具体的硬盘指令. 众所周知,内存中的数据是无法永久保存的.在计算机硬件 ...
- 反射的常用API
反射的常用API 加载程序集 Assembly assembly = Assembly.Load("程序集名称"); // 从前目录加载程序集,提供程序集名称,无后缀 Assemb ...
- 自己动手实现springboot运行时新增/更新外部接口
最近有个需求:需要让现有springboot项目可以加载外部的jar包实现新增.更新接口逻辑.本着拿来主义的思维网上找了半天没有找到类似的东西,唯一有点相似的还是spring-loaded但是这个东西 ...
- CloudQuery v1.3.4 版本更新
Hello,大家好久不见! 上一个版本(v1.3.3)发布已是春节前的事情了,此次 v1.3.4 是 CloudQuery 社区版在辛丑牛年的第一个版本发布.本次更新增加了新功能,优化了原有功能点.同 ...
- FreeBSD 13 显卡支持
On FreeBSD 13, using drm-devel-kmod, support is the same as on Linux 5.4. This includes support for ...
- webpack4.x 从零开始配置vue 项目(一)基础搭建项目
序 现在依旧记得第一次看到webpack3.x 版本配置时候的状态 刚开始看到这些真的是一脸懵.希望这篇文章能帮到刚开始入门的同学. webpack 是什么? webpack是一个模块化打包工具,w ...
- 一本关于HTTP的恋爱日记
1991年 8月 我叫客户端,英文名字 client. 她叫服务端,英文名字 server. 这一年,我们出生了. 是的,我们都是90后. 我爱她,可是她却远在天边. 为了和她可以互诉衷肠,我同时发明 ...
- JS基础学习第三天
条件分支语句switch语句语法: 1234567891011121314 switch(条件表达式){ case 表达式: 语句... break; case 表达式: 语句... break; c ...