Windows 内核技术与驱动开发笔记(完整版)
Windows驱动学习笔记
需要说明的是,本书并不是一本详尽的入门书籍,它只是根据我本人的学习过程进行的 经验总结,适合作为专门教程的辅助读物。
灰狐 [iCoodle] :
邪恶八进制社区和泡面代码社区同时享有本书的任何处理权利。
作者简介
灰狐,又名 grayfox、nokyo 等,马甲众多,自 2005 年至 2009 年就读于成都信息工程 学院,喜编程、擅灌水,以结识志同道合者为好,常混迹于各大 BBS ,潜水居多。
MSN:peiyaoq iang@ms Gtalk :peiyaoq iang@gma il. c om Ema il:peiyaoq iang@126. c om QQ 群:醉爱编程 [iCoodle](群号:78298479) 个人主页:
1.1 关于 DDK............................................................................................................................ 5 1.2 关于驱动程序的编译.......................................................................................................... 5 1.3 驱动程序的运行.................................................................................................................. 6 第二章 驱动程序的结构.......
《Windows驱动开发技术详解》之Windows内核函数
《Windows驱动开发技术详解》之Windows内核函数内核模式下字符串操作ANSI_STRING和UNICODE_STRING分别定义如下:以UnicodeString类型对象进⾏初始化为例,代码如下:输出:进⾏复制字符串操作,代码如下:输出:但是如果这⾥改为:加载驱动运⾏就会蓝屏。
Why?其实,RltFreeUnicodeString是⽤来释放利⽤申请的堆空间初始化的UnicodeString类型对象的,⽽RtlInitUnicodeString对UniStr1进⾏初始化时,只是让Buffer指向了⼀个常量区。
进⾏ANSI_STRING字符串与UNICODE_STRING字符串相互转换操作,代码如下:注意这⾥要利⽤RtlFreeUnicodeString释放通过RtlAnsiStringToUnicodeString得到的UniStr2。
为什么这个需要释放?我们利⽤Windbg跟踪下代码。
⾸先,跟踪时要逐⼀,这⾥的勾如果不去掉,就是在源码下单步跟踪,⽽不是在汇编指令⾥单步跟踪:在RtlUnicodeStringToAnsiString函数中,有这么⼀个系统API此时的参数是正好是传⼊的字节数的⼤⼩。
⽽这个API最终调⽤了:所以,我们要利⽤RtlFreeUnicodeString进⾏释放。
内核模式下的⽂件操作:创建⽂件:代码⼊下:1 VOID FILEOPERATION(){2 OBJECT_ATTRIBUTES ObjAttributes;3 IO_STATUS_BLOCK iostatus;4 HANDLE hfile;5 UNICODE_STRING logFileUnicodeString;67 RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");8 InitializeObjectAttributes(&ObjAttributes,9 &logFileUnicodeString,10 OBJ_CASE_INSENSITIVE,11 NULL,12 NULL);13//创建⽂件14 NTSTATUS status = ZwCreateFile(&hfile, GENERIC_WRITE,15 &ObjAttributes,16 &iostatus,17 NULL,18 FILE_ATTRIBUTE_NORMAL,19 FILE_SHARE_READ,20 FILE_OPEN_IF,//这⾥是FILE_OPEN_IF则不论⽂件是否存在都可以Create成功,⽽如果改为FILE_OPEN,则只当⽂件存在时create成功。
Windows 驱动程序开发指导说明书
课程内容驱动基本概念介绍驱动核心代码分析WDM和WDF介绍Windows 10通用驱动平台驱动程序是一个软件模块,可以使操作系统和硬件设备进行交互驱动程序是操作系统的一个扩展驱动程序一般是由硬件的设计者或厂商进行编写Microsoft已经为符合公共设计规范的硬件设备提供了内置的驱动程序可执行文件,扩展名是.exe入口函数是Main()Main()函数完成大部分工作应用程序完成工作后返回,并释放内存空间在用户态运行可执行文件,扩展名是.sys入口函数是DriverEntry()DriverEntry()不会做很多工作,只是初始化驱动驱动其他部分会注册很多回调函数,会被系统的不同模块调用驱动不会返回,会一直存在直至被显示的释放在内核态或用户态运行Driver StacksPDO位于驱动栈的最底层,和总线驱动相关联当总线驱动被加载时,它会枚举所有挂载在总线上面的设备并请求设备所需要的资源每个设备都有自己对应的PDOPnP管理器会确定每个设备的驱动并在设备的PDO 之上构建适当的设备栈设备栈的核心部分,FDO和设备功能驱动相关联设备功能驱动完成Windows和设备交互的核心功能对上向应用程序和服务提供上层接口对下为设备或其他驱动提供数据交换的接口一个设备栈可以包含多个FiDO,可以在FDO之上或之下每个FiDO和一个过滤驱动相关联,FiDO是可选的通常的目的是修改一些在设备栈中传输的I/O请求,例如可以加密和解密读写请求当一个新设备被插入到系统后,系统总线驱动会向PnP管理器报告这个新设备PnP管理器通过总线驱动查询这个设备的更多信息,比如设备ID和设备所需要的资源PnP管理器利用这个信息去查找是否有有对应的驱动在本地或WU(Windows Update)上面一旦查找到设备对应的驱动,Windows便会安装并加载这个驱动加载驱动到地址空间解析驱动中引入的函数-调用其他模块调用驱动的入口函数(DriverEntry()),因此驱动可以注册回调函数调用AddDevice(),驱动此时可以创建一个“设备对象”,并将这个对象加入到设备栈中所有的事物在驱动框架中都是用对象呈现的(驱动,设备,请求等等)对象拥有属性,方法和事件WDF 对象方法属性事件操作对象的函数被WDF 框架调用用于通知某些事件设置或获取单个属性值的方法Driver (WDFDRIVER)Device (WDFDEVICE)Device (WDFDEVICE)Queue (WDFQUEUE)Queue (WDFQUEUE)……ObjectOperation方法:Status = Wdf Device Create ();属性:Cannot failWdfInterrupt Get Device();WdfInterrupt Set Policy();Can fail:Status = WdfRegistry Assign Value();Status = WdfRegistry Query Value();Status = WdfRequest Retrieve InputBuffer();回调事件:PFN_WDF_INTERRUPT_ENABLE EvtInterruptEnable初始化宏:WDF_XXX_CONFIG_INITWDF_XXX_EVENT_CALLBACKS_INIT当驱动被加载时,DriverEntry是第一个被操作系统调用的函数WdfDriverCreate( RawDriverObject, […] , attributes, &driver )NTSTATUS DriverEntry(_In_PDRIVER_OBJECT DriverObject ,_In_PUNICODE_STRING RegistryPath ) {[…]// Create WDF Driver ObjectWDF_OBJECT_ATTRIBUTES_INIT(&attributes);attributes.EvtDriverUnload = OnDriverUnload;WDF_DRIVER_CONFIG_INIT(&config, OnDeviceAdd);status = WdfDriverCreate(DriverObject ,RegistryPath ,&attributes,&config,&driver );}WDF EventWDF MethodWDF ObjectDeclare vars这是一个过滤驱动程序吗?驱动程序是电源管理策略的所有者吗?为设备对象创建I/O队列创建辅助对象,例如计时器,工作者对象,锁等NTSTATUS OnDeviceAdd( WDFDRIVER Driver,PWDFDEVICE_INIT DeviceInit) {WDFDEVICE device;IWDFIoQueue* pDefaultQueue= NULL;DeviceInit->SetPowerPolicyOwnership(TRUE );status= WdfDeviceCreate(&DeviceInit,&deviceAttributes, &device);context = GetContext(device);context->WdfDevice= device;status = pIWDFDevice->CreateIoQueue(NULL, TRUE, WdfIoQueueDispatchParallel,TRUE, FALSE, &pDefaultQueue);return status;}Static Configuration Device CreateSetting ContextQueue Create进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnPrepareHardware(WDFDEVICE Device ,WDFCMRESLIST ResourcesRaw ,WDFCMRESLIST ResourcesTranslated ) {int ResourceCount = WdfCmResourceListGetCount(ResourcesTranslated );for (i=0; i < ResourceCount; i++) {descriptor =WdfCmResourceListGetDescriptor(ResourcesTranslated , i);switch (descriptor->Type) {case CmResourceTypePort : […]case CmResourceTypeMemory : […]case CmResourceTypeInterrupt : […]default : break ;}}return STATUS_SUCCESS ;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnD0Entry(IN WDFDEVICE Device ,IN WDF_POWER_DEVICE_STATE RecentPowerState ){PADXL345AccDevice pAccDevice = nullptr pAccDevice = GetContext(Device);WdfWaitLockAcquire(pAccDevice->m_WaitLock);I2CSensorWriteRegister(pAccDevice->m_I2CIoTarget, MY_REGISTER,MY_VALUE, sizeof (MY_VALUE) );pAccDevice->m_PoweredOn = true ;WdfWaitLockRelease(pAccDevice->m_WaitLock);return STATUS_SUCCESS ;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)NTSTATUS OnInterruptEnable(IN WDFINTERRUPT Interrupt,IN WDFDEVICE Device){PDEVICE_EXTENSION devExt;ULONG regUlong;PULONG intCsr;devContext = GetDeviceContext(WdfInterruptGetDevice(Interrupt) );intRegId = &devContext->IntRegisterId regVal = READ_REGISTER_ULONG( intRegId );regVal = ENABLE_INTERRUPT_BYTE( regVal );WRITE_REGISTER_ULONG( intRegId, regVal );return STATUS_SUCCESS;}进入电源状态管理(D0Entry)使能中断(InterruptEnable)…获取硬件资源,进行一些静态配置,(PrepareHardware)EvtIoResume EvtDMAEnablerFillEvtDeviceSelfManagedIoInitEvtDeviceDisarmWakeFromSxEventChildListScanForChildren EvtDeviceRemoveAddedResourcesStart power-managed queuesEvtIoResume Disarm wake signal, if it was armed. (called onlyduring power up; not called during resource rebalance)EvtDeviceDisarmWakeFromSx EvtDeviceDisarmWakeFromS0Request information about child devicesEvtChildListScanForChildren Enable DMA, if driver supports it EvtDmaEnablerSelfManagedIoStartEvtDmaEnablerEnableEvtDmaEnablerFillConnect interruptsEvtDeviceD0EntryPostInterruptsEnabledEvtInterruptEnable Notify Driver of state change EvtDeviceD0EntryDevice OperationalRestart from here if device is in low power statePrepare hardware for power EvtDevicePrepareHardwareChange resources requirements EvtDeviceRemoveAddedResourcesEvtDeviceFilterAddResourceRequirementsEvtDeviceFilterRemoveResourcRequirementsRestart from here if rebalancing resourcesCreate Device object EvtDriverDeviceAddDevice arrivedEnable self-managed I/O, if driver supports it.EvtDeviceSelfManagedIoInit (implicit power up),EvtDeviceSelfManagedIoRestart (explicit power up)Stop power-managed queuesEvtIoStop Arm wake signal, if it was not armed. (calledonly during power up; not called duringresource rebalance)EvtDeviceArmWakeFromSx EvtDeviceArmWakeFromS0Disable DMA, if driver supports it EvtDmaEnablerSelfManagedIoStopEvtDmaEnablerDisableEvtDmaEnablerFlushDisconnect interrupts EvtDeviceD0EntryPostInterruptsDisabledEvtInterruptDisableNotify Driver of state changeEvtDeviceD0Exit Device OperationalStop here if transitioning to low power stateRelease hardware EvtDeviceReleaseHardwarePurge power-managed queuesEvtIoStop Stop here if rebalancing resourcesFlush I/O if driver supports self-managedI/OEvtDeviceSelfManagedIoFlush Device removedSuspend self-managed I/O, if driver supports it.EvtDeviceSelfManagedIoSuspend Cleanup I/O buffers if driver supports self-managed i/o EvtDeviceSelfManagedIoCleanupDelete device object s context area.EvtDeviceContextCleanupEvtDeviceContextDestroyWDM和操作系统深度耦合,WDM驱动程序直接调用系统服务例程,直接操作系统数据结构WDM驱动程序全部为内核态程序,操作系统对驱动输入只做有限的检查WDF框架处理与操作系统的交互,驱动本身专注于和设备交互WDF基于对象模型和事件驱动WDF支持内核态程序和用户态程序将操作系统底层的复杂逻辑抽象化使驱动代码有可能<20行对不同的硬件设备使用相同的编程模型例如GPIO,UART,I2C,NFC,传感器驱动框架内置的日志系统为数据分析定制的工具支持上千种不同的硬件设备最初UMDF V1基于C++ COMUMDF V2使用和内核态驱动开发相同的模型和语法支持USB周边设备,传感器,NFC,智能卡,HID(包括触控)等等驱动崩溃只会影响宿主进程,不会影响整个操作系统系统重启策略可以自动恢复崩溃的UMDF驱动Windows 10提供了一系列API和DDI,对于所有的Windows平台都是通用的,被称为Universal Windows Platform(UWP) Windows通用驱动是指一个内核态或用户态的驱动并能运行在所有基于UWP的系统上面Windows通用驱动只能调用属于UWP部分的DDI,这部分DDI会在MSDN文档中标记为Universal确定你的驱动是否支持UWP,把你的驱动标记为通用驱动然后重新编译在Visual Studio中打开驱动项目工程在配置选项中把操作系统选择为Windows 10在工程属性中把目标平台改为“通用”,其他选项还有“桌面”和“手机”重新编译驱动,这时可以会出现一些链接器错误尝试修复这些错误,对于出现错误的API,请参考文档是否有通用平台的API可以替代,如果没有,您可能需要重新设计你的驱动KMDF version Release method Included in this versionof Windows Drivers using it run on1.19Windows 10, version1607 WDK Windows 10, version1607Windows 10 version1607 and later,Windows Server 20161.17Windows 10, version1511 WDK Windows 10, version1511Windows 10 version1511 and later,Windows 10 Mobile,Windows 10 IoT Core,Windows Server 20161.15Windows 10 WDK Windows 10Windows 10 for desktop editions, Windows 10 Mobile, IoT Core, Windows Server 2016UMDF version Release method Included in this version ofWindows Drivers using it can run on2.19Windows 10, version 1607WDK Windows 10, version 1607Windows 10, version 1607 (all SKUs), Windows Server 20162.17Windows 10, version 1511WDK Windows 10, version 1511Windows 10 for desktop editions (Home, Pro, Enterprise, and Education), Windows 10 Mobile, Windows 10 IoT Core (IoT Core), Windows Server 20162.15Windows 10 WDK Windows 10Windows 10 for desktop editions, Windows 10 Mobile, IoT Core, Windows Server 2016驱动程序运行在哪个版本的操作系统上驱动程序支持的硬件类型驱动程序使用的驱动模型确定驱动程序是否使用了只有KMDF支持的功能,如果驱动程序没有使用KMDF的功能,并且驱动运行在Windows 8.1或以后的系统上,则可以迁移到UMDF 2https:///en-us/windows/hardware/drivers/wdf/wdf-porting-guide Which Drivers Can Be Ported and WhereDifferences Between WDM and WDFPreparing for PortingSteps in PortingSummary of KMDF and WDM Equivalents。
《Windows核心编程》读书笔记上
6. 对象句柄继承:创建内核对象的时候可以指定SECURITY_ATTRIBUTES. bInheritHandle表示可继承(任何时候可以使用 SetHandleInformation修改可继承性等属性),创建子进程时指定CreateProcess的参数bInheritHandles为TRUE,则子进程从父进程的对象 表中拷贝所有可继承的对象到自己的对象表的相同表位置中(并增加引用计数),因为表项结构被完全拷贝且内核对象实际地址在地址空间 后2G的内核地址段中,所以拷贝过来的表项完全有效,进而父子进程的可继承内核对象的句柄值完全相同,于是只要以任何方式将要继承 的对象的句柄值跨进程交给子进程(创建子进程时的命令行参数、环境变量、共享内存、消息等手段),则后者可以使用。
看如下代码:
_chdir("D:/Downloaloads,且进程当前驱动器为D:
_chdir("F:/Projects"); // 修改F:的当前路径为Projects,且进程当前驱动器为F:
std::ofstream("1.txt"); // 当前驱动器是F:,所以绝对路径是F:/Projects/1.txt
7. 命名内核对象:要访问已经存在的命名内核对象,可以使用CreateXXX或者OpenXXX,后者在对象不存在的时候返回NULL。如果打 开了一个已经存在的命名对象,在打开时为API指定的对象名以外的参数被忽略。注意,一个进程打开同一对象两次,除了增加引用两次 外,返回的句柄值是不同的,需要分别关闭一次,即打开和关闭完全对称(很合理的行为)。在Vista及以上的系统,对象名可以包括在命名 空间下,避免被低授权用户访问。
12. GetVersionEx获取系统版本信息。VerifyVersionInfo检测当前系统是否满足版本需要。
DDK驱动开发笔记
DDK驱动开发笔记1、windows驱动分为NT式驱动和WDM式驱动,前者为非即插即用,后者为即插即用驱动。
需要头文件分别为NTDDK.h和WDM.h2、驱动的入口函数均为extern "C" NTSTA TUS DriverEntry(IN PDRIVER_OBJECTpDriverObject, IN PUNICODE_STRING pRegistryPath),它由I/O管理器负责调用,前参数为传递进来的驱动对象,后参数为Unicode字符串,指向此驱动的注册表。
3、驱动程序向windows的I/O管理器注册一些回调函数,回调函数是由程序员定义的函数,由操作系统负责调用,只要把地址告诉操作系统即可如:pDriverObject->DriverUnload=HelloDDKUnload;4、使用CreateDevice函数创建驱动设备对象如:CreateDevice(pDriverObject);返回NTSTATUS类型5、KdPrint是一个宏,用于打印输出信息,在Checked中会使用DbgPrint代替,在Free版本中无效果,用法和TRACE一致。
6、Windows的设备管理是使用线性链表进行管理,每一个节点记录了设备对象的地址,每次要对指定驱动进行操作,就必须先遍历设备对象链表。
7、设备对象函数NextDevice域记录下一个设备对象的地址,IoDeleteDevice用于删除设备对象如:IoDeleteDevice(pDevExt->pDevice),IoDeleteSymbolicLink用于删除设备符号链接。
8、DDK环境编译驱动源程序,需要使用两个自己创建的脚本makefile和Sources,最好使用二进制文本格式,makefile的内容固定为:!INCLUDE $(NTMAKEENV)\makefile.def。
sources文件记录了驱动的名称、驱动类型、编译输出目录、include目录、指定源文件。
学习笔记windows驱动开发技术详解
<学习笔记>Windows驱动开发技术详解派遣函数是Windows驱动程序中的重要概念。
驱动程序的主要功能是负责处理I/O请求,其中大部分I/O请求是在派遣函数中处理的。
用户模式下所有对驱动程序的I/O请求,全部由操作系统转换为一个叫做IRP数据结构,不同的IRP会被“派遣”到不同的派遣函数中。
IRP与派遣函数IRP的处理机制类似于Windows应用程序中的“消息处理”,驱动程序接收到不同的IRP后,会进入不同的派遣函数,在派遣函数中IRP得到处理。
1.IRP在Windows内核中,有一种数据结构叫做IRP(I/O Request Package),即输入输出请求包。
上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求。
操作系统将I/O请求转化为相应的IRP数据,不同类型的IRP会被传递到不同的派遣函数中。
IRP有两个基本的重要属性,一个是MajorFunction,另一个MinorFunction,分别记录IRP的主类型和子类型,操作系统根据MajorFunction将IRP“派遣”到不同的派遣函数中,在派遣函数中还可以继续判断这个IRP属于哪种MinorFunction。
下面是HelloDDK的DriverEntry中关于派遣函数的注册:view plaincopy to clipboardprint?#pragma INITCODEextern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegisterPath){NTSTATUS status;KdPrint(("Enter DriverEntry\n"));//设置卸载函数pDriverObject->DriverUnload = HelloDDKUnload;//设置派遣函数pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_SET_INFORMATI ON] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTR OL] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = HelloDDKDispatchRoutine;pDriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTR OL] = HelloDDKDispatchRoutine;//创建驱动设备对象status = CreateDevice(pDriverObject);KdPrint(("Leave DriverEntry\n"));return status;} 2.IRP的类型文件I/O的相关函数,如CreateFile,ReadFile,WriteFile,CloseHandle等函数会使操作系统产生出IRP_MJ_CREATE,IRP_MJ_READ,IRP_MJ_WRITE,IRP_MJ_CLOSE等不同的IRP。
驱动开发学习笔记
驱动开发学习笔记1很久没有网了,出了一段时间的差,近来,莫名的就有点郁闷!前不久在大富翁上发了一份帖子是关于delphi程序员的发展,大家的反应并不都是很好。
于是开始觉得可以考虑换个方向。
以前我是做MIS开发的。
换哪个方向呢?人越多的方向,好像越是没有前途。
想想当初上大学,那可是越多人考的学校,学费越贵啊!可现在的职业呢?越多人干的事,越是没有前途了。
考虑来考虑去,决定学习一下驱动程序的开发吧!于是从网上查找了一些资料,看的懂的觉得蛮不错适合我这种小学生的就贴了出来,算是学习笔记吧!用户模式与内核模式从Intel80386开始,出于安全性和稳定性的考虑,该系列的CPU可以运行于ring0~ring3从高到低四个不同的权限级,对数据也提供相应的四个保护级别。
运行于较低级别的代码不能随意调用高级别的代码和访问较高级别的数据,而且也只有运行在ring0层的代码可以直接对物理硬件进行访问。
由于WindowsNT是一个支持多平台的操作系统,为了与其他平台兼容,它只利用了CPU的两个运行级别。
一个被称为内核模式,对应80x86的ring0层,是操作系统的核心部分,设备驱动程序就是运行在该模式下;另一个被称为用户模式,对应80x86的ring3层,操作系统的用户接口部分(就是我们通常所说的win32 API)以及所有的用户应用程序都运行在该级别。
操作系统对运行在内核模式下的代码是不设防的,所以不管是建设还是破坏内核模式下的编程都是值得去研究的。
图1-WIN2000系统的分层结构在物理硬件与系统核心之间有一个硬件抽象层(HardwareAbstractionLayer),它屏蔽了不同平台硬件的差异,向操作系统的上层提供了一套统一的接口。
从图中我们还可以看到,设备驱动程序(DeviceDriver)是被I/O管理器(I/OManager)包围起来的,即驱动程序与操作系统上层的通信全部都要通过I/O管理器。
这给驱动程序的编写带来了很大的便利,因为很多诸如接收用户的请求、与用户程序交换数据、内存映射、挂接中断、同步等等麻烦的工作都由I/O管理器代劳了。
windows文件核心驱动结构简介、FileMon例程简介、开发注意要点
本帖子是《注册表实时监控拦截》的下篇,也是本系列的最后一篇。
主要讲述如何自己动手做一个在windows系统下的文件操作拦截的小驱动。
利用本驱动,可以实现对本机的所有文件操作请求进行实时监视、拦截,可以完全保护文件系统,在此基础上的进行深入开发后,可以做到文件加密、病毒防护等功能。
本帖子分三个部分:windows文件核心驱动结构简介、FileMon例程简介、开发注意要点。
一、windwos文件核心驱动结构简介在windows操作系统中(NT以上版本),规定了一套严格的文件操作请求处理流程,总体结构如下图:在图中上部分有一条虚线,这是“用户态”软件和“核心驱动”的分界线(用户态软件可以理解为普通的、可见的软件,如各类exe类型的软件)。
当用户态软件需要操作文件时,则发出文件操作请求,然后统一发送给系统的I/O管理器,I/O管理器把这个操作请求依次向下传递给“文件系统驱动”、“磁盘驱动”等,后者执行真正的文件操作。
上图是在本机上进行文件操作的流程,那么在访问网络上的文件,则处理流程如下:可以看到,在目标计算机(即文件所处的计算机)上,文件操作请求同样经过了“本地文件系统”和“磁盘驱动”,在这一点上,两者没有区别。
那么,如果我们要自己做一个文件的驱动,应该放在什么位置?下图给出了详细的“自定义驱动”的插入位置:图中以深色表示的部分,即留给用户可以插入“自定义驱动”的位置,可以看到,新插入的驱动和系统的驱动是“串接”在一起的。
所以,所有的文件操作均会通过“自定义驱动”(当然了,如果有人又开发了另外一个驱动,并插入到你所开发的驱动的下面,然后不通过正规的文件驱动而是直接发送消息到下层他的驱动,这样是拦截不到的)。
此时,你可以在你的驱动中很悠闲地处理这些请求,而且想啥时候丢弃、修改这些文件请求,那是全凭自己的心情了。
二、FileMon例程简介在了解了windows文件核心驱动的大致结构后,我们可以动手来试试了。
Windows驱动开发入门
接触windows驱动开发有一个月了,感觉Windows驱动编程并不像传说中的那么神秘。
为了更好地为以后的学习打下基础,记录下来这些学习心得,也为像跟我一样致力于驱动开发却苦于没有门路的菜鸟朋友们抛个砖,引个玉。
我的开发环境:Windows xp 主机+ VMW ARE虚拟机(windows 2003 server系统)。
编译环境:WinDDK6001.18002。
代码编辑工具:SourceInsight。
IDE:VS2005/VC6.0。
调试工具:WinDBG,DbgView.exe, SRVINSTW.EXE上面所有工具均来自互联网。
对于初学者,DbgView.exe和SRVINSTW.EXE是非常简单有用的两个工具,一定要装上。
前者用于查看日志信息,后者用于加载驱动。
下面从最简单的helloworld说起吧。
Follow me。
驱动程序的入口函数叫做DriverEntry(PDRIVER_OBJECT pDriverObj,PUNICODE_STRING pRegisgryString)。
两个参数,一个是驱动对象,代表该驱动程序;另一个跟注册表相关,是驱动程序在注册表中的服务名,暂时不用管它。
DriverEntry 类似于C语言中的main函数。
它跟main的差别就是,main完全按照顺序调用的方法执行,所有东西都按照程序员预先设定的顺序依次发生;而DriverEntry则有它自己的规则,程序员只需要填写各个子例程,至于何时调用,谁先调,由操作系统决定。
我想这主要是因为驱动偏底层,而底层与硬件打交道,硬件很多都是通过中断来与操作系统通信,中断的话就比较随机了。
但到了上层应用程序,我们是看不到中断的影子的。
说到中断,驱动程序中可以人为添加软中断,__asm int 3或者Int_3();前者是32位操作系统用的,后者是64位用的。
64位驱动不允许内嵌汇编。
下面是我的一个helloworld的源码:注意第16行的宏。
(完整版)WINDOWS笔记
(完整版)WINDOWS笔记一、鼠标的操作:单击:按下按键后放开,分左/右单击.左单击用于选定对象或执行菜单命令、按钮事件。
单击右键用于打开鼠标相应位置的“快捷菜单"或“控制菜单”。
双击:快速连续单击两次按钮.一般只有左键双击.用于打开所选定的对象或程序文件.三击:在WORD中选中一个段落。
拖动:对着目标按下左键不放同时移动鼠标,到目的地方后放开鼠标。
二、键盘的操作:ESC键-—取消当前操作。
Ctrl+Alt+ Del:(1)强行退出一个应用程序(按一次)(2) 热启动(连续按两次)F1: 启动Windows98帮助系统SHIFT的作用:(1)对双字符键(2) 临时切换大小写Capslock大写锁定键:(1) 灯亮-大写 (2) 不亮—小写Numlock:小键盘Printscreen:屏幕打印Home: 行首End:行末三、Windows2000桌面组成(一)图标:代表一个对象,可以是文件夹,应用程序或快捷方式(二)“开始"按钮1关闭系统2运行—-运行一个应用程序(*.exe)3帮助—-启动帮助系统4查找-—查找计算机或文件或文件夹5设置——-改变系统效果;如桌面、图片、鼠标6文档-—记录15个最近打开的文档7收藏夹——收藏各种热门信息8程序-—运行应用程序(系统目录、用户安装)(三)任务栏作用:(1)记录(2)切换应用程序(当前〈仅有一个>、后台)(ALT+TAB)(3)管理练习:用查找方法在C盘找出:(1 )纸牌(sol。
exe) (2)扫雷(Winmine.exe)(3)WINWORD。
EXE (4) EXCEL.EXE四、窗口操作(一)、窗口(windows)--计算机与用户之间对话的界面;一个窗口代表一个应用程序或文件夹(二)、组成:(1)标题栏——显示当前窗口的名称、状态(前台〈仅有一个>、后台)(2)菜单栏——执行若干命令(横向、纵向—-—弹出式菜单)(3)工具栏—-命令的快捷按键:(1)显示 (2)隐藏(4)主窗体——工作区域(5)滚动条—-(水平、垂直)可观察其余的不可见内容(6)状态栏—-显示当前窗口的信息.(三)、窗口的操作(1)移动窗口—-指针位于标题栏、按住<左键>并移动,或按“最小化”“还原(还原到用户最后一次定义的大小)”“最大化”按扭(2)缩放窗口:宽高对角线(3)关闭:单击“关闭"按扭或“Alt+F4”或“文件" 退出五、任务栏的操作:(一)、任务栏:记录当前正在运行的应用程序并进行管理前台:高亮度、可操作(蓝色)(仅有一个) (凹)后台:非高亮度、不可操作(灰色)(凸)(二)、操作(1)切换应用程序——在任务栏上单击某应用程序(ALT+TAB)(2)移动任务栏——按鼠标左键直接拖动任务栏(3)隐藏任务栏——指针在任务栏上按右键属性(4)利用任务栏设置时间、日期——双击时间按扭六、菜单操作:(一)、类型:(1)横向(2)纵向(即弹出式菜单)(3)快捷菜单:使用右键启动某个对象的控制菜单(二)、菜单的某些约定:(1)“”表示有下一级子菜单(2)“…”该菜单的将打开一个对话框(3)“√”命令开关按扭可选多个“●" 只能选一个(4)“字母”启动菜单的快捷键(方法:ALT+相应菜单的字母)(三)、对话框作用(1)提供提示信息(2)接受用户输入信息(四)、对话框组成(1)文本输入框:供用户输入自定义内容(出现光标时才能输入)(2)列表:将可供选择的内容以表格形式显示,供用户选择:(1)普通列表(2)下拉列表:将表的内容编成一个下拉三角(3)单选框:在一组单选框中只能选中一个选项”●”(3)复选框:在一组复选框中能选中多个选项"√"(4)命令按扭:激活一系列的动作或命令(5) 选项卡七、文件管理(一)、文件:保存计算机信息(数据)的最小单位.(一组相关数据<文字、数字、符号、字母、声音图像〉的集合) 。
Windows驱动开发技术详解 第六章的(Windows内核函数)自我理解
Windows驱动开发技术详解第六章的(Windows内核函数)自我理解学习各种高级外挂制作技术,马上去百度搜索(魔鬼作坊),点击第一个站进入,快速成为做挂达人。
其实这章主要就是讲函数DDK有自己的函数跟SDK一样编写DDK使用DDK提供的函数就OK了///////////////////////////////////////////////////////////////////////////////ASCII字符串和宽字符串ASCII字符构造char*str1="abc";打印ASCII字符串char*string="hello";KdPrint("%s\n",string);\\注意是小写%s/////UNICODE字符构造wchar_t*str2=L"abc";打印宽字符串WCHAR*string=L"hello";KdPrint("%S\n",string);\\注意是大写%S///////////////////////////////////////////////////////////////////////////////ANSI_STRING字符串和UNICODE_STRING字符串ASCII字符串进行了封装typedef struct_STRING{USHORT Length;//字符的长度。
USHORT MaximumLength;//整个字符串缓冲区的最大长度。
PCHAR Buffer;//缓冲区的指针。
}STRING;输出字符串ANSI_STRING ansiString;KdPrint("%Z\n",&ansiString);//注意是%ZUNICODE_STRING宽字符串封装typedef struct_UNICODE_STRING{USHORT Length;//字符的长度,单位是字节。
李银辉windows驱动开发教程
李银辉windows驱动开发教程李银辉Windows驱动开发教程在计算机领域中,驱动程序是操作系统与硬件设备之间的桥梁,起到了关键的作用。
Windows操作系统中的驱动开发,是指为硬件设备编写相应的驱动程序,以实现操作系统与设备的通信和协同工作。
本篇文章将介绍李银辉编写的Windows驱动开发教程,帮助读者了解和掌握该领域的知识和技术。
一、什么是Windows驱动开发?Windows驱动开发是指为Windows操作系统编写设备驱动程序的过程。
驱动程序是操作系统的核心组成部分,负责管理和控制计算机硬件设备的工作。
通过编写驱动程序,可以实现对硬件设备的访问和控制,使其能够与操作系统无缝协同工作。
二、为什么需要学习Windows驱动开发?随着计算机技术的不断发展,硬件设备的种类和数量也在不断增加。
为了更好地支持和兼容各种硬件设备,Windows操作系统提供了丰富的驱动开发接口和工具。
学习Windows驱动开发可以帮助我们理解和掌握操作系统与硬件设备之间的交互原理,为开发高性能、高可靠性的驱动程序提供基础。
三、李银辉Windows驱动开发教程的特点作为国内著名的Windows驱动开发专家,李银辉编写的驱动开发教程具有以下特点:1.系统全面:李银辉的教程从驱动开发的基础知识开始讲解,逐步深入,涵盖了驱动程序开发的方方面面。
读者可以系统地学习和掌握驱动开发的各个环节和技术。
2.实践性强:李银辉的教程以实际案例为基础,通过编写具体的驱动程序来讲解相关的知识和技术。
读者可以通过实际的编程练习,加深对驱动开发原理和方法的理解。
3.案例丰富:李银辉的教程提供了大量的案例代码和实验,覆盖了多种设备类型和应用场景。
这些案例可以帮助读者更好地理解和应用所学知识,提升驱动开发的实际能力。
4.实用性强:李银辉的教程注重实用性,重点介绍了一些常见的驱动开发技术和工具,以及解决实际问题的方法。
读者可以通过学习这些内容,提高自己的驱动开发水平。
《Windows核心编程》读书笔记
第一部分程序员必读Szq整理使用第1章对程序错误的处理(1)常见的Windows函数的返回类型:VOID:无返回值型,该函数的运行不可能失败。
Windows函数很少此类型BOOL:函数运行失败则返回0,否则返回非0HANDLE:失败则返回NULL,否则返回一个可操作的对象的Handle。
注:有些函数会返回一个句柄值INVALID_HANDLE_VALUE,?它被定义为-1。
函数的Platform? SDK 文档将会清楚地说明该函数运行失败时返回的是NULL还是INVALID_HANDLE_VALIDPVOID :函数运行失败,则返回值是NULL,否则返回PVOID,以标识数据块的内存地址LONG/DWORD:这是个难以处理的值。
返回数量的函数通常返LONGDWORD。
如果由于某种原因,函数无法对想要进行计数的对象进行计数,那么该函数通常返回0或-1(根据函数而定)。
如果调用的函数返回了LONG/DWORD,那么请认真阅读 Platform SDK文档以确保能正确?检查潜在的错误。
(2)当某Windows函数运行错误时,可以通过调用 DWORD GetLast Error()函数获取调用该函数的关联线程的32位错误代码。
其具体的错误文本以列表形式存放于WinError.h头文件中,在VC中调试时,也可以通过在Watch 窗口键入“@err,hr”来获取所调用函数的运行错误代码和具体的错误文本。
(3)Windows还提供了一个函数,可以将错误代码转换成它的文本描述。
该函数称为FormatMessage,该函数的格式如下:DWORD FormatMessage(DWORD dwFlags,LPCVOID pSource,DWORD dwMessageID,DWORD dwLanguageID,PTSTR pszBuffer,DWORD nSize,va_list *Argument);2004年11月8号Trackback: /TrackBack.aspx?PostId=174570第一章程序员必读1.1定义自己的错误代码若你编写了一个希望其他人调用的函数,你的函数可能因为这样或那样的原因而运行失败,你必须向函数的调用者说明它已经运行失败。
[笔记]《Windows核心编程(第5版)》
[笔记]《Windows核⼼编程(第5版)》[第三章 内核对象]区分内核对象和⽤户/GDI对象的⽅法:⼏乎所有创建内核对象的函数都有⼀个允许指定安全属性的参数。
句柄实际作为进程句柄表的索引来使⽤(句柄值为4的倍数,操作系统内部使⽤了最后类位)⽆论以什么⽅式创建的内核对象,都要调⽤CloseHandle关闭之(从进程句柄表中删除,内核对象本⾝不⼀定销毁,因为可能还有其他进程在⽤)。
当进程终⽌运⾏,操作系统会确保此进程所使⽤的所有资源都被释放。
这适⽤于所有内核对象、资源(包括GDI对象)以及内存块。
世界上根本没有“对象继承”,Windows⽀持的是“对象句柄的继承”,换⾔之,只有句柄才是可以继承的,对象本⾝不能继承。
内核对象的内容被保存在内核地址空间中——系统上运⾏的所有进程都共享这个空间。
进程间共享内核对象的三种机制:使⽤对象句柄继承、为对象命名、复制对象句柄。
[第四章 进程]进程在终⽌后绝对不会泄露任何东西[第六章 线程基础]进程从来不执⾏任何东西,它只是⼀个线程的容器。
窗⼝只⽤⼀个线程新创建的线程可以访问进程内核对象的所有句柄、进程中的所有内存以及同⼀个进程中其他所有线程的栈。
⽤_beginthreadex⽽不要⽤CreateThread创建线程GetCurrentProcess和GetCurrentThread返回的是伪句柄,不会在主调进程的句柄表中新建句柄,也不会影响进程内核对象或线程内核对象的使⽤计数。
可使⽤DuplicateHandke将伪句柄转换为真正的句柄。
[第七章 线程调度、优先级和关联性]任何线程都可以调⽤SuspendThread函数挂起另⼀个线程(只要有线程的句柄);线程可以将⾃⼰挂起,但⽆法⾃⼰恢复;⼀个线程最多可以挂起MAXIMUN_SUSPEND_COUNT(WinNT.h中定义为127)次。
Windows中不存在挂起和恢复进程的概念,因为系统从来不会给进程调度CPU时间。
windows核心编程(第五版)笔记第十一章线程池(thewindowsthrea
windows核心编程(第五版)笔记第十一章线程池(thewindowsthrea...Windows核心编程(第五版)笔记第十一章线程池(The Windows Thread Pool)第十一章线程池线程池的目的就是为了减少创建和销毁线程的额外开销,利用已经存在的线程多次循环执行多个任务从而提高系统的处理能力.线程池会自动地根据内制的算法增加或减少线程池中的线程或为程序增加新的线程池。
1.异步方法调用异步方法调用有以下两种方法:(1)线程函数原型(回调函数)VOID NTAPI SimpleCallback(PTP_CALLBACK_INSTANCE pInstance, // See "Callback Termination Actions" sectionPVOID pvContext);TrySubmitThreadpoolCallback该函数将线程函数执行请求发到线程池,并将一个"工作项目"添加到线程池的队列中。
注:我们不需要调用CreateThread函数,线程池中的线程会执行我们的回调函数(2)显示控制"工作项目"CreateThreadpoolWork 创建一个工作项目SubmitThreadpoolWork 将工作项目提交到线程池中,一个工作项目可以多次提交到线程池中。
WaitForThreadpoolWorkCallbacks 等待线程函数执行完毕或取消执行线程函数。
CreateThreadpoolWork 要求的线程函数原型:VOID CALLBACK WorkCallback(PTP_CALLBACK_INSTANCE Instance,PVOID Context,PTP_WORK Work);VOID WaitForThreadpoolWorkCallbacks(PTP_WORK pWork,BOOL bCancelPendingCallbacks);2.时间间隔内调用函数(1)CreateThreadpoolTimer要求的线程函数原型VOID CALLBACK TimeoutCallback(PTP_CALLBACK_INSTANCE pInstance, // See "Callback Termination Actions" sectionPVOID pvContext,PTP_TIMER pTimer);(2)步骤CreateThreadpoolTimerSetThreadpoolTimerWaitForThreadpoolTimerCallbacks CloseThreadpoolTimer3.当内核对象处于Signal状态时调用函数当指定的内核对象变成Signal状态或等待超时,线程池会用户指定的线程函数。
操作系统内核的基础知识和编程技巧
操作系统内核的基础知识和编程技巧操作系统内核是操作系统的核心组件,它负责管理计算机的硬件资源、提供用户程序运行的环墶并为用户程序的运行提供必要的支持。
操作系统内核开发需要对计算机体系结构有深入的了解,同时也需要掌握一定的程序设计和系统调用技巧。
本文将介绍操作系统内核的基础知识和编程技巧,包括内核的结构和功能、内核的开发过程、系统调用和中断处理等内容。
内核的结构和功能操作系统内核通常由若干个模块组成,每个模块负责不同的功能。
常见的内核模块包括进程管理模块、文件系统模块、内存管理模块、设备驱动模块等。
这些模块相互协作,共同完成操作系统的功能。
下面我们来详细介绍一下常见的内核模块及其功能。
1.进程管理模块进程管理模块负责创建、调度和终止进程,它需要维护进程控制块(PCB)来保存进程的状态信息,包括进程的ID、状态、运行时间等。
进程管理模块还需要实现进程的调度算法,如先来先服务(FCFS)、短作业优先(SJF)、优先级调度等。
此外,进程管理模块还需要提供进程间通信和同步机制,如信号量、互斥锁、条件变量等。
2.文件系统模块文件系统模块负责管理存储设备上的文件和目录,它需要实现文件的创建、删除、打开、关闭、读写等操作。
文件系统模块还需要实现文件的组织结构和文件的物理存储管理,包括索引节点(inode)的管理、块的分配和释放等。
3.内存管理模块内存管理模块负责管理物理内存和虚拟内存,它需要实现内存的分配和释放、页面置换算法、地址映射等。
内存管理模块还需要实现页面的写保护、内存的共享和内存的保护机制。
4.设备驱动模块设备驱动模块负责管理计算机的输入输出设备,它需要实现设备的初始化、读写操作和中断处理等。
设备驱动模块还需要管理设备的中断请求(IRQ)和直接内存访问(DMA),以提高设备的性能。
内核的开发过程内核的开发通常包括内核的设计、编码、测试和部署等过程。
下面我们来介绍一下内核的开发过程。
1.内核的设计内核的设计是内核开发的第一步,它需要明确内核的功能和接口,确定内核的模块和模块间的关系,设计内核的数据结构和算法。
【驱动笔记1】第一个驱动程序
【驱动笔记1】第一个驱动程序学习各种高级外挂制作技术,马上去百度搜索"魔鬼作坊",点击第一个站进入,快速成为做挂达人。
驱动程序的开发,向来是令人感到有所畏惧的,可能很多人像我一样,看了很久却还是一头雾水,不得其门而入。
我们今天就通过一个简单的程序来使读者学会初步的驱动程序开发。
在开发Windows驱动程序之前,我们需要首先安装DDK,Win98及其以前的VxD我们就不要再考虑了;Windows2000DDK也比较老了点,很少有人使用了,微软最新的WDK貌似都不支持2000了;在本文中假设我们已经安装了Win XP DDK或2003DDK(2003会包括XP)。
驱动开发通常有两种环境,一种是使用任意文本编辑器来编写代码,然后通过编写makefile 和sources文件在WinDDK的命令行环境下使用build命令编译;另一种方法是使用各种各样的方法以图可以利用IDE的环境来搭建驱动框架,比如使用驱动向导文件或一些小工具,我经常使用的是EasySys这个小工具。
废话不多说了,假设我们已经通过EasySys生成了一个驱动框架,现在我们就向里面添加代码。
下面我们编写了一个函数,它的作用是根据形参来创建一个文件,形参中给出了将要被创建的文件完整路径。
(注意,以下程序有许多错误,具体请看后面的讲解)BOOL CreateFileTest(IN PUNICODE_STRING FileName){BOOL bRet=FALSE;HANDLE hFile=NULL;NTSTATUS status;IO_STATUS_BLOCK Io_Status_Block;//初始化文件路径OBJECT_ATTRIBUTES obj_attrib;InitializeObjectAttributes(&obj_attrib,&FileName,OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE,NULL,NULL);//创建文件status= ZwCreateFile(hFile,GENERIC_ALL,NULL,Io_Status_Block,NULL,FILE_ATTRIBUTE_NORMA L,FILE_SHARE_READ,FILE_CREATE,FILE_NON_DIRECTORY_FILE| FILE_SYNCHRONOUS_IO_NONALERT,NULL,0);if(Io_Status_rmation!=FILE_CREATED){bRet=FALSE;}else{bRet=TRUE;}if(hFile){ZwClose(hFile);}return bRet;}当我们激动地编译上述程序时,却很郁闷地发现编译器报出了十几个错误,不要急,这是大多数新手都必须要跨过的一个坎儿。
WINDOWS内核学习清单·EXP
WINDOWS内核学习清单·EXP•WINDOWS 内核学习顺序指引清单o前言o 1. 基础知识▪ 1.1. 驱动框架(NT和WDM)▪ 1.2. 驱动基础(编程概念、内核函数、基本数据结构等等)▪ 1.3. 驱动通信(R3主动与R0通信、R0主动与R3交互)▪ 1.4. 基本操作(系统线程、工作队列、计时器、字符串、内存、链表等等等等)o 2. 进程相关▪ 2.1. 枚举进程(PID、EPROCESS、进程路径等)▪ 2.2. 结束进程(多种方法)▪ 2.3. 挂起进程▪ 2.4. 恢复进程▪ 2.5. 保护进程(API HOOK、回调)▪ 2.6. 隐藏进程(API HOOK、DKOM)▪ 2.7. 枚举线程▪ 2.8. 结束线程(多种方法)▪ 2.9. 挂起线程▪ 2.10. 恢复线程▪ 2.11. 枚举DLL(多种方法)▪ 2.12. 卸载DLL▪ 2.13. 注入DLL/SHELLCODE(NT6注入到系统进程)▪ 2.14. RING3 INLINE HOOK/UNHOOK/绕过(多种方法)▪ 2.15. RING3 EAT HOOK/UNHOOK▪ 2.16. RING3 IAT HOOK/UNHOOK▪ 2.17. 窗口操作(枚举、发消息、隐藏/显示、启用/禁用等)▪ 2.18. 内存操作(枚举、申请、释放、读写、修改保护类型等)▪ 2.19. 消息钩子(枚举、删除)▪ 2.20. 内核回调表(枚举、清除HOOK)▪ 2.21. 枚举句柄▪ 2.22. .关闭句柄▪ 2.23. 监控进程创建/退出(API HOOK、回调)▪ 2.24. 监控线程创建/退出(API HOOK、回调)▪ 2.25. 监控DLL加载(API HOOK、回调)o 3. 文件相关▪ 3.1. API层文件操作(枚举、复制、删除、重命名)▪ 3.2. FSD层文件操作(枚举、复制、删除、重命名)▪ 3.3. DISK层文件操作(读写)▪ 3.4. 解析NTFS/FAT32▪ 3.5. 监控文件操作(API HOOK、SFILTER、MINIFILTER)o 4. 注册表相关▪ 4.1. API层注册表操作(枚举、新建、删除、重命名)▪ 4.2. 解析HIVE操作注册表▪ 4.3. 监控注册表操作(API HOOK、回调、DKOH)o 5. HOOK相关▪ 5.1. SSDT HOOK/UNHOOK(包括SHADOW SSDT)▪ 5.2. INLINE HOOK/UNHOOK/绕过(多种方法)▪ 5.3. IRP HOOK▪ 5.4. OBJECT HOOK/UNHOOK▪ 5.5. IDT HOOK/UNHOOK▪ 5.6. EAT HOOK/UNHOOK▪ 5.7. IAT HOOK/UNHOOK▪ 5.8. MSR HOOK/UNHOOKo 6. 内核相关▪ 6.1. 枚举内核模块(链表、目录对象、暴搜)▪ 6.2. 监控驱动加载(API HOOK、回调)▪ 6.3. 枚举/删除回调(进程、线程、映像、注册表、蓝屏、关机、对象、文件系统改变)▪ 6.4. 枚举/删除定时器(IO/DPC)▪ 6.5. 枚举GDTo7. 网络相关▪7.1. 内核网络通信(TDI、WSK)▪7.2. 监控网络通信(WFP、TDI HOOK、NDIS HOOK、NDIS FILTER)▪7.3. 枚举网络连接(API方法、发IRP法)▪7.4. 枚举/挂钩NDIS处理函数▪7.5. 流量统计/下载限速▪7.6. 端口复用o8. 64位系统专用▪8.1. 破解PATCHGUARD(动态/静态)▪8.2. 破解DSE(动态/静态)o9. 杂项▪9.1. 对象劫持▪9.2. 符号操作▪9.3. PE解析▪9.4. 反调试o10. 整体项目▪10.1. PE工具▪10.2. ARK▪10.3. 调试器▪10.4. 主动防御▪10.5. 沙箱▪10.6. 透明加密▪10.7. VT级调试/反调试/主动防御o11. 其他▪11.1. MFC开发WINDOWS 内核学习顺序指引清单前言鉴于很多同学想学习逆向工程,但是找不到切入点导致无从入手,因此编写了这个指引清单。
WINDOWS内核学习步骤
(一)内核驱动入门 1.驱动级HelloWorld 2.驱动框架理解
WINDOWS内 核 学 习 步 骤
(二)内核开发基础 3.驱动级文件与注册表操作 4.中断运行级别 5.同步与多线程 6.内核数据结构 7.应用程序与驱动通信与弹窗
(三)内核高级技术 8.DKOM 9.HOOK/DKOH 10.回调(进程/线程/模块/注册表等) 11.文件系统(sfilter/minifilter) 12.网络驱动(tdi/ndis/wfp) 13.PE文件结构/汇编与逆向(ida/ollydbg)
(四)内核编程综合应用 14.主防(HIPS) 15.沙盘(SANDBOX) 16.防火墙(TDI/NDIS/WFP) 17.ARK/基于MBR和BIOS的BOOTKIT技术分析与查杀 18.程序逆向/病毒分析
ห้องสมุดไป่ตู้
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Windows 内核技术与驱动开发笔记
1.简述Driver Entry例程
动程序的某些全局初始化操作只能在第一次被装入时执行一次,而Driver Entry例程就是这个目的。
* Driver Entry是内核模式驱动程序主入口点常用的名字。
* Driver Entry的第一个参数是一个指针,指向一个刚被初始化的驱动程序对象,该对象就代表你的驱动程序。
WDM驱动程序的Driver Entry例程应完成对这个对象的初始化并返回。
非WDM驱动程序需要做大量额外的工作,它们必须探测自己的硬件,为硬件创建设备对象(用于代表硬件),配置并初始化硬件使其正常工作。
* Driver Entry的第二个参数是设备服务键的键名。
这个串不是长期存在的(函数返回后可能消失)。
如果以后想使用该串就必须先把它复制到安全的地方。
* 对于WDM驱动程序的Driver Entry例程,其主要工作是把各种函数指针填入驱动程序对象,这些指针为操作系统指明了驱动程序容器中各种例程的位置。
2.简述使用VC进行内核程序编译的步骤
编译方式是使用VC++进行编译
1.用VC新建工程。
2.将两个源文件Driver.h和Driver.cpp拷贝到工程目录中,并添加到工程中。
3.增加新的编译版本。
4.修改工程属性,选择“project | setting”将IterMediate file和Output file 都改为MyDriver_Check。
5.选择C/C++选项卡,将原有的Project Options内容全部删除替换成相关参数。
6.选择Link选项卡,将原有的Project Options内容删除替换成相关Link。
7.修改VC的lib目录和include的目录。
8.在VC中选择tools | options,在弹出的对话框中选择“Directories”选项卡,在“Show directories for”下拉菜单中选择“Include file”菜单。
添加DDK的相关路径。
3.简述单机内核调试技术
答:1.下载和安装WinDbg能够调试windows内核模块的调试工具不多,其中一个选择是微软提供的WinDbg
下载WinDbg后直接双击安装包执行安装。
2.安装好虚拟机以后必须把这个虚拟机上的windows设置为调试执行。
在被调试系统2000、2003或是xp的情况下打开虚拟机中的windows系统盘。
3.将boot.ini文件最后一行复制一下,并加上新的参数使之以调试的方法启动。
重启系统,在启动时就可以看到菜单,可以进入正常windows xp,也可以进入Debug模式的windows xp。
4.设置VMware管道虚拟串口。
调试机与被调试机用串口相连,但是有被调试机是虚拟机的情况下,就不可能用真正的串口连接了,但是可以在虚拟机上生成一个用管道虚拟机的串口,从而可以继续内核调试。
4.请画出Windows架构简图
Windows 结构简图
5.对象管理程序的作用
Windows操作系统中提供的所有服务几乎是以对象的形式存在。
对象管理器程序就是创建、管理、回收、这些对象的组建涉及很多对象,如驱动程序对象、设备对象等。
6.写出打开注册表的内核函数原型
NTSTATUS
ZwOpenksy(
OUT PHANDLE key Handle
IN ACCESS_MASK
Desired Access
IN POBJECT_ATT
IN ACCESS_MASK
Desired Access
IN POBJECT_ATTRIBUTES
ObjectAttributes
);
7.画出I/O请求包数据结构图
8.简述I/0堆栈
任何内核模式程序在创建一个IRP时,同时还创建了一个与之关联的IO_STACK_LOCATION结构数组:数组中的每个堆栈单元都对应一个将处理该IRP的驱动程序。
另外还有一个堆栈单元供IRP的创建者使用。
堆栈单元中包含该IRP的类型代码和参考信息以及完成函数的地址。
9.写出常见的四种创建IRP的内核函数
* 可以使用下面任何一种函数创建IRP:
* Io Bulid Asgnechronous Fsd Request创建异步IPR(不需要等待其完成)。
该函数和下一个函数仅适用于创建某些类型的IRP
* Io Build Synchronous Fsd Request创建同步IRP(需要等待其完成)
* Io Build Devicelo Control Request 创建一个同步IRP_MJ_DEVICE_CONTROL或IRP_MJ_INTERNAL_DEVICE CONTROL 请求
* Io Allocatelrp创建上面桑函数不支持的其他种类的IRP
10.简述分层驱动技术
分层驱动是指两个或两个以上的驱动程序,他们分别建立设备对步。
并且形成一个由高到低的设备对象栈。
IRP异步会被传送到设备栈的最顶层的设备对象,顶层的设备可以选择直接结束IRP请求。
也可以选择将IRP请求向下层的设备对象转发。
如果是向下层的对象设备转发IRP请求。
当IRP请求结束时,IRP顺着设备栈的反方向原路返回。
当得知下层驱动程序已经结束IRP请求时,本层设备对象可以选择继续将IRP向上返回或者重新将IRP再次传递到底层设备驱动。