能力值:
( LV2,RANK:10 )
|
-
-
2 楼
下面是全部代码
#include<ntddk.h>
#include<ntddkbd.h>
/*类驱动下的端口驱动*/
//声明驱动 符号链接
#define KEYBOARD_DRIVER_NAME L"//Driver//Kbdclass"
//usb
#define USB_DRIVER_NAME L"//Driver//kbdhid"
//Ps2
#define PS2_DRIVER_NAME L"//Driver//i8042prt"
//声明要搜索的回调函数类型
typedef VOID (_stdcall * KEYBOARDCLASSSERVICECALLBACK)(
PDEVICE_OBJECT DeviceObject, //驱动对象
PKEYBOARD_INPUT_DATA InputDataStart, //
PKEYBOARD_INPUT_DATA InputDataEnd,
PULONG InputDataConsumed
);
typedef unsigned char * (PBYTE); //声明 不声明会报错
//声明此函数根据设备名 打开设备对象
NTSTATUS ObReferenceObjectByName(
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE *ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object //OUT
);
extern POBJECT_TYPE *IoDriverObjectType; //声明全局变量
typedef struct _KBD_CALLBACK{
PDEVICE_OBJECT classDriverObject;
KEYBOARDCLASSSERVICECALLBACK serviceCallBack;
}KBD_CALLBACK,*PKBD_CALLBACK;
KBD_CALLBACK gKbdCallBack = {0}; //定义全局变量 来搜索到的回调函数
//新的回调函数
VOID newCallBackFunction(
PDEVICE_OBJECT DeviceObject, //驱动对象
PKEYBOARD_INPUT_DATA InputDataStart, //
PKEYBOARD_INPUT_DATA InputDataEnd,
PULONG InputDataConsumed
){
DbgPrint("keyup %d",InputDataStart->MakeCode);
DbgPrint("keydown %d",InputDataEnd->MakeCode);
}
//寻找回调函数地址
NTSTATUS SearchServiceCallBack(IN PDRIVER_OBJECT DriverObject){
PDRIVER_OBJECT KbdDriverObject = NULL; //返回打开的驱动对象指针
NTSTATUS status = STATUS_SUCCESS; //状态
UNICODE_STRING Kbdname; //保存设备名称
PVOID KbdDriverStart = NULL; //驱动起始地址
ULONG KbdDriverSize = 0; //驱动大小
ULONG i = 0;
PDRIVER_OBJECT UsingDriverObject = NULL; ////打开kbdclass指针
PDEVICE_OBJECT UsingDeviceObject = NULL; //保存找到驱动对象的设备对象
PVOID UsingDeviceExt = NULL; //保存找到设备对象的扩展
UNICODE_STRING UsingKbd;
PDEVICE_OBJECT pTargetDeviceObject = NULL; //用来遍历 kbdclass 下的设备
PBYTE DeviceExt = NULL; //用来存储扩展结构
//打开驱动对象 如果PS2打不开就打开USB的
//全打不开返回错误
RtlInitUnicodeString(&Kbdname,PS2_DRIVER_NAME);
DbgPrint("open PS2 keyboard driver now...");
status = ObReferenceObjectByName(&Kbdname,
OBJ_CASE_INSENSITIVE,
NULL,0,
*IoDriverObjectType,
KernelMode,
0,
&KbdDriverObject
);
//如果打开失败 打开USB的
if(!NT_SUCCESS(status)){
DbgPrint("open USB keyboard driver now...");
RtlInitUnicodeString(&Kbdname,USB_DRIVER_NAME);
status = ObReferenceObjectByName(&Kbdname,
OBJ_CASE_INSENSITIVE,
NULL,0,
*IoDriverObjectType,
KernelMode,
0,
&KbdDriverObject
);
if(!NT_SUCCESS(status)){
DbgPrint("open keyboard driver error");
return STATUS_UNSUCCESSFUL;
}
}else{
DbgPrint("open PS2 keyboard driver success!");
}
//打开成功解除引用对象 -1
ObReferenceObject(KbdDriverObject);
//吧打开驱动对象的指针 赋给UsingDriverObject
UsingDriverObject = KbdDriverObject;
//设备对象
UsingDeviceObject = UsingDriverObject->DeviceObject;
//扩展
UsingDeviceExt = UsingDeviceObject->DeviceExtension;
//找到在Kbdclass回调函数地址
//打开Kbdclass
RtlInitUnicodeString(&UsingKbd,KEYBOARD_DRIVER_NAME);
status = ObReferenceObjectByName(&UsingKbd,
OBJ_CASE_INSENSITIVE,
NULL,0,
*IoDriverObjectType,
KernelMode,
0,
&UsingDriverObject
);
//如果失败返回错误状态
if(!NT_SUCCESS(status)){
DbgPrint("open kbdclass driver error");
return STATUS_UNSUCCESSFUL;
}else{
ObReferenceObject(UsingDriverObject); //引用计数-1
//获取开始位置 以及大小
KbdDriverStart = UsingDriverObject->DriverStart; //驱动起始地址
KbdDriverSize = UsingDriverObject->DriverSize; //驱动大小
}
pTargetDeviceObject = UsingDriverObject->DeviceObject;
//循环遍历
while(pTargetDeviceObject){
DeviceExt = (PBYTE)UsingDeviceExt;
for(;i<4096;i++,DeviceExt+=sizeof(PBYTE)){
PVOID tmp; //临时变量
//如果此处内存不可读或引发分页错误则 跳出
if(!MmIsAddressValid(DeviceExt)){
break;
}
//如果找到了地址 跳出循环
if(gKbdCallBack.classDriverObject && gKbdCallBack.serviceCallBack){
status = STATUS_SUCCESS;
break;
}
//在端口驱动扩展中 找类驱动对象
tmp = *(PVOID*)DeviceExt;
if(tmp ==pTargetDeviceObject){
gKbdCallBack.classDriverObject = (PDEVICE_OBJECT)tmp;
DbgPrint("classObject %8x\n",tmp);
continue;
}
//如果在设备栈 中找到了 位于 Kbdclass 的地址 那么就可认为该地址就为回调函数的地址
if(tmp>KbdDriverStart && tmp<((PBYTE)KbdDriverStart+KbdDriverSize) && MmIsAddressValid(tmp)){
//将这个回调函数记录下来
gKbdCallBack.serviceCallBack = (KEYBOARDCLASSSERVICECALLBACK)tmp;
AddrServiceCallBack = (PVOID*)DeviceExt;
DbgPrint("函数地址 获得成功 %8x",tmp);
}
}
//循环结束遍历下一个设备对象
pTargetDeviceObject = pTargetDeviceObject->NextDevice;
}
//如果都找到了 就替换自己的回调函数
if(AddrServiceCallBack && gKbdCallBack.serviceCallBack){
DbgPrint("hook start ......");
*AddrServiceCallBack = newCallBackFunction;
}
return status;
}
//main
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegPath){
NTSTATUS status;
#if DBG
_asm int 3
#endif
status = SearchServiceCallBack(DriverObject);
return STATUS_SUCCESS;
}
|