
正文
《寒江独钓_Windows内核安全编程》中修改类驱动分发函数
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
最近在阅读《寒江独钓_Windows内核安全编程》一书的过程中,发现修改类驱动分发函数这一技术点,书中只给出了具体思路和部分代码,没有完整的例子。
按照作者的思路和代码,将例子补充完整,发现将驱动安装在WIN7 32位环境下,键盘失效。
经调试发现,可能的原因是替换了\\Driver\\Kbdclass类驱动的所有分发函数导致,如果只替换分发IRP_MJ_READ的函数,不会有问题,以下为代码
//替换分发函数 来实现过滤
#include <wdm.h>
#include <Ntddkbd.h>
// Kbdclass驱动的名字
#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"
//旧的函数地址
PDRIVER_DISPATCH OldDispatchFun[IRP_MJ_MAXIMUM_FUNCTION+];
extern POBJECT_TYPE *IoDriverObjectType;
PDRIVER_DISPATCH OldDIspatchRead;
// 这个函数是事实存在的,只是文档中没有公开。声明一下
// 就可以直接使用了。
NTSTATUS
ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);
//新的分发函数地址
NTSTATUS c2pDispatchGeneral(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION irpStack=IoGetCurrentIrpStackLocation(Irp);
DbgPrint("irpStack->MinorFunction=%x\n",irpStack->MinorFunction);
return OldDIspatchRead(DeviceObject,Irp);
//return OldDispatchFun[irpStack->MinorFunction](DeviceObject,Irp);
}
#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
//卸载时候 要替换回来
VOID c2pUnload(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
int nIndex = ;
PDRIVER_OBJECT KeyBoardDriverObject = NULL;
UNICODE_STRING KeyBoardName;
LARGE_INTEGER Delay; RtlInitUnicodeString(&KeyBoardName, L"\\Driver\\Kbdclass"); Status = ObReferenceObjectByName(&KeyBoardName, OBJ_CASE_INSENSITIVE, NULL, , *IoDriverObjectType,
KernelMode, NULL, &KeyBoardDriverObject); if (!NT_SUCCESS(Status))
{
DbgPrint("UnloadDriver Get Keyboard Driver Object Error\n");
return;
} //交换原来的分发函数 // for (nIndex; nIndex < IRP_MJ_MAXIMUM_FUNCTION; nIndex++)
// {
// InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[nIndex], OldDispatchFun[nIndex]);
// }
InterlockedExchangePointer(&KeyBoardDriverObject->MajorFunction[IRP_MJ_READ], OldDIspatchRead);
DbgPrint("Change MajorFunction Successful!\n"); Delay = RtlConvertLongToLargeInteger(* DELAY_ONE_MILLISECOND);
// 延时等待完成
KeDelayExecutionThread(KernelMode, FALSE, &Delay);
ObReferenceObject(KeyBoardDriverObject);
}
//驱动程序入口
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
ULONG i;
NTSTATUS status; UNICODE_STRING uniNtNameString;
//返回kdbclass驱动对象
PDRIVER_OBJECT KbdDriverObject = NULL; KdPrint(("MyAttach\n")); // 初始化一个字符串,就是Kdbclass驱动的名字。
#if DBG
_asm int ;
#endif
RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME);
// 请参照前面打开设备对象的例子。只是这里打开的是驱动对象。
status = ObReferenceObjectByName (
&uniNtNameString,
OBJ_CASE_INSENSITIVE,
NULL,
,
*IoDriverObjectType,
KernelMode,
NULL,
&KbdDriverObject
);
// 如果失败了就直接返回
if(!NT_SUCCESS(status))
{
DbgPrint("MyAttach: Couldn't get the MyTest Device Object %x\n",status);
return( status );
}
else
{
// 这个打开需要解应用。早点解除了免得之后忘记。
//解释为 可能导致DriverObject引用计数加1 } OldDIspatchRead=KbdDriverObject->MajorFunction[IRP_MJ_READ];
InterlockedExchangePointer(&KbdDriverObject->MajorFunction[IRP_MJ_READ],c2pDispatchGeneral);
ObDereferenceObject(KbdDriverObject);
// 卸载函数。
DriverObject->DriverUnload = c2pUnload; return status;
}








