Windows驱动开发系列之一:小白入门经典_第1页
Windows驱动开发系列之一:小白入门经典_第2页
Windows驱动开发系列之一:小白入门经典_第3页
Windows驱动开发系列之一:小白入门经典_第4页
Windows驱动开发系列之一:小白入门经典_第5页
已阅读5页,还剩53页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第第PAGE158页Windows内核/驱动编程系列之一:驱动开发技术详解Windows驱动开发小白入门欢迎进入Windows的驱动编程世界驱动程序可以是针对某一特定硬件的,为系统提供管理硬件的各种功能;也可以是针对系统设备的,对系统的输入输出做一些处理,实现特定的功能,比如当软件要做的事用应用程序无法实现或者难以实现某种功能时,但驱动程序可以实现,则需要驱动程序。\h\h可能会简单地认为驱动程序是控制硬件设备的。Windows下驱动并不单单是用来控制硬件设\h备的。Windows中的驱动程序可以创建虚拟设备,也可以与设备无关。Windows是一个开放式的\h操作系统,这个开放式并不是指其开放源代码,而是指通过其提供的接口可以很容易和方便地对其内\h核进行扩展。图书推荐:环境配置:Vs2015,sdk10Wd10VmwareWin10x64驱动安装与调试工具驱动类型: NT式驱动WDMWDF通篇概览:驱动程序入门Windows内核架构与驱动开发的基本概念VS2015+WDK10+Vmware(win10x64)双机调试驱动程序驱动程序的基本结构Windows内核层的内存管理Windows内核层的常用内核函数IRP派遣函数驱动程序的同步处理IRP的同步内核层的定时器驱动程序调用驱动程序分层驱动程序NT式驱动程序#include<ntifs.h>VOIDUnloadDriver(PDRIVER_OBJECTpDriverObject){KdPrint(("UnloadDriversuccess."));}mainNTSTATUSDriverEntry(PDRIVER_OBJECTpDriverObject,PUNICODE_STRINGpRegistryPath){KdPrint(("DriverPath:%wZ",pRegistryPath)\h);KdPrint(("Hello,myDriver"));=UnloadDrive\hr;//routinereturnSTATUS_SUCCESS;}win10x64NT驱动程序禁用驱动程序强制签名第一步:点击右下角的“通知”,选择“所有设置”第二步:“更新和安全”第三步:“恢复”第七步:“重启”第八步:“7”:禁用驱动程序强制签名驱动安装工具SRVINSTW.EXE配置DbgView.exeWindowsRegistryEditorVersion5.00Manager\DebugPrintFilter]"DEFAULT"=dword:0000000fDbgView.exe默认无法捕获驱动层的输出信息需要修改注册表。第一个WDM式驱动程序新建工程即插即用PnPPnPPlug-and-Play,译文为即插即用。PnP的作用是自动配置低层计算机中的板卡和其他设备,然后告诉对应设备都做了什么。PnP的任务是把物理设备和软件设备驱动程序相配合,并操作设备,在每个设备和它的驱动程序之间建立通信信道。然后,PnP分配下列资源给设备和硬件:I/O地址、IRQ、DMA通道和内存段。PNP是由Microsoft提出的,意思是系统自动侦测周边设备和板卡并自动安装设备驱动程序,做到插上就能用,无须人工干预,是Windows自带的一项技术。所谓即插即用是指将符合PNP标准的PC插卡等外围设备安装到电脑时,操作系统自动设定系统结构的技术。当用户安装新的硬件时,不必再设置任何跳线器开关,也不必用软件配置中断请求(IRQ)、内存地址或直接存储器存取(DMA)通道,Windows会向应用程序通知硬件设备的新变化,并会自IRQDMA通道之间的冲突。在PnP技术出现之前,中断和I/O端口的分配是由人手工进行的,例如想要这块声卡占用中断5,就需要找一个小跳线在卡上标着中断5的针脚上一插。这样的操作需要用户了解中断和I/O端口的知识,并且能够自己分配中断地址而不发生冲突,对普通用户提出这样的要求是不切实际的。代码详解/********************************************HelloWDM.h********************************************/cplusplusextern"C"{#endif#include<wdm.h>cplusplus}#endiftypedefstruct_DEVICE_EXTENSION{PDEVICE_OBJECTfdo;PDEVICE_OBJECTNextStackDevice;UNICODE_STRINGustrDeviceName; //UNICODE_STRINGustrSymLinkName;//}DEVICE_EXTENSION,*PDEVICE_EXTENSION;#definePAGEDCODEcode_seg("PAGE")#defineLOCKEDCODEcode_seg()#defineINITCODEcode_seg("INIT")#definePAGEDDATAdata_seg("PAGE")#defineLOCKEDDATAdata_seg()#defineINITDATAdata_seg("INIT")#definearraysize(p)(sizeof(p)/sizeof((p)[0]))NTSTATUSHelloWDMAddDevice(INPDRIVER_OBJECTDriverObject,INPDEVICE_OBJECTPhysicalDeviceObject);NTSTATUSHelloWDMPnp(INPDEVICE_OBJECTfdo,INPIRPIrp);NTSTATUSHelloWDMDispatchRoutine(INPDEVICE_OBJECTfdo,INPIRPIrp);voidHelloWDMUnload(INPDRIVER_OBJECTDriverObject);extern"C"NTSTATUSDriverEntry(INPDRIVER_OBJECTDriverObject,INPUNICODE_STRINGRegistryPath);Wdm驱动程序总结DriverEntry(...)pDriverObject->DriverExtension->AddDevice=HelloWDMAddDevice;///2.分发例程pDriverObject->MajorFunction[IRP_MJ_PNP]=HelloWDMPnp;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=pDriverObject->MajorFunction[IRP_MJ_CREATE]=pDriverObject->MajorFunction[IRP_MJ_READ]=pDriverObject->MajorFunction[IRP_MJ_WRITE]=HelloWDMDispatchRoutine;///3.卸载例程pDriverObject->DriverUnload=HelloWDMUnl\hoad;PAGE1058页API函数:IoCreateDeviceIoDeleteDeviceIoAttachDeviceToDeviceStackIoSkipCurrentIrpStackLocationIoDetachDeviceIoSkipCurrentIrpStackLocationIoCompleteRequestIoCreateSymbolicLink,IoDeleteSymbolicLink配置文件INF;;HelloWDM.inf;[Version]Signature="$WINDOWSNT$"Class=SystemProvider=fyxyDriverVer=08/27/2020,74CatalogFile=HelloWDM2.cat[DestinationDirs]DefaultDestDir=12[SourceDisksNames];1=%DiskName%,,,"";1="HelloWDM",Disk1,,1=%DiskName%,,,""[SourceDisksFiles]HelloWDM.sys=1,,[Manufacturer]%ManufacturerName%=Standard,NTamd64[Standard.NTamd64]%HelloWDM.DeviceDesc%=HelloWDM,Root\HelloWDM;TODO:edithw-id[HelloWDM.NT]CopyFiles=Drivers_Dir[Drivers_Dir]HelloWDM.sys;Serviceinstallation[HelloWDM.NT.Services]AddService=HelloWDM,%SPSVCINST_ASSOCSERVICE%,HelloWDM_Service_Inst;HelloWDMdriverinstallsections[HelloWDM_Service_Inst]DisplayName =%HelloWDM.SVCDESC%ServiceType =1 ;SERVICE_KERNEL_DRIVERStartType =3 ;SERVICE_DEMAND_STARTErrorControl =1 ;SERVICE_ERROR_NORMALServiceBinary=%12%\HelloWDM.sys[Strings]SPSVCINST_ASSOCSERVICE=0x00000002ManufacturerName="fyxy";TODO:ReplacewithyourClassName="Samples"DiskName="HelloWDMSourceDisk"HelloWDM.DeviceDesc="HelloWDMDevice"HelloWDM.SVCDESC="KMDF_Driver1Service"Windows内核架构与驱动开发的基本概念Widnows操作系统概述Windows家族Win9X系列Windows95,Windows98,WindowsMeWinNT系列WindowsNT3.1,WindowsNT3.5WindowsNT4.0Windows2000WindowsXPWindowsServer2003WindowsVistaWindows7Windows10Windows特性可移植性兼容性健壮性可扩展性异步结构用户模式与内核模式操作系统与应用程序Windows操作系统的分层结构Windows操作系统总体架构应用程序与Win32子系统NativeAPIWin32APINativeAPINativeAPIWin32API数前面加上NtCreateFileNtCreateFileNt是在“ntdll.dll”实现的,而多数Win32API都是在“kernel.dll”导出的,也有少部分GDIgdi32.dll”和“user32.dll”导出的。NativeAPI从用户模式穿越进入到内核模式调用系统服务,这个穿越过程是通过软中断的方式进入的。这个软中断的实现方法在不同版本的Windows实现方式略有不同,在Win2K下是通过“int2ehWinXPsysenter”指令完成的。软中断会将NativeAPI的参数和系统服务号的参数一起传进内核模式,不同的NativeAPISSDT系统服务函数一般和NativeAPI具有相同的名字,例如都是NtCreateFile,但它们的实现不同,系统服务调用是在“ntoskrnl.exe”导出的。NTDLL.DLL系统支持库,用于子系统DLL,包含以下两种类型的函数:系统服务分发存根WINDOWS执行体系统服务内部支持函数DLL及其他的原生映像文件使用行体的系统服务。对于每个这样的函数,NTDLL包含了一个同名的入口点。函数内部的代码包含了与处理器体系结构相关的模式切换指令,通过该指令可以转换到内核模式下,从而调用系统服务分发器,分发器检验了参数后,调用真正的内核模式系统服务,其中包括NTOSKRNL。系统服务执行体组件执行体组件执行体是NTOSKRNL.EXE的上层(内核是下层),包括以下函数(1)NTDLL被导出DEVICEIOCONTROL函数来调用的设备驱动器函数只能在内核模式下调用的导出函数,且已经文档化在内核模式下调用但未文档化定义为全局符号但是未被导出的函数,包括在NTOSKRNL内调用的内部支持函数未定义为全局符号,而是在一个模块内部的函数执行体包括以下主要组件配置管理器。负责系统注册表的实现和管理进程和线程管理器,创建或终止进程和线程安全引用监视器,强制在本地计算机上实行安全策略I/O管理器I/O操作即插即用管理器电源管理器WDM驱动管理,允许设备驱动程序发布有关性能和配置的信息调整缓存管理器I/O操作的性能内存管理器,实现了虚拟内存逻辑预取器,加速系统和进程的启动过程另外执行体还包含四组主要的支持函数对象管理器LPC设施,在同一台机器上的客户进程和服务器进程之间传递消息公共运行库函数,比如:字符串处理、算术操作、数据类型转换以及安全结构处理执行体支持例程,比如系统内存分配、同步对象等内核内核被认为是Windows操作系统的心脏。Windows的内核从执行体组件分割出来。和执行体组件相比,内核是非常小的。内核(SpinLock)CPU同步支持,提供中断处理等。内核提供了以下功能:》对内核对象的支持。》对线程的调度。》对多处理器同步的支持。》中断处理函数的支持。》对错误陷阱的支持。》对其他硬件特殊功能的支持。Windows\h在调度线程的时候不能被其他线程所打断,即不能允许线程的切换。但是内核可以被更高的中断请求级别(IRQL)所打断。内核是由NTOSKRNL.EXE中的一组函数以及对于硬件体系结构的低层支持(比如中断和异常分发)C编写,对于特殊指令和寄存器,使用汇编[内核对象]提供一组定义明确的、可预知的操作系统低层原语和机制,从而使得执行体中的高层组件可以做它们需要做的事情。实现从内核外部来看,执行体将线程和其他可共享的资源表示为对象,这些对象要求一些策略开销,这些开销在内核中不存在,内核实现一组简单的对象,执行体层的大部分对象包装了一个或多个内核对象。[硬件支持]内核的另一个主要任务是将执行体和设备驱动程序图使公共代码最大化支持内核的这一功能,支持一组可移植的接口。驱动程序I/O管理器接收应用程序的请求后,创建相应的IRP,并传送至驱动程序进行处理,有如下几种处理的方法。IRPIRP,并返回。将此IRP的请求,转发到更底层的驱动中去,并等待底层驱动的返回。接受到IRP请求,不是急于完成。而是分配新的IRP发到其他驱动程序中,并等待返回。驱动程序处理IRP的过程往往不是单独操作,而是将以上几种操作结合在一起。[设备驱动程序]可加载的内核模式模块,通过以.SYS结尾,在I/O管理器与相应的硬件之间建立起链接,设备驱动程序位于以下三种执行环境之一:1I/O功能的用户线程环境中2、在内核模式系统线程的环境中3、作为一个中断的结果通过调用HAL来维护硬件是设备驱动程序的工作,分为以下类型1、硬件设备驱动程序2、文件系统驱动程序3、文件系统过滤器驱动程序4、网络重定向器和服务器5、协议驱动程序6、内核流式过滤器驱动程序WDM的角度有以下几种:1、总线型驱动程序2、功能型驱动程序3、过滤型驱动程序硬件抽象层[硬件抽象层HAL]HAL例程来保持可移植性Windows与微内核什么是微内核?原语仅仅包括了建立一个系统必需的几个部分,如线程管理,地址空间和进程间通信等。微核的目标是将系统服务的实现和系统的基本操作规则分离开来。例如,进程的输入/\h个服务组件的失效并不会导致整个系统的崩溃,\h内核需要做的,仅仅是重新启动这个组件,而不必影响其它的部分。从应用程序到驱动程序打开Windows的设备管理器,可以发现这里罗列着计算机里安装的所有设备,这些设备有的是真实的物理设备。例如:网卡设备、显卡设备等。有些设备则是虚拟设备。例如,自己编写的驱动,它没有对应着PC的任何设备,而完全是虚拟出来的“假”设盘对卷设备的所有操作,全部会转化成磁盘设备的操作。PC上的设备千差万别,所实现的功能完全不同,如何用统一的接口操作不同的设备,Windows一接口,将所有设备以普通文件看待。也就是说在Windows中,无论何种设备,都用操作文件的办法去操作设备。对所有设备的操作统一成和文件操作一样的操作,这一方法非常巧妙。文件操作和设备操作有很多类似的地方。例如,二者都有打开、关闭、读、写、取消等操作。下表列举了文Win32API函数。Wn2AI。下图是对Windows架构简图的简化,可以很清晰地看到应用程序到驱动程序是怎样操作设备的。这里以CreateFileAPI\hAPICreateFileAPI,这个API是由Win32子系统的三大模块中的\hKernel32.dll实现的。CreateFile函数会调用Ntdll.dll中的NtCreateFile函数,其中NtCreateFile是未文档化的函数,程序员最好不要直接使用这个未文档化的函数。NtCreateFile的作用是穿越用户模式的边界,进入到内核模式,这个步骤是通过软中断实现的。进入到内核模式后,会调用系统的服务函数,这里会调用同名的系统服务CaileCaileaiePI,另一个是位于内核模式的系统服务调用)NtCreateFile系统函数调用通过I/O管理器,创建IRP并传输到设备的驱动程序中。IRP(I/ORequestPackage)即输入输出请求包,是驱动程序开发中重要的数据结构。驱动程序的运行,完全是靠IRP驱动的。下面会有对IRP的专门介绍,这里可以将IRP理解为一个消息。这个消息告诉驱动程序,是需要读操作还是写操作。驱动程序根据IRP,进行相应的操作。这些操作一般是对设备的直接操作,例如对端口的读操作。对端口的读操作根据不同的硬件平台,实现方法会有所不同,Windows根据不同的硬件平台,会有不同的硬件抽象层(HAL)。硬件抽象层提供一组宏,如READ_PORT_BUFFER_UCHAR。例如,对32位X86系列CPU中的Windows,READ_PORT_BUFFER_UCHARIN操作。回想这个复杂的过程,经过了多个层次的交互,只是为了执行一个读写端口的操作。对于有过DOS变成经验的程序员来说,在DOS中操作硬件完全可以不使用驱动,直接使用IN汇编代码就可以实现。事实的确如此,但Windows这样做完全是为了安全的考虑。所有直接操作硬件的指令,如读写物理内存、读写端口都认为是危险的操作,必须经过驱动才能完成。试想一下,如果应用程序能任意执行IN和OUT汇编指令,那么就可轻易地对磁盘进行控制,这会给操作系统带来安全隐患。又例如,如果能直接读写物理内存,黑客会很容易地对当前进程以外的其他进程进行内存读写,那么盗取账号密码将会变得非常简单。因此,在应用程序中无法执行IN汇编指令,而必须通过驱动程序来执行。在一层层地调用中,每层又会严格地检查,保证参数的合法性。VS2015+VMware(win10x64)双机调试驱动驱动程序的开发语言选择第一条:C语言为首选。调用约定调用约定是指函数在被调用时,会按照不同的规则翻译成不同的汇编代码。CC++语言编译程序的时候,一般会有以下两种调用约定。C语言调用约定。c语言调用约定要求在生命函数时用cdecl对函数进行修饰。如cdeclfoo(inta,intb);c语言调用会在目标文件中产生一个符号来代表这个函数,此符号的形式为+函ret形式返回。例如:foo(0x12345678,0x11223344);push0x11223344push0x12345678call_fooaddesp,8标准调用约定。要求在声明函数时用stdcall对函数进行修饰。如stdcallfoo(inta,intb);标准调用会在目标文件中产生一个符号来代表这个函数,此符号形式为++X,其中X为清理堆栈时需要的数字,函数以retX形式返回。上例中展成汇编代码为:0x112233440x12345678callfoo@8一般来说,很少见到用关键字指定函数的调用约定,编译器会选择默认的调用约定进行VCC语言的调用约定。而Windows驱动程序的编写使用的是标准调用约定,尤其是入口函数。系统会寻找DriverEntry@8c的调用约定就会导致链接错误,因此在编译驱动是需要改变默认的调用约定。运行时函数的调用VS2015+VMWare(Win10x64)搭建双机调试环境WDK8.1后,开发windowwindbg+虚拟机调试了,我们调试驱动EXE一样方便,下面是win10(主机)+WDK10+VS2015+vmware_win10驱动开发环境配置教程注意事项:ping通。win10的版本Cmdver/winverMicrosoftWindowsVersion10.0.17134.1550](版本:1803)注意:SDKWDK的版本,一定要与win10的版本对应上。Win10-sdk: win101803(17134)win10-sdkWin10-wdk:win101803win10-wdk如何下载sdk?去微软官方或百度,搜索“winsdk17134”\h/zh-cn/windows-hardware/drivers/other-wdk-downloads如何下载wdk?\h/zh-cn/windows-hardware/drivers/other-wdk-downloadsVisualstudio2015请自己百度:vs2015.ent_chs.iso根据你的需要下载对应版本的VS2015,推荐下载Community版本,因为这个版本免费且功能齐全。7G左右。VisualC++Windows10SDKVS2015的时候呢,最好是全部安装,安装的过程也是很慢的,耐心等待吧!sdkWindows10版本1803\h适用于\hWindows10.0.17134\h的\hWindowsSDKwdkWindows10版本1803\h适用于\hWindows10\h版本\h1803\h的\hWDKVS2015W\hDK10,WDK10是一个在线安装程序,可以直接安装也可以下载到本地再进行安装,我选择的是直接下载到本地:Win10驱动程序示例\h/Microsoft/Windows-driver-samplesVmware--Win10x64cn_windows_10_consumer_editions_version_2004_x64_dvd\h/win10jiaocheng/14029.html创建串口注意:最好把“打印机”删除掉。启用系统保护“创建系统还原点”WDKTestTargetSetupxxxxx.msiWDKTestTargetSetupx86-x86_e\hn-us.msiWDKTestTargetSetupx64-x64_e\hn-us.msi虚拟机中关闭“驱动证书检测程序”CMD使用“bcdedit.exe/setnointegritycheckson”命令关闭驱动数字证书检测程序。3.使用“bcdedit.exe”命令查看驱动数字证书检测程序。4.使用“bcdedit.exe/setnointegritychecksoff”命令打开驱动数字证书检测程序。VS2015 Configure Devices基本配置Win102020CXAZZFWin102020CXAZZF\\.\pipe\com_1有一个坑这个过程也就是创建一个WDKRemoteUser管理员用户并安装一些运行库等,最后还创建了一个系统还原点。起初我虚拟机是企业版的时候,在安装那一步老是报错:Provisioningatargetsystemfordriverdevelop\hmentfailswitherror1312这里显示是bug,但是我注意到vs创建WD\hKRemoteUser时是有密码的,然后我用另一个管理员账户清除了WDKRemoteUser的密码后\h,以WDKRemoteUser身份登陆后,再点vs配置里面的安装,却安装成功了,成功界面:重启win10,禁用驱动程序签名驱动安装工具SRVINSTW.EXEWin10x64WDM驱动第一步:添加过时硬件第二步:安装我手动从列表选择的硬件然后点击“下一步”,第三步:从磁盘安装选择“inf文件”驱动程序的基本结构Windows驱动程序中重要的数据结构驱动对象DRIVER_OBJECT设备对象DEVICE_OBJECTDEVICE_EXTENSION驱动对象DRIVER_OBJECTtypedefstruct_DRIVER_OBJECT{CSHORTType;CSHORTSize;////Thefollowinglinksallofthedevicescreatedbyasingledriver//togetheronalist,andtheFlagswordprovidesanextensibleflag//locationfordriverobjects.//PDEVICE_OBJECTDeviceObject;ULONGFlags;////Thefollowingsectiondescribeswherethedriverisloaded.Thecount//fieldisusedtocountthenumberoftimesthedriverhashadits//registeredreinitializationroutineinvoked.//PVOIDDriverStart;ULONGDriverSize;PVOIDDriverSection;PDRIVER_EXTENSIONDriverExtension;////Thedrivernamefieldisusedbytheerrorlogthread//determinethenameofthedriverthatanI/Orequestis/wasbound.//UNICODE_STRINGDriverName;////Thefollowingsectionisforregistrysupport.Thisisapointer//tothepathtothehardwareinformationintheregistry//PUNICODE_STRINGHardwareDatabase;////Thefollowingsectioncontainstheoptionalpointertoanarrayof//alternateentrypointstoadriverfor"fastI/O"support.FastI/O//isperformedbyinvokingthedriverroutinedirectlywithseparate//parameters,ratherthanusingthestandardIRPcallmechanism.Note//thatthesefunctionsmayonlybeusedforsynchronousI/O,andwhen//thefileiscached.//PFAST_IO_DISPATCHFastIoDispatch;////Thefollowingsectiondescribestheentrypointstothisparticular//driver.Notethatthemajorfunctiondispatchtablemustbethelast//fieldintheobjectsothatitremainsextensible.//PDRIVER_INITIALIZEDriverInit;PDRIVER_STARTIODri

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论