1.理解过滤的概念
关于过滤,我们可以举一个现实中的例子。比如一条河流中水的流向由东向西,但是呢我们想要去掉水中的杂物,又要不影响水的流向,这时我们可以在东西中间插入一张过滤网,这样就可以实现我们的目的了。这次我们用过滤PCHunter32as.sys中的例程其实就是这个思想。
还有一个我们也要明白,我们为什么能够替换其他其他驱动程序的例程呢,因为IO管理器实现了通用的框架,每个驱动程序的参数,返回值他们定义都是相同的。
2.PCHunter查看驱动对象地址
3.Windbg查看驱动对象
kd> dt _DRIVER_OBJECT -b 0x86855ED8
ntdll!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : 0x86855138
+0x008 Flags : 0x12
+0x00c DriverStart : 0x9648d000
+0x010 DriverSize : 0xb0000
+0x014 DriverSection : 0x86855078
+0x018 DriverExtension : 0x86855f80
+0x01c DriverName : _UNICODE_STRING "\Driver\PCHunter32as"
+0x000 Length : 0x28
+0x002 MaximumLength : 0x28
+0x004 Buffer : 0x87f55c18 "\Driver\PCHunter32as"
+0x024 HardwareDatabase : 0x841c2250
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0x96538000
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0x96500e50
+0x038 MajorFunction :
[00] 0x9650185a
[01] 0x83f0bda3
[02] 0x9650185a
[03] 0x83f0bda3
[04] 0x83f0bda3
[05] 0x83f0bda3
[06] 0x83f0bda3
[07] 0x83f0bda3
[08] 0x83f0bda3
[09] 0x83f0bda3
[10] 0x83f0bda3
[11] 0x83f0bda3
[12] 0x83f0bda3
[13] 0x83f0bda3
[14] 0x96554030
[15] 0x83f0bda3
[16] 0x83f0bda3
[17] 0x83f0bda3
[18] 0x83f0bda3
[19] 0x83f0bda3
[20] 0x83f0bda3
[21] 0x83f0bda3
[22] 0x83f0bda3
[23] 0x83f0bda3
[24] 0x83f0bda3
[25] 0x83f0bda3
[26] 0x83f0bda3
[27] 0x83f0bda3
MajorFunction中的好多例程是0x83f0bda3,其实这个是系统提供的默认例程,就是驱动程序没有做任何事情。使用Windbg查看此函数:
kd> u 0x83f0bda3
nt!IopInvalidDeviceRequest:
83f0bda3 8bff mov edi,edi
83f0bda5 55 push ebp
83f0bda6 8bec mov ebp,esp
83f0bda8 8b4d0c mov ecx,dword ptr [ebp+0Ch]
83f0bdab 32d2 xor dl,dl
83f0bdad c74118100000c0 mov dword ptr [ecx+18h],0C0000010h
83f0bdb4 ff15600afc83 call dword ptr [nt!pIofCompleteRequest (83fc0a60)]
83f0bdba b8100000c0 mov eax,0C0000010h
4.实现简单的过滤
#include <ntddk.h>
/*************************************************************************/
NTKERNELAPI NTSTATUS ObReferenceObjectByName(
IN PUNICODE_STRING ObjectName,
IN ULONG Attributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType,
IN KPROCESSOR_MODE AccessMode,
IN OUT PVOID ParseContext OPTIONAL,
OUT PVOID *Object
);
extern POBJECT_TYPE *IoDriverObjectType;
PDRIVER_OBJECT g_FilterDriverObject;
PDRIVER_DISPATCH gfn_OrigReadCompleteRoutine;
/*************************************************************************/
NTSTATUS FilterDeviceControlCompleteRoutine(
_In_ struct _DEVICE_OBJECT *DeviceObject,
_Inout_ struct _IRP *Irp
)
{
KdPrint(("Device Control is coming!\n"));
return gfn_OrigReadCompleteRoutine(DeviceObject, Irp);
}
VOID UnFilterDriverRoutine()
{
//检测地址是否有效
if (MmIsAddressValid(g_FilterDriverObject))
{
//卸载的时候恢复过来
g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = gfn_OrigReadCompleteRoutine;
}
}
NTSTATUS FilterDriverQuery()
{
NTSTATUS Status;
UNICODE_STRING usObjectName;
RtlInitUnicodeString(&usObjectName, L"\\Driver\\PCHunter32as");
//OBJ_CASE_INSENSITIVE 不区分大小写
Status = ObReferenceObjectByName(&usObjectName, \
OBJ_CASE_INSENSITIVE, \
NULL, \
0, \
*IoDriverObjectType, \
KernelMode, \
NULL, \
(PVOID*)&g_FilterDriverObject);
if (!NT_SUCCESS(Status))
{
KdPrint(("ObReferenceObjectByName faild\n"));
return Status;
}
KdPrint(("%p\n", g_FilterDriverObject));
//过滤,不能影响原来流程
gfn_OrigReadCompleteRoutine = g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
g_FilterDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FilterDeviceControlCompleteRoutine;
ObDereferenceObject(g_FilterDriverObject);
return STATUS_SUCCESS;
}
VOID UnloadDriver(PDRIVER_OBJECT pDriver)
{
KdPrint(("UnloadDriver \n"));
UnFilterDriverRoutine();
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
NTSTATUS Status;
KdPrint(("%p--%wZ\n", pDriver, pReg));
pDriver->DriverUnload = UnloadDriver;
FilterDriverQuery();
return STATUS_SUCCESS;
}