麦洛克菲内核驱动开发第六课.ppt_第1页
麦洛克菲内核驱动开发第六课.ppt_第2页
麦洛克菲内核驱动开发第六课.ppt_第3页
麦洛克菲内核驱动开发第六课.ppt_第4页
麦洛克菲内核驱动开发第六课.ppt_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

麦洛克菲内核开发第五课 Sfilter文件系统过滤,麦洛克菲 ,周扬荣,麦洛克菲,提纲,文件系统驱动 绑定与过滤 Sfilter基本框架 文件拦截 创建 删除 修改 重命名 作业,麦洛克菲,过滤,文件过滤驱动设备,文件卷设备,磁盘设备,IRP,驱动设备,IRP,过滤:分层驱动中再加一层而不影响它的上下层,以过滤它们之间的数据,对数据或行为进行安全控制。过滤是通过设备绑定实现的。,绑定,设备栈绑定的形式。驱动自己生成一个设备(过滤设备),调用系统提供的绑定API,绑定到目标设备上。并返回一个在未绑定之前目标设备所在设备栈的最顶层设备。这样发往下层的IRP或者发往上层的数据都会被过滤设备截获。 绑定API: IoAttachDevice() IoAttachDeviceToDeviceStackSafe(2000 SP4以及XP以上) IoAttachDeviceToDeviceStack(),IoAttachDeviceToDeviceStack,PDEVICE_OBJECT IoAttachDeviceToDeviceStack( IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice ); AttachedDevice需要记录在DEVICE_EXTENSION中,以便调用IoCallDriver()继续下发IRP,文件系统过滤框架,Filemon Sfilter Minifilter Filespy,Sfilter总体流程,创建控制设备 创建控制设备符号链接 过滤分发函数 Fastio 过滤与绑定 生成一个过滤设备 IoRegisterFsRegistrationChange( DriverObject, SfFsNotification ); (文件系统设备绑定) SfFsControl (卷设备绑定) 一个驱动,看见几个文件系统设备,看见几个卷设备,对应每一个设备就生成相应设备附载上去,然后进行相应处理。,IoRegisterFsRegistrationChange,FileMon里的方法: 枚举26个盘符,打开文件,获得FileObjectDeviceObject. 然后通过自己驱动生成一个过滤设备,Attach过滤设备到DeviceObject上 无法监控类似U盘等动态加载上去的 IoRegisterFsRegistrationChange动态获得,fastio,文件系统除了处理正常的IRP之外,还要处理所谓的FastIo. FastIo是Cache Manager调用所引发的一种没有irp的请求。换句话说,除了正常的Dispatch Functions之外,你还得为DriverObject撰写另一组Fast Io Functions. 这组函数的指针在driver-FastIoDispatch,Sfilter代码通读分析,DriverEntry sfCreate,再次深入理解IRP,过滤驱动与IRP处理方式,a.Pending完成例程 IoCopyCurrentIrpStackLocationToNext b.忽略直接下发 IoSkipCurrentIrpStackLocation,下层设备拿到的IO_STACKLOCATION 和当前的一样 c.结束IRP不下发 PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation (Irp); Irp-IoStatus.Status = STATUS_SUCCESS; Irp-IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); d.手动构建IRP IoAllocateIrp IoGetNextIrpStackLocation,IRP注意事项,在驱动程序将IRP 传递个下一个驱动之后,就不再拥有这个IRP,并且不能试图再去访问它。否则会导致系统崩溃。那个IRP 会被其它的驱动或者线程释放或完成。如果驱动需要访问一个已经在栈里传下去的IRP,这个驱动必须实现并设置IoCompletion 例程。当I/O管理器调用IoCompletion 例程时,这个驱动就能够在IoCompletion 例程执行期间重新获得对这一IRP 的所有权。如此,IoCompletion 例程就能够访问IRP 中的域。 若是驱动的分发例程也还须在IRP 被后面的驱动处理完成之后再处理它,这个IoCompletion例程必须返STATUS_MORE_PROCESSING_REQUIRED,以将IRP 的所有权返回给分发例程。如此一来,I/O 管理器会停止IRP 的处理,将最终完成IRP 的任务留给分发例程。分发例程能够在之后调用ICompleteRequest 来完成这个IRP,或者还能将这个IRP 标记为等候进一步处理。,Pending完成例程,KEVENT event; KeInitializeEvent( ,NTSTATUS CompRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) Irp-UserIosb-Status = Irp-IoStatus.Status; Irp-UserIosb-Information = Irp-IoStatus.Information; KeSetEvent(Irp-UserEvent, IO_NO_INCREMENT, FALSE); /IoFreeIrp(Irp); return STATUS_MORE_PROCESSING_REQUIRED; ,忽略直接下发,对IRP没有任何改动的时候,比如放行: PDEVICE_EXTENSION deviceExtension; IoSkipCurrentIrpStackLocation(Irp); /拿到保存在设备扩展里的下层设备 deviceExtension = (PDEVICE_EXTENSION) DeviceObject-DeviceExtension; /下发 return IoCallDriver( deviceExtension-TargetDeviceObject, Irp);,拷贝直接下发,/ Forward request to next driver IoCopyCurrentIrpStackLocationToNext( Irp ); / Send the IRP down status = IoCallDriver( nextDevice, Irp ); / The following is an error because this driver / no longer owns the IRP. If (status = STATUS_PENDING) IoMarkIrpPending( Irp );/错误,无权操作Irp了 / Return the lower drivers status return status;,自己构建IRP下发,IoAllocateIrp /IoBuildDeviceIoControlRequest IoGetNextIrpStackLocation 例子: 强制删除文件 Sfilter里查询文件名字,非过滤驱动中的默CommonDispatch,NTSTATUS CommonDispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp) Irp-IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; ,过滤驱动中CommonDispatch写法,NTSTATUS SfPassThrough ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) PIO_STACK_LOCATION pIrp = IoGetCurrentIrpStackLocation( Irp ); ASSERT(!IS_MY_CONTROL_DEVICE_OBJECT( DeviceObject ); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ); if (!IS_MY_DEVICE_OBJECT(DeviceObject) | IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject) NTSTATUS status = Irp-IoStatus.Status = STATUS_INVALID_PARAMETER; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( (PSFILTER_DEVICE_EXTENSION) DeviceObject-DeviceExtension)-NLExtHeader.AttachedToDeviceObject, Irp ); ,分发过滤函数,FilterCreate(创建) FilterRead(一般不拦,加解密处理) FilterWrite(修改,加解密处理) FilterSetInfo(删,重命名) FilterClose(一般不拦) FilterClean(写关闭等) 等,API流程,CreateFile,ntCreateFile,zwCreateFile,IRP_MJ_CREATE,过滤设备,卷设备,磁盘设备,CreateFilter,DispatchCreate,IRP,Ntdll.dll,ring3,ring0,再次深入理解设备对象,设备对象类别,Sfilter自己的设备 控制设备 过滤设备 其它设备 文件系统设备 卷设备 设备类别 FILE_DEVICE_DISK_FILE_SYSTEM,#define IS_MY_DEVICE_OBJECT(_devObj) (_devObj) != NULL) & (_devObj)-DriverObject = gSFilterDriverObject) & (_devObj)-DeviceExtension != NULL) #define IS_MY_CONTROL_DEVICE_OBJECT(_devObj) (_devObj) = gSFilterControlDeviceObject) ? (ASSERT(_devObj)-DriverObject = gSFilterDriverObject) & (_devObj)-DeviceExtension = NULL), TRUE) : FALSE) #define IS_DESIRED_DEVICE_TYPE(_type) (_type) = FILE_DEVICE_DISK_FILE_SYSTEM) | (_type) = FILE_DEVICE_CD_ROM_FILE_SYSTEM) | (_type) = FILE_DEVICE_NETWORK_FILE_SYSTEM),三种类型的设备处理,NTSTATUS FilterXXX(PDEVICE_OBJECT DeviceObject, PIRP pIrp) NTSTATUS Status = STATUS_SUCCESS; ULONG ulInfomation = 0; IO_STACK_LOCATION* lpIrpStack = IoGetCurrentIrpStackLocation(pIrp); if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject) /如果需要与R3交互,这里必须返回成功 pIrp-IoStatus.Status = Status; pIrp-IoStatus.Information = ulInfomation; IoCompleteRequest(lpIrp, IO_NO_INCREMENT); else if (!IS_MY_DEVICE_OBJECT(DeviceObject) /非法参数 pIrp-IoStatus.Status = Status = STATUS_INVALID_PARAMETER; pIrp-IoStatus.Information = 0; IoCompleteRequest(pIrp, IO_NO_INCREMENT); else /这里才是我们要过滤的操作 IoSkipCurrentIrpStackLocation( pIrp ); Status = IoCallDriver(PSFILTER_DEVICE_EXTENSION)-DeviceExtension)DeviceObject-NLExtHeader.AttachedToDeviceObject, pIrp); return Status; ,重要问题:文件路径的解析与保存,Namelookup.c(构造IRP,不能用 ObQueryNameString) NLGetFullPathName() NLPQueryFileSystemForFileName()IRP查询 在SfCreate里查询名字,通过FILE_OBJECT与Name保存起来。供其它过滤函数中查询使用。 保存在哪里? List_Entry HASH TREE,Sfilter安装测试,原始的Sfilter框架,不支持通信 sfCreate中对自己的控制设备,返回成功 符号链接的创建(框架中没有) GroupOrder:“FSFilter Activity Monitor“ LFileSystemSFilterDrv DeviceObjectFlags |= DO_BUFFERED_IO 不要在release版本使用DriverUnload。BSOD,开始过滤,FilterCreate(1),放: 内核过来的 Irp-RequestorMode = KernelMode 本进程的 FilterDeviceIoctrl中 PsGetCurrentProcessId() 系统进程的 DriverEntry里:PsGetCurrentProcessId() 文件夹 ulOptions = IrpStack-Parameters.Create.Options ; FlagOn(IrpStack-FileObject-Flags, FO_VOLUME_OPEN) | FlagOn(ulOptions, FILE_DIRECTORY_FILE) | FlagOn(IrpStack-Flags, SL_OPEN_PAGING_FILE) 分页IO (Irp-Flags ,FilterCreate(2),拿

温馨提示

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

评论

0/150

提交评论