随笔分类 -  驱动

摘要: 阅读全文
posted @ 2016-07-28 22:40 _No.47 阅读(196) 评论(0) 推荐(0)
摘要:驱动中 fltKernel.h报 EPROCESS和PETHREAD重定义异常解决办法 驱动中 fltKernel.h报 EPROCESS和PETHREAD重定义异常解决办法 驱动编写中经常会莫名出现 error C2371: 'PEPROCESS' : redefinition; differen 阅读全文
posted @ 2016-07-27 18:28 _No.47 阅读(374) 评论(0) 推荐(0)
摘要:分层驱动程序概念 分层的目的是将功能复杂的驱动程序分解成多个简单的驱动程序。一般来说,他们是指两个或两个 以上的驱动程序,它们分别创建设备对象,并且形成一个由高到低的设备对象栈。IRP请求一般会被传送到设备栈的最顶层的设备对象,顶层的设备对象可以选择 直接结束IRP请求,也可以选择将IRP请求向下层 阅读全文
posted @ 2016-06-18 11:49 _No.47 阅读(3543) 评论(0) 推荐(1)
摘要:本节介绍“手动”构造各个IRP,然后将IRP传递到相应驱动程序的派遣函数里。 获得设备指针 每个内核中的句柄都会和一个内核对象的指针联系起来。ZwCreateFile内核函数可以通过设备名打开设备句柄,这个设备句柄和一个文件对象的指针关联。IoGetDeviceObjectPointer内核函数可以 阅读全文
posted @ 2016-06-16 16:16 _No.47 阅读(1433) 评论(0) 推荐(0)
摘要:在驱动程序开发中,经常需要一个驱动程序调用另一个驱动程序。例如,虚拟串口转USB设备的驱动程序,这种驱动程序首先创建一个虚拟串口设备,对这个虚拟串口设备的读写请求会转发到一个USB设备上去。这时就需要在虚拟串口驱动程序中调用USB驱动程序。 同步调用方法 本章节假设DriverA是将要被调用的目标驱 阅读全文
posted @ 2016-06-14 20:30 _No.47 阅读(2397) 评论(0) 推荐(0)
摘要:I/O定时器 I/O定时器是DDK提供的一种定时器。它每个1s钟系统会调用一次I/O定时器例程。I/O定时器例程运行在DISPATCH_LEVEL级别,因此在这个例程中不能使用分页内存,否则会引起页故障从而导致系统崩溃。另外I/O定时器是运行在任一线程的,不一定是IRP发起的线程中,因此不能直接使用 阅读全文
posted @ 2016-06-13 11:17 _No.47 阅读(1731) 评论(0) 推荐(0)
摘要:自定义StartIO 系统定义的StartIO队列只能使用一个队列(DDK提供的StartIO内部只有一个队列),这个队列将所有的IRP进行处理化。例如,读、写操作都会混在一起进行串行处理。然而,有时需要读、写分别进行串行化处理。这就需要自定义StartIO例程。当然,程序员需要自己去维护这个IRP 阅读全文
posted @ 2016-06-09 20:22 _No.47 阅读(492) 评论(0) 推荐(0)
摘要:StartIO例程 StartIO例程能够保证各个并行的IRP顺利执行,即串行化。假如有N个线程同时操作串口设备,必须将这些操作排队,然后一一进行处理。如果不做串行处理,当一个操作没有完毕时,新的操作又开始了,这会导致操作的混乱。因此,驱动有必要将并行的请求变成串行的请求,这需要用到队列。 将 转化 阅读全文
posted @ 2016-06-07 16:48 _No.47 阅读(1276) 评论(0) 推荐(0)
摘要:应用程序对设备的同步异步操作: 大部分IRP都是由应用程序的Win32 API函数发起的。这些Win32 API本身就支持同步和异步操作。例如,ReadFile、WriteFile和DeviceIoControl等,它们都有异步和同步两种操作方式。DeviceIoControl的同步操作如图所示: 阅读全文
posted @ 2016-06-01 10:11 _No.47 阅读(2130) 评论(0) 推荐(0)
摘要:中断请求级 中断请求被分为软件中断和硬件中断两种,这些中断都映射成不同级别的中断请求级。每个中断请求都有各自的优先级别,正在运行的线程随时都可以被中断打断,进入到中断处理程序。优先级高的中断来临时,处在优先级低的中断处理程序,也会被打断,进入到更高级别的中断处理函数。 Windows规定了32个中断 阅读全文
posted @ 2016-05-30 17:22 _No.47 阅读(940) 评论(0) 推荐(0)
摘要:缓冲区方式读写操作 设置缓冲区读写方式: 读写操作一般是由ReadFile和WriteFile函数引起的,这里先以WriteFile函数为例进行介绍。WriteFile要求用户提供一段缓冲区,并且说明缓冲区的大小,然后WriteFile将这段内存的数据传入到驱动程序中。这种方法,操作系统将应用程序提 阅读全文
posted @ 2016-05-26 17:59 _No.47 阅读(5831) 评论(0) 推荐(0)
摘要:驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的。用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构,不同的IRP数据会被“派遣”到不同的派遣函数中。 IRP与派遣函数 IRP的全称是输入输出请求包。 其部分结构如下: 用图表示数据结构 阅读全文
posted @ 2016-05-26 11:26 _No.47 阅读(1831) 评论(0) 推荐(0)
摘要:内核模式下字符串操作 ANSI_STRING和UNICODE_STRING分别定义如下: 以UnicodeString类型对象进行初始化为例,代码如下: 输出: 进行复制字符串操作,代码如下: 输出: 但是如果这里改为: 加载驱动运行就会蓝屏。Why?其实,RltFreeUnicodeString是 阅读全文
posted @ 2016-05-24 17:50 _No.47 阅读(766) 评论(0) 推荐(0)
摘要:虚拟内存地址 Windows所有的程序(Ring0和Ring3层)可以操作的都是虚拟内存。有一部分单元会和物理内存对应起来,但并非一一对应,多个虚拟内存页可以映射同一个物理内存页。还有一部分单元会被映射成磁盘上的文件,并标记为脏的。读取这段虚拟内存的时候,系统会发出一个异常,此时会出发异常处理函数, 阅读全文
posted @ 2016-05-23 21:55 _No.47 阅读(1083) 评论(0) 推荐(0)
摘要:驱动对象 每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候被内核中的对象管理程序所创建的。驱动对象用DRIVER_OBJECT数据结构表示,它作为驱动的一个实例被内核加载,并且内核对一个驱动只加载一个实例。确切的说,是由内核中的I/O管理器负责加载的。驱动程序需要在Driv 阅读全文
posted @ 2016-05-22 11:36 _No.47 阅读(5899) 评论(0) 推荐(0)
摘要:之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似: 设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager,SCM)系统组件完成。加载和卸载NT驱动分为四个步骤: 为NT驱动创建新的服 阅读全文
posted @ 2016-05-21 09:48 _No.47 阅读(2262) 评论(0) 推荐(0)
摘要:编写如下代码: 运行会报错: 这里的原因是有没有引用到的形参,需要添加如下代码即可: 记得在系统启动时按F8禁用掉数字签名: 将编译好的驱动拖入虚拟机,以管理员身份运行DbgView捕捉内核态输出数据,以管理员身份运行InstDrv以加载驱动,我们就可以看到启动和停止时,DriverEntry和Dr 阅读全文
posted @ 2016-05-19 22:41 _No.47 阅读(1345) 评论(0) 推荐(0)
摘要:LoadDriver 首先通过OpenSCManager打开服务会话管理器,然后利用CreateService创建驱动所对应的服务,这个函数很重要,它涉及到了驱动的安装。它会在注册表的对应位置创建一个服务名。它相当于InstDrv中的安装按钮: 服务会创建在注册表位置:HKEY_LOCAL_MACH 阅读全文
posted @ 2016-04-04 17:53 _No.47 阅读(890) 评论(0) 推荐(0)
摘要:概述 API在某个头文件中定义,被封装在某个DLL中,而这个DLL会进一步被封装在ntdll.dll中(它里面的API叫native api),比如,ReadFile在ntdll.dll中就对应着ntReadFile;然后这个API会通过sysenter的方式进入内核层。 那么,比如对于Create 阅读全文
posted @ 2016-04-03 12:20 _No.47 阅读(776) 评论(0) 推荐(0)