windows驱动学习_Second
来源:互联网 发布:网络银行办理 编辑:程序博客网 时间:2024/06/05 05:14
windows驱动学习_Second
一.内核空间和用户空间
1.在单个进程内的编程特点:
(1)可以自由使用通用寄存器,不用关心这些寄存器被其他进程修改。不同进程看似各自拥有一套通用寄存器。
(2)原则上可以自由使用0-N范围内的内存空间,N的大小取决于操作系统的位数,每个进程的用户空间内存是隔离的。
(3)通过操作系统约定的方式与其他进程共享其他资源。
因此,在单个进程内编程只需要定义和使用本进程所需要的资源,并编写代码操作这些资源,不需要关心其他进程。
2.进程的空间实际上被分成两部分。一部分供进程独立使用,称为用户空间;另一部分容纳操作系统的内核,称为内核空间或称为系统空间。
3.用户空间是各个进程隔离的,但是内核空间是共享的。
4.内核空间是收到硬件保护的,比如x86架构下R0层(Ring 0)的代码才可以访问内核空间,普通应用程序编译出来之后都运行的R3层,R3层的代码要调用R0层的功能时,一般通过操作系统提供的一个入口来实现。这样应用程序既可以调用操作系统内核中提供的功能,又不至于得到随意修改内核的权利。
5.内核模块位于内核空间,而内核空间又被所有的进程共享。因此内核模块实际上是位于任何一个进程空间中。但是任意一段代码的任意一次执行,一定是位于某个进程空间中的。这个进程是哪个可以通过PsGetCurrentProcessId函数能获得当前进程的进程号。
二.数据类型
1.使用宏NT_SUCCESS()可以判断一个返回值是否成功,如果成功,毫无疑问返回STATUS_SUCESS。(返回值定义存在ntstatus.h中)。
2.UNICODE_STRING是宽字符,双字节的,可直接用DbgPrint打印,用%wZ。
三.重要的数据结构
1.驱动对象
typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; // // The following links all of the devices created by a single driver // together on a list, and the Flags word provides an extensible flag // location for driver objects. // PDEVICE_OBJECT DeviceObject; ULONG Flags; // // The following section describes where the driver is loaded. The count // field is used to count the number of times the driver has had its // registered reinitialization routine invoked. // PVOID DriverStart; ULONG DriverSize; PVOID DriverSection; PDRIVER_EXTENSION DriverExtension; // // The driver name field is used by the error log thread // determine the name of the driver that an I/O request is/was bound. // UNICODE_STRING DriverName; // // The following section is for registry support. Thise is a pointer // to the path to the hardware information in the registry // PUNICODE_STRING HardwareDatabase; // // The following section contains the optional pointer to an array of // alternate entry points to a driver for "fast I/O" support. Fast I/O // is performed by invoking the driver routine directly with separate // parameters, rather than using the standard IRP call mechanism. Note // that these functions may only be used for synchronous I/O, and when // the file is cached. // PFAST_IO_DISPATCH FastIoDispatch; // // The following section describes the entry points to this particular // driver. Note that the major function dispatch table must be the last // field in the object so that it remains extensible. // PDRIVER_INITIALIZE DriverInit; PDRIVER_STARTIO DriverStartIo; PDRIVER_UNLOAD DriverUnload; PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION + 1];} DRIVER_OBJECT;typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;
和编写一个应用程序,windows直接从main()函数开始执行来生成一个进程不同,内核模块并不生成一个进程,只写一组回调函数让windows来调用,而且这组回调函数必须符合windows内核规定。如上述结构体中,这一组回调函数包括“普通分发函数” MajorFunction和“快速分发函数” FastIoDispatch,这些函数用来处理和发送给这个内核模块的请求。
2.设备对象
typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT { CSHORT Type; USHORT Size; LONG ReferenceCount; struct _DRIVER_OBJECT *DriverObject; struct _DEVICE_OBJECT *NextDevice; struct _DEVICE_OBJECT *AttachedDevice; struct _IRP *CurrentIrp; PIO_TIMER Timer; ULONG Flags; // See above: DO_... ULONG Characteristics; // See ntioapi: FILE_... __volatile PVPB Vpb; PVOID DeviceExtension; DEVICE_TYPE DeviceType; CCHAR StackSize; union { LIST_ENTRY ListEntry; WAIT_CONTEXT_BLOCK Wcb; } Queue; ULONG AlignmentRequirement; KDEVICE_QUEUE DeviceQueue; KDPC Dpc; // // The following field is for exclusive use by the filesystem to keep // track of the number of Fsp threads currently using the device // ULONG ActiveThreadCount; PSECURITY_DESCRIPTOR SecurityDescriptor; KEVENT DeviceLock; USHORT SectorSize; USHORT Spare1; struct _DEVOBJ_EXTENSION *DeviceObjectExtension; PVOID Reserved;} DEVICE_OBJECT;
在内核世界里,大部分“消息”都以请求IRP的方式传递,而设备对象是唯一可以接受请求的实体,任何一个请求都是发送给某个设备对象的。
四.请求
大部分请求以IRP的形式发送,IRP是一个内核数据结构,这个结构表示无数种实际请求。一个IRP往往要传递n个设备才能得以完成,在传递过程中,有可能会有一些“中间变换”,导致请求的参数变化,为了保存这种参数变化,给每次“中转”都留一个“栈空间”,用来保存中间参数。
五.函数
内核中printf、scanf及fopen、fclose、fwrite、fread、malloc、free、strdup这些函数无法使用,因为在内核没有控制台,而且读\写文件也不那么轻松。但是sprintf、strlen、strcpy、wcslen、wcscpy、memcpy、memset都是可以的。
六.代码的中断级
Passive级和Dispatch级
七.特殊代码
#pragma alloc_text 用来指定某个函数的可执行代码在编译出来后再sys文件中的位置;INIT节的特点是在初始化完毕后就被释放,不再占用内存空间;PAGE节的特点是位于可以进行分页交换的内存空间,这些空间在内存紧张时可以被交换到硬盘上已节省内存;PAGELK节加载后位于不可分页交换的内存空间。(放在PAGE节的函数不可以在Dispatch级调用,因为这种函数调用可能诱发缺页中断,但是缺页中断处理不能再Dispatch级完成,一般用PAGED_CODE()进行测试,如果发现当前中断级为Dispatch级,则程序直接报异常)
- windows驱动学习_Second
- 学习windows驱动(驱动对象)
- 学习Windows驱动
- windows驱动学习笔记
- windows驱动学习_First
- windows驱动学习_Third
- windows驱动学习指导
- 学习windows驱动(队列)
- windows驱动开发学习
- windows驱动编程学习(1)--------了解驱动
- windows驱动编程学习顺序?
- 驱动学习之windows认识!
- windows驱动开发学习,准备工作
- windows驱动编程学习路线
- windows 驱动学习 环境搭建
- windows驱动开发学习笔记
- 学习windows驱动(DDI接口)
- 学习windows驱动(父子关系)
- db2 赋值权限
- RNTI
- Note on <AngularJS> - Aborted Because Of Too Many Errors In This Book
- Android中preference的使用(二)
- Wpf GridView Head隐藏
- windows驱动学习_Second
- Linux的查看文件大小和磁盘大小
- 黑马程序员_Java基础_网络编程_客户端服务端数据传输,交互,客户端请求服务原理,自定义浏览器,URL统一资源定位符
- 睡眠--TASK_INTERRUPTIBLE and TASK_UNINTERRUPTIBLE
- hdu 1711 Number Sequence
- 虚拟机如何上网
- stl单向队列 简单使用
- I2C总线驱动程序的实现
- badboy + jmeter并发性能测试