日期:2014-05-17 浏览次数:20752 次
#include "ntddk.h" #pragma pack(1) typedef struct _SYS_SERVICE_TABLE { void*ServiceTable;//指向函数表地址 void *CounterTable; //指向函数调用次数记录表,用于调试阶段 unsigned long ServiceLimit; //服务数 void*ArgumentsTable; //参数表 }SYS_SERVICE_TABLE,*PSSDT; //系统服务表述表 SYS_SERVICE_TABLE #pragma pack() extern PSSDT KeServiceDescriptorTable; PMDL g_pmdlSystemCall;//MDL指针 void *MappedSSDT;//用于保存我们使用MDL描述的原SSDT表的地址,这个地址的SSDT的内存保护设为了“可写” const WCHAR devicename[]=L"\\Device\\Protector";//设备名 const WCHAR devicelink[]=L"\\DosDevices\\PROTECTOR";//设备符号连接名 typedef NTSTATUS (*CREATESECTION)(OUT PHANDLE SectionHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN PLARGE_INTEGER MaximumSize OPTIONAL,IN ULONG SectionPageProtection,IN ULONG AllocationAttributes,IN HANDLE FileHandle OPTIONAL); CREATESECTION RealCallee;//保存原先本来该调用的函数地址 ULONG SSDT_Address;//用于保存相关函数的地址,用于最后退出程序时修改过来 //-----------------------------------------判断是否允许使用------------------------------------- //this function decides whether we should allow NtCreateSection() call to be successfull NTSTATUS MyCreateSection(OUT PHANDLE SectionHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,IN PLARGE_INTEGER MaximumSize OPTIONAL,IN ULONG SectionPageProtection,IN ULONG AllocationAttributes,IN HANDLE FileHandle OPTIONAL) { return RealCallee(SectionHandle,DesiredAccess,ObjectAttributes,MaximumSize,SectionPageProtection,AllocationAttributes,FileHandle); } //----------------------------Dispatch Routine-------------------------------- NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp) { ULONG Input; //暂存 PIO_STACK_LOCATION loc=IoGetCurrentIrpStackLocation(Irp);//获取IRP堆栈地址 if(loc->Parameters.DeviceIoControl.IoControlCode==1000)//如果是自己制定的操作,操作号设成了1000,见主程序代码 { SSDT_Address=(ULONG)(((PSSDT)MappedSSDT)->ServiceTable)+4*50;//获取函数在的SSDT表的表项地址 RealCallee=(CREATESECTION)(*((ULONG*)SSDT_Address));//记录真实的被调用者 Input=(ULONG)MyCreateSection;//赋给Input RtlMoveMemory((ULONG*)SSDT_Address,&Input,4);//把我们自己的函数地址放到SSDT中 } Irp->IoStatus.Status=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return 0; } //---------------------------------打开关闭请求的处理-------------------------------------- // nothing special NTSTATUS DrvCreateClose(IN PDEVICE_OBJECT device,IN PIRP Irp) { Irp->IoStatus.Information=0; Irp->IoStatus.Status=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return 0; } //------------------------------------------------------------------------ // nothing special -just a cleanup void DrvUnload(IN PDRIVER_OBJECT driver) { UNICODE_STRING devlink; RtlMoveMemory((PVOID)SSDT_Address,&RealCallee,4);//把原地址复原 if(g_pmdlSystemCall) { MmUnmapLockedPages(MappedSSDT,g_pmdlSystemCall);//取消MDL内存映射 MmUnlockPages(g_pmdlSystemCall);//取消内存锁定 IoFreeMdl(g_pmdlSystemCall); } RtlInitUnicodeString(&devlink,devicelink); IoDeleteSymbolicLink(&devlink); IoDeleteDevice(driver->DeviceObject); KdPrint(("驱动卸载完毕.\n")); } //-------------------------------------------------------------------- //DriverEntry just creates our device - nothing special here 初始化映射SSDT NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING path) { PDEVICE_OBJECT devobject; UNICODE_STRING devlink,devname;//设备符号链接名和设备名 devobject=0; RtlInitUnicodeString(&devname,devicename);//赋值 RtlInitUnicodeString(&devlink,devicelink); IoCreateDevice(driver,256,&devname,FILE_DEVICE_UNKNOWN,0,TRUE,&devobject);//创建设备 IoCreateSymbolicLink(&devlink,&devname);//把符号链接名和设备名相关联 driver->Majo