第3章代码

// #include #include #define NTSTRSAFE_LIB
#include #define  CPP_MAX_COM_ID 32
#define     DELAY_ONE_MICROSECOND (-10)
#define     DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define     DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
static PDEVICE_OBJECT s_fltobj[CPP_MAX_COM_ID] = {0};
static PDEVICE_OBJECT s_nextobj[CPP_MAX_COM_ID] = {0};
NTSTATUS ccpAttachDevice(
PDRIVER_OBJECT driver
, PDEVICE_OBJECT oldobj
, PDEVICE_OBJECT *fltobj
, PDEVICE_OBJECT *next)
{
NTSTATUS status;
PDEVICE_OBJECT topdev = NULL;
// IoCreateDevice 创建设备对象
// driver 驱动程序对象 , oldobj->DeviceType设备的类型
// fltobj指向接收DEVICE_OBJECT结构体的指针
status = IoCreateDevice (driver, 0, NULL, oldobj->DeviceType, 0, FALSE, fltobj);
if (status != STATUS_SUCCESS)
{
return status;
}
if (oldobj -> Flags & DO_BUFFERED_IO)
{
(*fltobj)->Flags |= DO_BUFFERED_IO;
}
if (oldobj->Flags & DO_DIRECT_IO)
{
(*fltobj)->Flags |= DO_DIRECT_IO;
}
if (oldobj->Flags & FILE_DEVICE_SECURE_OPEN)
{
(*fltobj)->Characteristics |= FILE_DEVICE_SECURE_OPEN;
}
(*fltobj)->Flags |= DO_POWER_PAGABLE;
// 将调用方的设备对象附加到设备对象链中的最高层,并返回之前在设备对象链中最高的设备对象。
// fltobj需要附着的源设备对象, oldobj附着到的目标设备对象
// 把fltobj放到oldobj所在的链的顶端
topdev = IoAttachDeviceToDeviceStack (*fltobj, oldobj);
if (NULL == topdev)
{
// 从系统中删除一个设备对象fltobj
// VOID IoDeleteDevice(
//     _In_ PDEVICE_OBJECT DeviceObject
//     );
//     DeviceObject 要删除的设备对象指针
IoDeleteDevice (*fltobj);
*fltobj = NULL;
status = STATUS_UNSUCCESSFUL;
return status;
}
*next = topdev;
(*fltobj)->Flags = (*fltobj)->Flags & ~DO_DEVICE_INITIALIZING;
return STATUS_SUCCESS;
}
PDEVICE_OBJECT cppOpenCom(ULONG id, NTSTATUS *status)
{
UNICODE_STRING name_str;
static WCHAR name[32] = {0};
PFILE_OBJECT fileobj = NULL;
PDEVICE_OBJECT devobj = NULL;
memset (name, 0, sizeof(WCHAR)*32);
RtlStringCchPrintfW(name, 32, L"\\Device\\Serial%d", id);
RtlInitUnicodeString (&name_str, name);
// 获取命名对象
// IoGetDeviceObjectPointer返回一个指向命名对象设备堆栈顶部的对象指针和
// 相应的文件对象指针
// The IoGetDeviceObjectPointer routine returns a pointer to the top object
// in the named device object's stack and a pointer to the corresponding file object,
// if the requested access to the objects can be granted.
*status = IoGetDeviceObjectPointer(&name_str, FILE_ALL_ACCESS, &fileobj, &devobj);
if (*status == STATUS_SUCCESS)
{
// 解除引用。
// ObDereferenceObject检查给定对象的引用计
// The ObDereferenceObject routine decrements the given object's reference count
// and performs retention checks.
ObDereferenceObject(fileobj);
}
return devobj;
}
void cppAttachAllCom(PDRIVER_OBJECT driver)
{
ULONG i;
PDEVICE_OBJECT com_ob;
NTSTATUS status;
for (i = 0; i < CPP_MAX_COM_ID; ++i)
{
com_ob = cppOpenCom (i, &status);
if (NULL == com_ob)
{
continue;
}
ccpAttachDevice(driver, com_ob, &s_fltobj[i], &s_nextobj[i]);
}
}
NTSTATUS ccpDispatch(PDEVICE_OBJECT device, PIRP irp)
{
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation (irp);
NTSTATUS status;
ULONG i, j;
for (i = 0; i < CPP_MAX_COM_ID; ++i)
{
if (device == s_fltobj[i])
{
if (irpsp->MajorFunction == IRP_MJ_POWER)
{
// The PoStartNextPowerIrp routine signals the power manager that
// the driver is ready to handle the next power IRP.
// (Windows Server 2003, Windows XP, and Windows 2000 only.)
PoStartNextPowerIrp (irp);
// The IoSkipCurrentIrpStackLocation macro modifies the system's
// IO_STACK_LOCATION array pointer, so that when the current
// driver calls the next-lower driver, that driver receives
// the same IO_STACK_LOCATION structure that
// the current driver received.
IoSkipCurrentIrpStackLocation (irp);
// The PoCallDriver routine passes a power IRP to the next-lower
// driver in the device stack.
// (Windows Server 2003, Windows XP, and Windows 2000 only.)
return PoCallDriver (s_nextobj[i], irp);
}
if (irpsp->MajorFunction == IRP_MJ_WRITE)
{
ULONG len = (irpsp->Parameters.Write.Length);
PUCHAR buf = NULL;
if (irp->MdlAddress != NULL)
{
// The MmGetSystemAddressForMdlSafe macro returns a
// nonpaged system-space virtual address for the buffer that
// the specified MDL describes.
buf = (PUCHAR)MmGetSystemAddressForMdlSafe(
irp->MdlAddress, NormalPagePriority);
}
else
{
buf = (PUCHAR)irp->UserBuffer;
}
if (NULL == buf)
{
buf = (PUCHAR)irp->AssociatedIrp.SystemBuffer;
}
for (j = 0; j < len; ++j)
{
DbgPrint("comcap: Send Data: %2x\r\n", buf[j]);
}
}
IoSkipCurrentIrpStackLocation (irp);
// The IoCallDriver routine sends an IRP to the driver associated with
// a specified device object.
// 发送irp给s_nextobj[i]
return IoCallDriver (s_nextobj[i], irp);
}
}
irp->IoStatus.Information = 0;
irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
// The IoCompleteRequest routine indicates that the caller has completed all processing
// for a given I/O request and is returning the given IRP to the I/O manager.
// 调用者已完成所有处理对于一个给定的I / O请求和返回给定的irp到I / O管理器。
IoCompleteRequest(irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
void ccpUnload(PDRIVER_OBJECT drv)
{
ULONG i;
LARGE_INTEGER interval;
for (i = 0; i < CPP_MAX_COM_ID; ++i)
{
if (NULL != s_nextobj[i])
{
// The IoDetachDevice routine releases an attachment between the caller's
// device object and a lower driver's device object.
// 从设备链上删除 s_nextobj[i]
// s_nextobj[i] 下层堆栈上的设备对象
IoDetachDevice (s_nextobj[i]);
}
}
interval.QuadPart = 5*1000*DELAY_ONE_MILLISECOND;
// The KeDelayExecutionThread routine puts the current thread into an alertable or
// nonalertable wait state for a specified interval.
// 延时
KeDelayExecutionThread (KernelMode, FALSE, &interval);
for (i = 0; i < CPP_MAX_COM_ID; ++i)
{
if (NULL != s_fltobj[i])
{
IoDeleteDevice (s_fltobj[i]);
}
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
size_t i;
#if DBG
_asm int 3;
#endif
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
driver->MajorFunction[i] = ccpDispatch;
}
driver->DriverUnload = ccpUnload ;
cppAttachAllCom (driver);
return STATUS_SUCCESS;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

  7. 寒江独钓-Windows内核安全编程笔记-第4章代码

    #ifndef __CTRL2CAP_H__ #define __CTRL2CAP_H__ #pragma once typedef struct _C2P_DEV_EXT { // 结构的大小 UL ...

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

     

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

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

最新文章

  1. mysql 备份压缩数据库_备份压缩mysql 数据库
  2. 基于tensorflow的MNIST手写字识别
  3. python提示错误TypeError: 'dict_keys' object does not support indexing
  4. 制作山寨智能机器人的一些记录 一 * 关于Arduino 以及外围模块的连接及使用...
  5. 2017.10.25
  6. 地图投影系列介绍(三)----地图投影
  7. idea 内存溢出解决方法
  8. Spring精华问答 | Spring 能帮我们做什么?
  9. python多变量拟合_Python曲线将多个参数拟合到多个数据集
  10. 《Essential C++》笔记之设计一个泛型算法(二)
  11. 逸管家:别只共享单车,互联网时代还可以共享人才
  12. CentOS镜像中替换安装镜像的小系统的内核方法
  13. [Book]《云计算核心技术剖析》读书笔记
  14. 蓝桥杯Java组常用算法与技巧
  15. 数据结构面试、数据结构考研复试——常见问题以及回答
  16. CMT2300A 433MHz SUB-1G无线收发芯片
  17. SlideBox 间隔滚动效果
  18. AWS云lamda实时判断IoTCore上传的数据并插入RDS中
  19. 解释什么是啸叫,为什么会发生啸叫,啸叫的为何和如何防止啸叫
  20. HDFS与HBASE的动态节点的扩容(增删)小白级(二)

热门文章

  1. 北京工作居住证的申请条件和可享受的待遇
  2. 如何解决html文档无法复制,职场必备技能:网页文档无法复制,3招教你轻松搞定...
  3. 劝人学医,天打雷劈?给医学新生的 10 条入学建议
  4. 有一种女人,她们并不漂亮,但看上去却很舒服!
  5. 2020安洵杯——EasyCM WriteUP
  6. MySql格式化小数保留小数点后两位
  7. 3D打印鞋或将成为新时尚 Nike也加入
  8. 魔兽世界正式服哪个服务器稳定,魔兽世界正式服什么职业厉害2021
  9. 游戏十连模拟器(html版)
  10. 物联网架构成长之路(35)-利用Netty解析物联网自定义协议