博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
XPsp3键盘设备链/栈信息_01_Code
阅读量:6463 次
发布时间:2019-06-23

本文共 8194 字,大约阅读时间需要 27 分钟。

WDK: GRMWDK_EN_7600_1.ISO

XP SP3 : zh-hans_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-74070.iso

 

1、zcFirst.c

#include 
// Kbdclass驱动的名字#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass"// 这个函数是事实存在的,只是文档中没有公开。声明一下// 就可以直接使用了。NTSTATUSObReferenceObjectByName( PUNICODE_STRING ObjectName, ULONG Attributes, PACCESS_STATE AccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PVOID ParseContext, PVOID *Object );NTSTATUS ObQueryNameString( IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength);extern POBJECT_TYPE IoDriverObjectType; // ZC: 这个变量是定义在WDK的头文件中的?(wdm.h中?)ULONG g_C2pKeyCount = 0;PDRIVER_OBJECT g_DriverObject = NULL;// ZC: 得到设备对象_pDeviceObject的 某些信息NTSTATUS ShowInfo_DeviceObject(PDEVICE_OBJECT _pDeviceObject){ NTSTATUS status = 0; ULONG ulRtnLen = 0; KdPrint(("_pDeviceObject->DeviceType : 0x%08X, _pDeviceObject->Characteristics : 0x%08X\n", _pDeviceObject->DeviceType, _pDeviceObject->Characteristics)); KdPrint(( "STATUS_INFO_LENGTH_MISMATCH : 0x%08X\n", STATUS_INFO_LENGTH_MISMATCH )); // ZC: 显示设备对象的名称 status = ObQueryNameString(_pDeviceObject, NULL, 0, &ulRtnLen); if (status == STATUS_INFO_LENGTH_MISMATCH) { POBJECT_NAME_INFORMATION pObjNameInfo = NULL; KdPrint(( "ObQueryNameString - ulRtnLen(1) : 0x%08X\n", ulRtnLen )); pObjNameInfo = (POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool, ulRtnLen); status = ObQueryNameString(_pDeviceObject, pObjNameInfo, ulRtnLen, &ulRtnLen); if (status == STATUS_SUCCESS) { //KdPrint(( "ObQueryNameString - ulRtnLen(2) : 0x%08X\n", ulRtnLen )); if (pObjNameInfo->Name.Length > 0) KdPrint(( "ObQueryNameString - objNameInfo : %wZ\n", &(pObjNameInfo->Name) )); else KdPrint(( "ObQueryNameString - objNameInfo is empty .\n" )); } else { KdPrint(( "ObQueryNameString failed : 0x%08X\n", status )); } ExFreePool(pObjNameInfo); } return status;}// ZC: 遍历设备栈// ZC: 输入参数_pDeviceObject : 设备栈中的一个 设备对象的指针 (这个设备对象 不一定是位于 设备栈中的哪个位置)NTSTATUS EnumDeviceStack(PDEVICE_OBJECT _pDeviceObject){ NTSTATUS status = 0; PDEVICE_OBJECT pDeviceObject = _pDeviceObject; int iIdxStack = 0; // (1)、不管 _pDeviceObject位于设备栈的哪个位置,往上找到设备栈中的第一个设备对象 while (pDeviceObject->AttachedDevice != NULL) { pDeviceObject = pDeviceObject->AttachedDevice; } // (2)、从 设备栈中的第一个设备对象 开始,往下遍历 所有 设备对象 while (TRUE) { PDEVICE_OBJECT *ppDevObj_AttachedTo = NULL; PDEVOBJ_EXTENSION pDevObjExt = NULL; KdPrint(( "Stack[%d] -- message begin :\n", iIdxStack )); iIdxStack ++; status = ShowInfo_DeviceObject(pDeviceObject); if (! NT_SUCCESS(status)) break; pDevObjExt = pDeviceObject->DeviceObjectExtension; if (pDevObjExt == NULL) break; KdPrint(( "pDevObjExt->Size : 0x%08X\n", pDevObjExt->Size )); KdPrint(( "pDevObjExt->Type : 0x%08X\n", pDevObjExt->Type )); //KdPrint(( "&DeviceObject : 0x%08X, 0x%08X\n", pDeviceObject, pDevObjExt->DeviceObject )); //{ // PDEVICE_OBJECT * pp = (PDEVICE_OBJECT*)((unsigned long)pDevObjExt + 0x4); // KdPrint(( "0x%08X, 0x%08X\n", pp, (*pp) )); //} KdPrint(( "Stack[%d] -- message end .\n\n", iIdxStack ));//0x018 // ZC: 往下遍历 // ZC: 下面的运算是 根据WinDBG加载过符号表之后执行命令“dt _DEVOBJ_EXTENSION”得到的运算方式。 // ZC: 可能不同的Windows版本会有差异,要注意 ppDevObj_AttachedTo = (PDEVICE_OBJECT*)((unsigned long)pDevObjExt + 0x18); if ( (*ppDevObj_AttachedTo) != NULL ) pDeviceObject = (*ppDevObj_AttachedTo); else break; } return status;}// ZC: 遍历设备链// ZC: 传入参数 _pDeviceObject : 1个驱动程序(驱动对象)中的 设备链中的 第1个设备对象 的指针NTSTATUS EnumDeviceChain(PDEVICE_OBJECT _pDeviceObject){ NTSTATUS status = 0; int iIdxChain = 0; // 这是设备链中的第一个设备 PDEVICE_OBJECT pTargetDeviceObject = _pDeviceObject; // 现在开始遍历这个设备链 while (pTargetDeviceObject) { KdPrint(( "Chain[%d] :\n", iIdxChain )); iIdxChain ++; status = EnumDeviceStack(pTargetDeviceObject); if (! NT_SUCCESS(status)) break; //next device pTargetDeviceObject = pTargetDeviceObject->NextDevice; }// while return status;}// 这个函数经过改造。能打开驱动对象Kbdclass,然后绑定// 它下面的所有的设备:NTSTATUS c2pAttachDevices( IN PDRIVER_OBJECT _DriverObject, IN PUNICODE_STRING _RegistryPath){ NTSTATUS status = 0; UNICODE_STRING uniNtNameString; //PC2P_DEV_EXT devExt; PDEVICE_OBJECT pFilterDeviceObject = NULL; PDEVICE_OBJECT pTargetDeviceObject = NULL; PDEVICE_OBJECT pLowerDeviceObject = NULL; PDRIVER_OBJECT KbdDriverObject = NULL; KdPrint(("MyAttach\n")); // 初始化一个字符串,就是Kdbclass驱动的名字。 RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); // 请参照前面打开设备对象的例子。只是这里打开的是驱动对象。 status = ObReferenceObjectByName ( &uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &KbdDriverObject ); // 如果失败了就直接返回 if(! NT_SUCCESS(status)) { KdPrint(("MyAttach: Couldn't get the MyTest Device Object\n")); KdPrint(("ObReferenceObjectByName return : 0x%08X\n", status)); return( status ); } else { // 这个打开需要解应用。早点解除了免得之后忘记。 ObDereferenceObject(_DriverObject); } status = EnumDeviceChain(KbdDriverObject->DeviceObject); return status; }// 提供一个Unload函数只是为了 (ZC: 动态卸载)VOID DriverUnload(PDRIVER_OBJECT _DriverObject){ // 但是实际上我们什么都不做,只打印一句话: DbgPrint("zcFirst: Our driver is unloading…\n");}NTSTATUS DriverEntry( IN PDRIVER_OBJECT _DriverObject, IN PUNICODE_STRING _RegistryPath ) { ULONG i; NTSTATUS status = STATUS_SUCCESS; KdPrint (("zcFirst.SYS: entering DriverEntry\n")); /* // 填写所有的分发函数的指针 for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = c2pDispatchGeneral; } // 单独的填写一个Read分发函数。因为要的过滤就是读取来的按键信息 // 其他的都不重要。这个分发函数单独写。 DriverObject->MajorFunction[IRP_MJ_READ] = c2pDispatchRead; // 单独的填写一个IRP_MJ_POWER函数。这是因为这类请求中间要调用 // 一个PoCallDriver和一个PoStartNextPowerIrp,比较特殊。 DriverObject->MajorFunction [IRP_MJ_POWER] = c2pPower; // 我们想知道什么时候一个我们绑定过的设备被卸载了(比如从机器上 // 被拔掉了?)所以专门写一个PNP(即插即用)分发函数 DriverObject->MajorFunction [IRP_MJ_PNP] = c2pPnP; */ // 卸载函数。 _DriverObject->DriverUnload = DriverUnload;//c2pUnload; // gDriverObject = DriverObject; KdPrint(("zcFirst.sys _DriverObject : 0x%08X\n", _DriverObject));#if DBG //_asm int 3#endif // 绑定所有键盘设备 status = c2pAttachDevices(_DriverObject, _RegistryPath); return status; }

 

2、makefile

!IF 0Copyright (C) Microsoft Corporation, 1997 - 1998Module Name:    makefile.!ENDIF## DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source# file to this component.  This file merely indirects to the real make file# that is shared by all the components of Windows NT### if building in a DDK environment#!IF defined(DDK_TARGET_OS)## ensure that said build environment is at least Windows XP# 0x500 == Windows 2000# 0x501 == Windows XP# 0x502 == Windows .NET#!    IF defined(_NT_TARGET_VERSION) && $(_NT_TARGET_VERSION)>=0x501!        INCLUDE $(NTMAKEENV)\makefile.def!    ELSE!        message BUILDMSG: Warning : The sample "$(MAKEDIR)" is not valid for the current OS target.!    ENDIF!ELSE## not a DDK environment, probably RAZZLE, so build#!    INCLUDE $(NTMAKEENV)\makefile.def!ENDIF

 

3、source

!IF 0Copyright (C) Microsoft Corporation, 1997 - 1999Module Name:    sources.!ENDIFTARGETNAME=zcFirstTARGETPATH=objTARGETTYPE=DRIVERSOURCES =zcFirst.c

 

4、

5、

 

转载于:https://www.cnblogs.com/DriverSkill/p/6197338.html

你可能感兴趣的文章
迅速学会PHP加密解密技巧
查看>>
C++ 开源库
查看>>
公用技术——设计模式24——空对象模式——待补充
查看>>
mysql 分区
查看>>
http-server让你在任何目录下都可以创建web服务
查看>>
thinkphp 关联模型 注意点
查看>>
gradle 学习
查看>>
ECharts
查看>>
无阻塞加载外部js(动态脚本元素,XMLHttpRequest注入,LazyLoad)
查看>>
IMU误差模型与校准
查看>>
Android二维码扫描、生成
查看>>
查找图标搜索引擎
查看>>
JVM的年轻代GC过程
查看>>
小峰servlet/jsp(6)jstl核心标签库
查看>>
你觉得自己厉害在哪里
查看>>
日期时间工具类
查看>>
五、坐标的概念以及依赖管理
查看>>
zw版【转发·台湾nvp系列Delphi例程】HALCON SetComprise2
查看>>
洛谷P1279 字串距离
查看>>
Bzoj3270 博物馆
查看>>