- //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表的遍历(源码)
最新推荐文章于 2022-10-19 10:48:11 发布