首页 > 代码库 > SSDT表的遍历
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表的遍历
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。