驱动开发坑总结

1. 用FILE_FLAG_OVERLAPPED打开设备时,ReadFile、WriteFile的OVERLAP参数不能为空,否则会异常,到不了驱动的派遣函数

2. 用IoGetDeviceObjectPointer得到FILE_OBJECT和DEVICE_OBJECT指针,用完后Deref文件对象就行了,设备对象千万别Deref,否则会损坏设备对象。他内部是ZwOpenFile再ObRefrenceObjectByHandle来得到FILE_OBJECT指针,再用它的成员得到DEVICE_OBJECT指针的,所以DEVICE_OBJECT不要deref

3. IoDriverObjectType,这个未公开的变量可以声明一下就用,但在vista以前是POBJECT_TYPE类型,后面变成了POBJECT_TYPE*类型。在ObRefrenceObjectByName等函数中要注意

4. 文件系统驱动或者过滤驱动,一定要实现FastIoDispatch,哪怕函数里面直接返回false也可以。楚狂人和wowocook的书里说不实现也可以,但自己试不实现的确会蓝屏,从wrk的代码里看,NtReadFile、NtWriteFile等确实会直接调用FastIoDispatch

    if (fileObject->PrivateCacheMap) {
            IO_STATUS_BLOCK localIoStatus;
            ASSERT(fastIoDispatch && fastIoDispatch->FastIoRead);
            //
            //  Negative file offsets are illegal.
            //
            if (fileOffset.HighPart < 0) {
                if (eventObject) {
                    ObDereferenceObject( eventObject );
                }
                IopReleaseFileObjectLock( fileObject );
                ObDereferenceObject( fileObject );
                return STATUS_INVALID_PARAMETER;
            }
            if (fastIoDispatch->FastIoRead( fileObject,
                                            &fileOffset,
                                            Length,
                                            TRUE,
                                            keyValue,
                                            Buffer,
                                            &localIoStatus,
                                            deviceObject )

5.  pIrp->MdlAddress) 引发的蓝屏

PUCHAR pBuf = NULL;
if(pDeviceObject->Flags & DO_BUFFERED_IO)
pBuf = (PUCHAR)(pIrp->AssociatedIrp.SystemBuffer);
else if((pDeviceObject->Flags & DO_DIRECT_IO) )
pBuf = (PUCHAR)(MmGetSystemAddressForMdlSafe(pIrp->MdlAddress,NormalPagePriority));

很普通的一段代码却蓝屏了,看蓝屏代码是0xd1,DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)
An attempt was made to access a pageable (or completely invalid) address at an interrupt request level (IRQL) that is too high.  This is usually
caused by drivers using improper addresses.If kernel debugger is available get stack backtrace.

后来才发现是pIrp->MdlAddress为空,MmGetSystemAddressForMdlSafe里的一行代码, 

mov     rcx, [rbx+8]    ; MemoryDescriptorList
test    byte ptr [rcx+0Ah], 5

这里rcx为0,变成违例了,难道用户传过来的buffer为空? 改了下代码

else if((pDeviceObject->Flags & DO_DIRECT_IO) && pIrp->MdlAddress)//pIrp->MdlAddress为空时,MmGetSystemAddressForMdlSafe会引发蓝屏

这样就ok了


6. IoFreeIrp这个函数在内部是会完成irp的,所以用IoBuildAsynchronousFsdRequest 等函数创建的irp,用完后直接free就行了,不要再去complete了


7. Ndis协议驱动,inf里面写的服务名和PROTOCOL_CHARACTERISTICS里的ProtocolName要匹配,否则注册协议能成功但不会被系统回调。(坑死寡人了。。)


展开阅读全文

没有更多推荐了,返回首页