#ifndef __CTRL2CAP_H__
#define __CTRL2CAP_H__
#pragma once
typedef struct _C2P_DEV_EXT
{
// 结构的大小
ULONG NodeSize;
// 过滤设备对象
PDEVICE_OBJECT pFilterDeviceObject;
// 同时调用时的保护锁
KSPIN_LOCK IoRequestsSpinLock;
// 进程间同步处理
KEVENT IoInProgressEvent;
// 绑定的设备对象
PDEVICE_OBJECT TargetDeviceObject;
// 绑定前底层设备对象
PDEVICE_OBJECT LowerDeviceObject;
} C2P_DEV_EXT, *PC2P_DEV_EXT;
// Kbdclass驱动的名字
#define KBD_DRIVER_NAME  L"\\Driver\\kbdclass"
#define  DELAY_ONE_MICROSECOND  (-10)
#define  DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define  DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
NTSTATUS c2pDevExtInit(IN PC2P_DEV_EXT devExt
, IN PDEVICE_OBJECT pFilterDeviceObject
, IN PDEVICE_OBJECT pTargetDeviceObject
, IN PDEVICE_OBJECT pLowerDeviceObject);
// 这个函数是事实存在的,只是文档中没有公开。声明一下
// 就可以直接使用了。
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);
NTSTATUS c2pPower(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp);
NTSTATUS c2pDispatchRead(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp);
NTSTATUS c2pReadComplete(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
, IN PVOID Context);
NTSTATUS c2pPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp);
VOID c2pDetach(IN PDEVICE_OBJECT pDeviceObject);
VOID c2pUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS c2pDevExtInit(IN PC2P_DEV_EXT devExt
, IN PDEVICE_OBJECT pFilterDeviceObject
, IN PDEVICE_OBJECT pTargetDeviceObject
, IN PDEVICE_OBJECT pLowerDeviceObject);
// 打开驱动对象Kbdclass,然后绑定它下面的所有的设备:
NTSTATUS c2pAttachDevices(IN PDRIVER_OBJECT DriverObject
, IN PUNICODE_STRING RegistryPath);
#endif // __CTRL2CAP_H__#include #include "ctrl2cap.h"
// IoDriverObjectType
extern POBJECT_TYPE *IoDriverObjectType;
ULONG gC2pKeyCount = 0;
PDRIVER_OBJECT gDriverObject = NULL;
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
ULONG i;
NTSTATUS status;
KdPrint(("MyAttach: enter DriverEntry!\n"));
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = c2pDispatchGeneral;
}
DriverObject->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;
DriverObject->MajorFunction[IRP_MJ_POWER] = c2pPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = c2pPnp;
DriverObject->DriverUnload = c2pUnload;
gDriverObject = DriverObject;
status = c2pAttachDevices (DriverObject, RegistryPath);
return status;
}
NTSTATUS c2pDispatchGeneral(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp)
{
KdPrint(("Other Dispath!"));
IoSkipCurrentIrpStackLocation (Irp);
return IoCallDriver(((PC2P_DEV_EXT)DeviceObject->DeviceExtension)->LowerDeviceObject, Irp);
}
NTSTATUS c2pDispatchRead(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
KeInitializeEvent (&waitEvent, NotificationEvent, FALSE);
if (Irp->CurrentLocation == 1)
{
ULONG Returnedinformation = 0;
KdPrint(("Dispatch encountered bogus current location \n"));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = Returnedinformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
gC2pKeyCount++;
devExt = (PC2P_DEV_EXT)DeviceObject->DeviceExtension;
currentIrpStack = IoGetCurrentIrpStackLocation (Irp);
IoCopyCurrentIrpStackLocationToNext (Irp);
IoSetCompletionRoutine (Irp, c2pReadComplete, DeviceObject, TRUE, TRUE, TRUE);
return IoCallDriver(devExt->LowerDeviceObject, Irp);
}
NTSTATUS c2pPower(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp)
{
PC2P_DEV_EXT devExt;
devExt = (PC2P_DEV_EXT)DeviceObject->DeviceExtension;
PoStartNextPowerIrp (Irp);
IoSkipCurrentIrpStackLocation (Irp);
return PoCallDriver (devExt->LowerDeviceObject, Irp);
}
NTSTATUS c2pPnp(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp)
{
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event;
devExt = (PC2P_DEV_EXT)DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("IRP_MN_REMOVE_DEVICE\n"));
IoSkipCurrentIrpStackLocation (Irp);
IoCallDriver(devExt->LowerDeviceObject, Irp);
IoDetachDevice (devExt->LowerDeviceObject);
IoDeleteDevice (DeviceObject);
return STATUS_SUCCESS;
default:
// 对于其他类型的IRP,全部都直接下发即可。
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(devExt->LowerDeviceObject, Irp);
}
return status;
}
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"));
return status;
}
else
{
// 这个打开需要解引用。早点解除了免得之后忘记。
ObDereferenceObject(DriverObject);
}
// 设备链中的第一个设备
pTargetDeviceObject = KbdDriverObject->DeviceObject;
// 遍历这个设备链
while (pTargetDeviceObject)
{
// 生成一个过滤设备
status = IoCreateDevice (DriverObject
, sizeof(C2P_DEV_EXT)
, NULL
, pTargetDeviceObject->DeviceType
, pTargetDeviceObject->Characteristics
, FALSE
, &pFilterDeviceObject);
// 如果失败了就直接退出。
if (!NT_SUCCESS(status))
{
KdPrint(("MyAttach: couldn't create the MyFilter Filter Device Object!\n"));
return status;
}
// 绑定。pLowerDeviceObject是绑定之后得到的下一个设备。
// 也就是所谓真实设备。
pLowerDeviceObject = IoAttachDeviceToDeviceStack (pFilterDeviceObject, pTargetDeviceObject);
// 如果绑定失败了,放弃之前的操作,退出。
if (!pLowerDeviceObject)
{
KdPrint(("MyAttach: couldn't attach to MyTest Device Object!\n"));
IoDeleteDevice(pFilterDeviceObject);
pFilterDeviceObject = NULL;
return status;
}
// 取到设备扩展
devExt = (PC2P_DEV_EXT)(pFilterDeviceObject->DeviceExtension);
c2pDevExtInit (devExt
, pFilterDeviceObject
, pTargetDeviceObject
, pLowerDeviceObject);
pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType;
pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics;
pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize+1;
pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags
& (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
pTargetDeviceObject = pTargetDeviceObject->NextDevice;
}
return status;
}
NTSTATUS c2pDevExtInit(IN PC2P_DEV_EXT devExt
, IN PDEVICE_OBJECT pFilterDeviceObject
, IN PDEVICE_OBJECT pTargetDeviceObject
, IN PDEVICE_OBJECT pLowerDeviceObject)
{
memset (devExt, 0, sizeof(C2P_DEV_EXT));
devExt->NodeSize = sizeof(C2P_DEV_EXT);
devExt->pFilterDeviceObject = pFilterDeviceObject;
devExt->TargetDeviceObject = pTargetDeviceObject;
devExt->LowerDeviceObject = pLowerDeviceObject;
KeInitializeSpinLock (&(devExt->IoRequestsSpinLock));
KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
return STATUS_SUCCESS;
}
// WIN7卸载的时候会导致电脑蓝屏重启。新手不知道什么原因。
VOID c2pUnload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PC2P_DEV_EXT devExt;
LARGE_INTEGER lDelay;
PRKTHREAD Currentthread;
lDelay = RtlConvertLongToLargeInteger (100* DELAY_ONE_MILLISECOND);
Currentthread = KeGetCurrentThread ();
KeSetPriorityThread (Currentthread, LOW_REALTIME_PRIORITY);
UNREFERENCED_PARAMETER(DeviceObject);
KdPrint(("DriverEntry unLoading...\n"));
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject)
{
c2pDetach(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
ASSERT(NULL == DriverObject->DeviceObject);
while (gC2pKeyCount)
{
KeDelayExecutionThread (KernelMode, FALSE, &lDelay);
}
KdPrint(("DriverEntry unLoad Ok!\n"));
return ;
}
NTSTATUS c2pReadComplete(IN PDEVICE_OBJECT DeviceObject
, IN PIRP Irp
, IN PVOID Context)
{
PIO_STACK_LOCATION Irpsp;
ULONG buf_len = 0;
PUCHAR buf = NULL;
size_t i;
Irpsp = IoGetCurrentIrpStackLocation (Irp);
if (NT_SUCCESS(Irp->IoStatus.Status))
{
buf = Irp->AssociatedIrp.SystemBuffer;
buf_len = Irp->IoStatus.Information;
for (i =0; i < buf_len; ++i)
{
DbgPrint("ctrl2cap: %2x\r\n", buf[i]);
}
}
gC2pKeyCount--;
if (Irp->PendingReturned)
{
IoMarkIrpPending (Irp);
}
return Irp->IoStatus.Status;
}
VOID c2pDetach(IN PDEVICE_OBJECT pDeviceObject)
{
PC2P_DEV_EXT devExt;
BOOLEAN NoRequestsOutstanding = FALSE;
devExt = (PC2P_DEV_EXT)pDeviceObject->DeviceExtension;
__try
{
__try
{
IoDetachDevice(devExt->TargetDeviceObject);
devExt->TargetDeviceObject = NULL;
IoDeleteDevice(pDeviceObject);
devExt->pFilterDeviceObject = NULL;
DbgPrint(("Detach Finished\n"));
}
__except (EXCEPTION_EXECUTE_HANDLER){}
}
__finally{}
return;
}!IF 0
Copyright (C) Microsoft Corporation, 1997 - 1999
Module Name:
sources.
!ENDIF
TARGETNAME=ctrl2cap
TARGETPATH=obj
TARGETTYPE=DRIVER
SOURCES =ctrl2cap.c!IF 0
Copyright (C) Microsoft Corporation, 1997 - 1998
Module 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

寒江独钓-Windows内核安全编程笔记-第4章代码相关推荐

  1. 寒江独钓-Windows内核安全编程笔记-第3章代码和笔记

    第3章代码 // #include #include #define NTSTRSAFE_LIB #include #define CPP_MAX_COM_ID 32 #define DELAY_ON ...

  2. 寒江独钓windows 内核安全编程学习笔记

    寒江独钓windows 内核安全编程学习笔记 本博客记录自己的学习过程,如有侵犯或者打扰请告知. 由于项目的需求,第一次接触到驱动程序.开始学习了寒江大神的的内核安全编程.小白一个,第一章就遇到了问题 ...

  3. 驱动开发专家解读 寒江独钓 Windows内核安全编程

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 驱动开发 ...

  4. 寒江独钓-Windows内核安全编程(完整版).pdf

    寒江独钓-Windows内核安全编程(完整版).pdf   编写Windows内核程序,就意味着这个程序可以执行任意指令,可以访问计算机所有的软件.硬件资源.因此,稍有不慎就有可能将系统变得不稳定.W ...

  5. 寒江独钓 Windows内核安全编程

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! < ...

  6. 寒江独钓——Windows内核安全编程

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow <寒江独钓- ...

  7. 寒江独钓:Windows内核安全编程(china-pub到货首发)

    寒江独钓:Windows内核安全编程(china-pub到货首发) [作 者]谭文;杨潇;邵坚磊等 [丛 书 名] 驱网核心技术丛书  [出 版 社] 电子工业出版社     [书 号] 978712 ...

  8. 《寒江独钓windows内核安全编程》学习笔记之一

     

  9. 寒江独钓Windows内核安全编程__一个简单的Windows串口过滤驱动程序的开发

    在Windows系统上与安全软件相关的驱动开发过程中,"过滤(filter)"是极其重要的一个概念.过滤是在不影响上层和下层接口的情况下,在Windows系统内核中加入新的层,从而 ...

最新文章

  1. 基于XFS的NAS数据恢复可以做了
  2. php7+apache2.4配置
  3. 011 数据结构逆向—二叉树
  4. Java 动态代理介绍及用法
  5. ImageUploadAssist--DATA
  6. 《revolution in the valley》读后随笔--Steve jobs与Macintosh
  7. 删除WinXP下打开最近文档后,产生的无效快捷方式
  8. 【Arthas】Arthas Command处理流程
  9. UI设计为什么要使用Figma?
  10. Mandelbrot vs Julia
  11. element的form表单中如何一行显示多el-form-item标签
  12. Cloudera Manager 安装 CDH5.x 心得
  13. c语言写识别电压的程序,PIC单片机C语言编程实例——交流电压测量
  14. GitHub使用教程详解(上)——官网操作指南[翻译]
  15. fcntl函数的SET用法
  16. WEB系统中集成控制扫描仪解决方案
  17. 小米手机android程序闪退,告诉大家小米手机应用闪退的解决方法,不需要修复...
  18. ubuntu 22.04 网易云音乐安装
  19. MapReduce之Partition分区实例操作
  20. FTP服务器、部署YUM仓库与NFS共享服务

热门文章

  1. iOS —label自动换行
  2. matplotlib修改背景颜色和插入背景图片
  3. Emscripten 单词_这300个单词务必让孩子在三年级前搞定
  4. QModel-BIM-Revit模型轻量化产品介绍
  5. 30个Python最佳实践和技巧,你值得拥有~
  6. 医学生学计算机建议,医学生计算机能力的培养
  7. 实体店收银系统怎么做管理和营销?
  8. 2022-2028全球与中国汽车软内饰材料市场现状及未来发展趋势
  9. 从创建服务器到搭建一台内网穿透服务器
  10. win10睡眠状态下唤醒花屏