SSDT表的遍历(源码)

来源:互联网 发布:天下3 英雄榜数据 编辑:程序博客网 时间:2024/05/16 14:14
  1. //VS2005创建的工程,系统xp sp2  
  2.   
  3. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
  4.   
  5. //stdafx.h文件  
  6. #ifndef _WIN32_WINNT        // Allow use of features specific to Windows XP or later.                     
  7. #define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.  
  8. #endif                        
  9.   
  10. #ifdef __cplusplus  
  11. extern "C"   
  12. {  
  13.   
  14. #endif  
  15.   
  16. #include <ntddk.h>  
  17. #include <ntddstor.h>  
  18. #include <mountdev.h>  
  19. #include <ntddvol.h>  
  20.   
  21. //注意:全局变量要在这里定义  
  22.   
  23. //系统服务描述符表-在ntoskrnl.exe中导出KeServiceDescriptorTable这个表  
  24. #pragma pack(1)  
  25. typedef struct _ServiceDescriptorTable  
  26. {  
  27.     //System Service Dispatch Table的基地址  
  28.     PVOID ServiceTableBase;        
  29.     //SSDT中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。  
  30.     PVOID ServiceCounterTable;   
  31.     //由 ServiceTableBase 描述的服务的数目。  
  32.     unsigned int NumberOfServices;    
  33.     //每个系统服务参数字节数表的基地址-系统服务参数表SSPT   
  34.     PVOID ParamTableBase;   
  35. }*PServiceDescriptorTable;    
  36. #pragma pack()  
  37.   
  38. //导出系统服务描述符表SSDT的指针  
  39. extern  PServiceDescriptorTable  KeServiceDescriptorTable;   
  40.   
  41. #ifdef __cplusplus  
  42. }  
  43. #endif  
  44.   
  45. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  
  46.   
  47. //ReadSsdtForFuntion.cpp文件  
  48. #include "stdafx.h"  
  49.   
  50. //由SSDT索引号获取当前函数地址,如:    
  51. //NtOpenProcess  [[KeServiceDescriptorTable]+0x7A*4]    
  52.   
  53. void ReadSsdtForFuntionUnload(IN PDRIVER_OBJECT DriverObject);  
  54. NTSTATUS ReadSsdtForFuntionCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);  
  55. NTSTATUS ReadSsdtForFuntionDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);  
  56.   
  57. //1.纯汇编读取内核函数的地址  
  58. LONG GetFunctionAddr_ASM(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex);  
  59.   
  60. //2.用指针读取内核函数的地址  
  61. LONG GetFunticonAddr(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex);  
  62.   
  63.   
  64. #ifdef __cplusplus  
  65. extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);  
  66. #endif  
  67.   
  68. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)  
  69. {  
  70.     UNICODE_STRING DeviceName,Win32Device;  
  71.     PDEVICE_OBJECT DeviceObject = NULL;  
  72.     NTSTATUS status;  
  73.     unsigned i;  
  74.   
  75.     //SSDT表的范围  
  76.     LONG lgSsdtNumber = -1;  
  77.   
  78.     RtlInitUnicodeString(&DeviceName,L"\\Device\\ReadSsdtForFuntion0");  
  79.     RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\ReadSsdtForFuntion0");  
  80.   
  81.     //设置默认处理例程  
  82.     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)  
  83.         DriverObject->MajorFunction[i] = ReadSsdtForFuntionDefaultHandler;  
  84.   
  85.     //设置创建例程  
  86.     DriverObject->MajorFunction[IRP_MJ_CREATE] = ReadSsdtForFuntionCreateClose;  
  87.     //设置关闭例程  
  88.     DriverObject->MajorFunction[IRP_MJ_CLOSE] = ReadSsdtForFuntionCreateClose;  
  89.       
  90.     //设置卸载例程  
  91.     DriverObject->DriverUnload = ReadSsdtForFuntionUnload;  
  92.   
  93.     //创建设备对象  
  94.     status = IoCreateDevice(DriverObject,  
  95.                             0,  
  96.                             &DeviceName,  
  97.                             FILE_DEVICE_UNKNOWN,  
  98.                             0,  
  99.                             FALSE,  
  100.                             &DeviceObject);  
  101.     if (!NT_SUCCESS(status))  
  102.         return status;  
  103.     if (!DeviceObject)  
  104.         return STATUS_UNEXPECTED_IO_ERROR;  
  105.   
  106.     DeviceObject->Flags |= DO_DIRECT_IO;  
  107.     DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;  
  108.   
  109.     //创建符号连接  
  110.     status = IoCreateSymbolicLink(&Win32Device, &DeviceName);  
  111.     if (!NT_SUCCESS(status))  
  112.         return status;  
  113.   
  114.     //初始化完成,可以工作了  
  115.     DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;  
  116.   
  117.     //设置测试断点  
  118.     __asm int 3  
  119.   
  120.     //获取SSDT表的范围  
  121.     lgSsdtNumber = KeServiceDescriptorTable->NumberOfServices;  
  122.   
  123.     //使用方法1.遍历SSDT  
  124.     KdPrint(("使用方法1.遍历SSDT\r\n"));  
  125.     for (i = 0; i < lgSsdtNumber; i++)  
  126.     {  
  127.         KdPrint(("Index:%04X--FunAddr:%08X\r\n", i, GetFunctionAddr_ASM(KeServiceDescriptorTable, i)));  
  128.     }  
  129.   
  130.     //使用方法2.遍历SSDT  
  131.     KdPrint(("使用方法2.遍历SSDT\r\n"));  
  132.     for (i = 0; i < lgSsdtNumber; i++)  
  133.     {  
  134.         KdPrint(("Index:%04X--FunAddr:%08X\r\n", i, GetFunticonAddr(KeServiceDescriptorTable, i)));  
  135.     }  
  136.   
  137.     return STATUS_SUCCESS;  
  138. }  
  139.   
  140.   
  141. //1.使用汇编的方法读取内核函数的地址  
  142. LONG GetFunctionAddr_ASM(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex)  
  143. {  
  144.     LONG lgSsdtFunAddr = 0;  
  145.   
  146.     //lgSsdtFunAddr = [[KeServiceDescriptorTable]+lgSsdtIndex*4]  
  147.     __asm  
  148.     {      
  149.         push ebx  
  150.         push eax  
  151.         mov ebx, KeServiceDescriptorTable  
  152.         mov ebx, [ebx]  //SSDT表的基地址  
  153.         mov eax, lgSsdtIndex  
  154.         shl eax, 2        
  155.         add ebx, eax          
  156.         mov ebx, [ebx]  
  157.         mov lgSsdtFunAddr, ebx  
  158.         pop  eax      
  159.         pop  ebx  
  160.     }  
  161.   
  162.     return lgSsdtFunAddr;  
  163. }  
  164.   
  165. //2.使用指针的方法获取函数的地址  
  166. LONG GetFunticonAddr(PServiceDescriptorTable KeServiceDescriptorTable, LONG lgSsdtIndex)  
  167. {  
  168.     LONG lgSsdtAddr = 0;  
  169.     //获取SSDT表的基址  
  170.     lgSsdtAddr = (LONG)KeServiceDescriptorTable->ServiceTableBase;  
  171.   
  172.     PLONG plgSsdtFunAddr = 0;   
  173.     //获取内核函数的地址指针  
  174.     plgSsdtFunAddr = (PLONG)(lgSsdtAddr+lgSsdtIndex*4);  
  175.   
  176.     //返回内核函数的地址  
  177.     return (*plgSsdtFunAddr);     
  178. }  
  179.   
  180.   
  181. void ReadSsdtForFuntionUnload(IN PDRIVER_OBJECT DriverObject)  
  182. {  
  183.     UNICODE_STRING Win32Device;  
  184.     RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\ReadSsdtForFuntion0");  
  185.     IoDeleteSymbolicLink(&Win32Device);  
  186.     IoDeleteDevice(DriverObject->DeviceObject);  
  187. }  
  188.   
  189. NTSTATUS ReadSsdtForFuntionCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)  
  190. {  
  191.     Irp->IoStatus.Status = STATUS_SUCCESS;  
  192.     Irp->IoStatus.Information = 0;  
  193.     IoCompleteRequest(Irp, IO_NO_INCREMENT);  
  194.     return STATUS_SUCCESS;  
  195. }  
  196.   
  197. NTSTATUS ReadSsdtForFuntionDefaultHandler(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)  
  198. {  
  199.     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;  
  200.     Irp->IoStatus.Information = 0;  
  201.     IoCompleteRequest(Irp, IO_NO_INCREMENT);  
  202.     return Irp->IoStatus.Status;  
  203. }  
  204.   
  205. //参考资料:  
  206. //郁金香老师讲课资料  
原创粉丝点击