随笔分类 -  Windows内核编程

摘要:有两种方法,一种是以文件句柄的形式,另外一种是通过设备指针调用其它驱动程序。1、以文件句柄形式调用1)应用程序 调用 驱动A 调用 驱动B这种方法类似于在应用程序中调用驱动程序。在应用程序中用CreateFile,ReadFile,CloseHandle来操作相应文件,驱动中用ZwCreateFile,ZwReadFile,Irp结束操作。要注意:ZwCreateFile,如果是同步打开设备,则参... 阅读全文
posted @ 2010-11-16 21:59 浪里飞 阅读(2909) 评论(0) 推荐(0) 编辑
摘要:一般两种方法使用/设置定时器,一种是使用I/O定时器例程,一种是使用DPC例程。1、定时器的实现1)使用I/O定时器例程NTSTATUSIoInitializeTimer(IN PDEVICE_OBJECT DeviceObject,IN PIO_TIMER_ROUTINE TimerRoutine,IN PVOID Context);IoStartTimerIoStopTimer开启定时器后,每... 阅读全文
posted @ 2010-11-14 20:19 浪里飞 阅读(2058) 评论(0) 推荐(0) 编辑
摘要:3、StartIo例程1)系统处理的StartIoStartIo例程能够保证各个并行的IRP顺序执行,即串行化。DDK提供一个内部队列,并将IRP用StartIo例程串行化处理。当设备由忙转入空闲状态时,从队列中抽取一个IRP进行处理,并将状态设为忙。一个新的IRP来时,如果设备为忙,则插入到队列当中,如果为空闲,则直接处理。OS提供kdevice_queue来实现串行化,队列头保存在pDrive... 阅读全文
posted @ 2010-11-09 23:10 浪里飞 阅读(1516) 评论(0) 推荐(0) 编辑
摘要:对设备的任何操作都会转化为IRP请求,而IRP一般都是由操作系统异步发送的。但是有时需要同步来避免逻辑错误。同步方法有:StartIO例程,使用中断服务例程等。1、应用程序对设备的同步异步操作1)同步操作原理大部分IRP是由应用程序的Win32 API发起。这些函数本身就支持同步异步操作。如ReadFile,WriteFile,DeviceIoControl等。 图示 IRP同步操作示意图P250... 阅读全文
posted @ 2010-11-08 23:21 浪里飞 阅读(2269) 评论(0) 推荐(0) 编辑
摘要:4、内核模式下的同步对象用户模式下用句柄来操作同步对象,而内核模式下可以获得同步对象的指针。每种同步对象在内核中均对应一种数据结构。1)等待KeWaitForMultipleObjectsKeWaitForSingleObject如果超时则返回STATUS_TIMEOUT。如果是因为数组中其一个同步对象变为激发态,则函数的返回值减去STATUS_WAIT_0,就是激发的同步对象在数组中的索引号。2... 阅读全文
posted @ 2010-11-07 17:29 浪里飞 阅读(3611) 评论(0) 推荐(2) 编辑
摘要:驱动程序的同步处理可重入,是指函数的执行结果不和执行顺序有关。同步机制很大程度上依赖于中断请求级。IRQ编号设备名称用途IRQ0Tine计算机系统计时器IRQ1KeyBoard键盘IRQ2RedirectI RQ9与IRQ9相接,MPU-401 MDI使用该IRQIRQ3COM2串口设备IRQ4COM1串口设备IRQ5LPT2建议声卡使用该IRQIRQ6FDD软驱传输控制用IRQ7LPT1打印机传... 阅读全文
posted @ 2010-11-07 11:28 浪里飞 阅读(1926) 评论(0) 推荐(0) 编辑
摘要:1、直接读写方式操作系统将用户模式下的缓冲区锁住,然后操作系统将这段缓冲区在内核模式地址再映射一遍。这样,用户模式的缓冲区和内核模式的缓冲区指向的是同一区域的物理地址。操作系统将用户模式的地址锁定后,用内存描述符MDL记录这段内存。MDL 示意图比如mdl->ByteCount就是记录的虚拟内存的大小。可以用几个宏来得到其值。The MmGetMdlByteCount macro retur... 阅读全文
posted @ 2010-11-02 00:56 浪里飞 阅读(1410) 评论(0) 推荐(0) 编辑
摘要:驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的。用户模式下所有对驱动程序的I/O请求,全部由操作系统转化为一个叫做IRP的数据结构,不同的IRP数据会被“派遣”到不同的派遣函数(Dispatch Function)中。1、IRPIRP(I/O request packet)有两个属性,一个是MajorFunction,另外一个是MinorF... 阅读全文
posted @ 2010-10-29 23:14 浪里飞 阅读(1917) 评论(0) 推荐(0) 编辑
摘要:注册表项相当于文件夹,注册表子项子文件夹(类似目录)。1、创建关闭ZwCreateKey示例代码代码2、打开ZwOpenKey3、添加、修改、注册表键值ZwSetValueKey示例代码代码4、查询ZwQueryValueKey来查询注册表项。1)用ZwQueryValueKey获取数据结构的长度。2)分配如此长度的内存。3)再次调用ZwQueryValueKey查询。4)回收内存。示例代码代码5... 阅读全文
posted @ 2010-10-29 00:20 浪里飞 阅读(3774) 评论(0) 推荐(0) 编辑
摘要:1、创建ZwCreateFile注意CreateDisposition参数。代码2、打开ZwOpenFile代码3、获取或修改文件属性ZwSetInformationFileZwQueryInformationFile4、文件的写、读操作ZwWriteFileZwReadFile代码参考:[1] Windows驱动开发详解[2] MSDN 阅读全文
posted @ 2010-10-28 23:57 浪里飞 阅读(1897) 评论(1) 推荐(0) 编辑
摘要:1、字符串 1)两种字符串,一种是char型,记录ansi字符集。每个字符一个字节。以0标志结束。在KdPrint中用%s输出。 宽字符型,wchar_t,描述unicode字符集的字符串,每个字符两个字节,以0标志结束。通过L来体现。在KdPrint中用%S输出。 如CHAR *string = "Hello"; WCHAR *string2 = L"hello"; KdPrint("%s\n"... 阅读全文
posted @ 2010-10-28 23:33 浪里飞 阅读(3665) 评论(4) 推荐(0) 编辑
摘要:1、虚拟地址 Windows的所有程序(ring0,ring3),可以操作的都是虚拟内存。CPU中寄存器CR0一个位PG位来告诉系统是否分页的。1为允许分页。DDK中宏PAGE_SIZE记录着分页大小,一般为4K,4GB的虚拟内存会被分割成1M个单元。 图 物理内存的映射 P120 2、两种模式 4G虚拟地址中,低2G为用户模式,高2G为内核模式。Windows规定用户态程序只能访问用户模式地址... 阅读全文
posted @ 2010-10-27 23:13 浪里飞 阅读(3458) 评论(0) 推荐(0) 编辑
摘要:SOURCES的文件格式: TARGETNAME=drivername , -本参数用于指定生成的设备驱动程序名称(不需后缀名),所产生的文件 -为drivername.sys. TARGETPATH=.\lib -本参数用于指定生成的设备驱动程序所存放的路径.一般采用.\lib. TARGETTYPE=DRIVER -build能够生成许多不同的目标对象,设备驱动程序一般选用DRIVER. IN... 阅读全文
posted @ 2010-10-24 15:38 浪里飞 阅读(866) 评论(0) 推荐(0) 编辑
摘要:1)默认情况下,内核加载器会加载所有的代码部分和全局数据到非分页内存中。而且,加载器是一次加载整个驱动的可执行文件,包括相关的DLL。加载后,内核加载器关闭驱动程序文件,甚至你可以删除当前正在执行的驱动文件。 但是,你可以告诉加载器你希望驱动的哪部分是可分页,所谓可分页,就是可能会被换页出内存(Page out)。可以使用下面的指令来实现: #define ALLOC_PRAGMA #pragma... 阅读全文
posted @ 2010-10-24 15:30 浪里飞 阅读(2942) 评论(0) 推荐(1) 编辑
摘要:在《Windows驱动开发技术详解》书中讲述了如何设定VC以编译驱动程序,不过稍有点麻烦。 在[2,3]中也有用VC设置的方法。不过有点麻烦。 下面,我们用另外一种方法来进行编译: 在[4]官网上下载如下几个文件: ddkwizard_setup_v1.3.0a.exe, ddkbuild_bat.zip, ddkbuild_cmd.zip 不过太慢,我下了,在CSDN上传中[7]。 步骤: 1、... 阅读全文
posted @ 2010-10-24 12:30 浪里飞 阅读(2096) 评论(1) 推荐(0) 编辑
摘要:9、Windows驱动程序的入口函数规定为_DriverEntry@8,所以用C++编写时要用extern。驱动程序中,不能使用编译器运行时函数,甚至C语言中的malloc,C++的new函数都不能用,因为他们在VC中的实现都是调用了Win32 API了。要用的话,必须自己重载new等运算符。大部分运行时函数是通过Win32 API实现的。在内核模式下无法调用用户模式的程序,而用户模式下通过参数审... 阅读全文
posted @ 2010-10-23 23:49 浪里飞 阅读(2313) 评论(0) 推荐(0) 编辑
摘要:一、基本框架 二、基本概念 1、操作系统的主要任务是调度线程,还有一些必要的工作,如:内存管理,进程管理,安全管理和I/O管理,这些部分叫做执行部件。 2、Ring是CPU的概念,而用户/内核模式是操作系统的概念。编写驱动主要为了操作硬件,如访问物理内存,设备端口等。驱动程序相当于内核的补丁,不同硬件设备会有不同的补丁。Windwos中,用户态与内核态切换通过软中断来进行。 3、操作系统分层 W... 阅读全文
posted @ 2010-10-23 23:05 浪里飞 阅读(1264) 评论(0) 推荐(0) 编辑
摘要:10、HOOK SSDT 的实现 SSDT 的全称是System Services Descriptor Table,即系统服务描述符表。这个表的作用是把ring3 的Win32 API 与ring0 的内核API 联系起来。当然SSDT 并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。 通过修改此表的函数地址可以对常用的Windows AP... 阅读全文
posted @ 2010-10-20 22:08 浪里飞 阅读(826) 评论(0) 推荐(0) 编辑
摘要:8、加裁驱动,驱动与设备1)前面我们主要通过Driver Studio和KmdManager。现在了解一下程序加裁。Windows NT式驱动是基于服务方式加载的,可以通过修改注册表内容完成,也可以通过服务相关API完成。设备驱动程序的动态加载主要由服务控制管理程序(Service Control Manager, SCM)系统组件完成,该组件可以启动、停止和控制服务等。具体加裁方法,参见 [1,... 阅读全文
posted @ 2010-10-20 22:01 浪里飞 阅读(2107) 评论(0) 推荐(0) 编辑
摘要:9、驱动程序与应用程序通信1)使用WriteFile通信可以在应用层调用ReadFile 和WriteFile 分别从驱动中读取和写入数据,他们通过两个不同的IRP来传递信息。http://msdn.microsoft.com/en-us/library/ff549427%28VS.85%29.aspx一个例子如下:首先是我们的应用层程序代码:代码另外,还要有:在DriverEntry 中添加一行... 阅读全文
posted @ 2010-10-20 21:48 浪里飞 阅读(1099) 评论(0) 推荐(0) 编辑