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系 ...
随机推荐
- HDOJ-3001(TSP+三进制状态压缩)
Traving HDOJ-3001 这题考察的是状态压缩dp和tsp问题的改编 需要和传统tsp问题区分的事,这题每个点最多可以经过两次故状态有3种:0,1,2 这里可以模仿tsp问题的二进制压缩方法 ...
- CVE-2017-7504-JBoss JMXInvokerServlet 反序列化
漏洞分析 https://paper.seebug.org/312/ 漏洞原理 这是经典的JBoss反序列化漏洞,JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的 ...
- AtCoder Beginner Contest 194
A I Scream int main() { IOS; int a, b; cin >> a >> b; if(a + b >= 15 && b > ...
- BIMFACE二次开发【C#系列】
本系列文章主要介绍使用 C# .ASP.NET(MVC)技术对 BIMFACE 平台进行二次开发,以满足本公司针对建筑行业施工图审查系统的业务需求,例如图纸模型(PDF 文件.二维 CAD 模型.三维 ...
- 利用kali系统制作最简单的OS
制作最简单的OS 一.生成.bin文件 1.创建Boot.asm文件,输入相应的汇编代码 org 07c00h ; mov ax, cs mov ds, ax mov es, ax call Disp ...
- 内存模型与c++中的memory order
概 c++的atomic使用总会配合各种各样的memory order进行使用,memory order控制了执行结果在多核中的可见顺序,,这个可见顺序与代码序不一定一致(第一句代码执行完成的结果不一 ...
- go-echarts 入门安装和使用
在 Golang 这门语言中,目前数据可视化的第三方库还是特别少,go-echarts的开发就是为了填补这部分的空隙.Echarts是百度开源的非常优秀的可视化图表库,凭借着良好的交互性,精巧的图表设 ...
- 浅析MyBatis(四):全自动写代码的MyBatis逆向工程
在前面几篇文章中,笔者介绍了 MyBatis 的运行流程,在此基础上简单介绍了手写 MyBatis 简易框架与自定义 MyBatis 插件的步骤,相信大家对于 MyBatis 框架的使用流程已经游刃有 ...
- 推荐模型NeuralCF:原理介绍与TensorFlow2.0实现
1. 简介 NCF是协同过滤在神经网络上的实现--神经网络协同过滤.由新加坡国立大学与2017年提出. 我们知道,在协同过滤的基础上发展来的矩阵分解取得了巨大的成就,但是矩阵分解得到低维隐向量求内积是 ...
- Mybatis自定义拦截器与插件开发
在Spring中我们经常会使用到拦截器,在登录验证.日志记录.性能监控等场景中,通过使用拦截器允许我们在不改动业务代码的情况下,执行拦截器的方法来增强现有的逻辑.在mybatis中,同样也有这样的业务 ...