阅读:1191回复:0
大家帮忙看看,自己创建IRP怎么读不到文件内容?
我准备在filemon拦截到对某个文件a进行读访问时(IRP_MJ_READ)利用自己创建的IRP向下层驱动读取数据,然后再将读取到的数据交给上层应用,可是怎么都读不到数据,不知道是不是我的IRP建立的有问题,请各位给我看看。
读例程: NTSTATUS FilemonReadDispatch( PDEVICE_OBJECT HookDevice, IN PIRP Irp ) { PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp); PFILE_OBJECT fileObject; PHOOK_EXTENSION hookExt; PCHAR fullPathName; CHAR name[PROCNAMELEN]; PUCHAR SysBuffer = NULL; //IRP中原有的MDL缓冲区 *nextIrpStack = *currentIrpStack; // // Allocate a buffer // fullPathName = ExAllocatePool( PagedPool, MAXPATHLEN ); fullPathName[0] = 0; // // Extract the file object from the IRP // fileObject = currentIrpStack->FileObject; // // Point at the device extension, which contains information on which // file system this IRP is headed for // hookExt = HookDevice->DeviceExtension; // // If a GUI is up there, get the canonical pathname // FilemonGetFullPath( FALSE, fileObject, hookExt, fullPathName ); // // Only log it if it passes the filter // if( FilemonGetProcess( name ) && ApplyNameFilter(fullPathName) ) { // // Determine what function we\'re dealing with // LARGE_INTEGER m_time; m_time.QuadPart = 1; if( FilterDef.logreads ) { UpdateStore( 100100, &m_time, \"%s\\tIRP_MJ_READ%c\\t%s\\tOffset: %d Length: %d\", name, (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? \'*\' : \' \', fullPathName, currentIrpStack->Parameters.Read.ByteOffset.LowPart, currentIrpStack->Parameters.Read.Length ); } if( (Irp->Flags & IRP_NOCACHE) || (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ) { FileBufferSize = currentIrpStack->Parameters.Read.Length; /*获取上层应用提供的缓冲区*/ if(Irp->MdlAddress){//Direct I/O Method SysBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority ); if(SysBuffer == NULL){ return CompleteRequest(Irp, STATUS_INSUFFICIENT_RESOURCES, 0); } } else SysBuffer = Irp->UserBuffer; /*创建一个新的缓冲区,用来给新IRP使用*/ FileBuffer = ExAllocatePool(NonPagedPool, FileBufferSize); Status = MyReadDispatch( hookExt->FileSystem, fileObject, FileBuffer, FileBufferSize, ¤tIrpStack->Parameters.Read.ByteOffset); if(!Status){ ExFreePool(FileBuffer); return CompleteRequest(Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); } RtlCopyMemory(SysBuffer, FileBuffer, FileBufferSize); ExFreePool(FileBuffer); if(fullPathName) ExFreePool(fullPathName); return CompleteRequest(Irp, Irp->IoStatus.Status, Irp->IoStatus.Information); } } if(fullPathName) ExFreePool(fullPathName); return IoCallDriver(hookExt->FileSystem, Irp); } 我自己的读例程: BOOLEAN MyReadDispatch(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUCHAR FileBuffer, ULONG FileBufferSize, PLARGE_INTEGER Offset ) { PIRP irp; KEVENT event; PMDL MyMDL; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION irpSp; ULONG MajorFunction; NTSTATUS Status; // // Set up the event we\'ll use. // KeInitializeEvent(&event, SynchronizationEvent, FALSE); // // Allocate an irp for this request. This could also come from a // private pool, for instance. // irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!irp) { // // Failure! // return FALSE; } // // Build the IRP\'s main body // irp->UserEvent = &event; irp->UserIosb = &IoStatusBlock; irp->Tail.Overlay.Thread = PsGetCurrentThread(); irp->Tail.Overlay.OriginalFileObject = FileObject; irp->RequestorMode = KernelMode; irp->Flags = IRP_READ_OPERATION; // // Set up the I/O stack location. // irpSp = IoGetNextIrpStackLocation(irp); irpSp->MajorFunction = IRP_MJ_READ; irpSp->MinorFunction = 0; irpSp->DeviceObject = DeviceObject; irpSp->FileObject = FileObject; irp->MdlAddress = IoAllocateMdl( FileBuffer, FileBufferSize, FALSE, FALSE, (PIRP) NULL ); if (irp->MdlAddress == NULL) { IoFreeIrp( irp ); return FALSE; } try { MmProbeAndLockPages( irp->MdlAddress, KernelMode, (LOCK_OPERATION) (irpSp->MajorFunction == IRP_MJ_READ ? IoWriteAccess : IoReadAccess) ); } except(EXCEPTION_EXECUTE_HANDLER) { if (irp->MdlAddress != NULL) { IoFreeMdl( irp->MdlAddress ); } IoFreeIrp( irp ); return FALSE; } irp->UserBuffer = FileBuffer; irpSp->Parameters.Read.Length = FileBufferSize; irpSp->Parameters.Read.ByteOffset = *Offset; // // Set the completion routine. // IoSetCompletionRoutine(irp, MyReadCompleted, 0, TRUE, TRUE, TRUE); // // Send it to the FSD // Status = IoCallDriver(DeviceObject, irp); // // Wait for the I/O // if(Status == STATUS_PENDING) KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); /*这里总是失败,任何内容都读不到*/ DbgPrint((\"%s content:%s\\n\", NT_SUCCESS( IoStatusBlock.Status )? \"Success\":\"Failed\", FileBuffer)); return( NT_SUCCESS( IoStatusBlock.Status )); } 完成例程: NTSTATUS MyReadCompleted(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { // // Copy the status information back into the \"user\" IOSB. // *Irp->UserIosb = Irp->IoStatus; if( !NT_SUCCESS(Irp->IoStatus.Status) ) { //总是运行到这里 DbgPrint((\" ERROR ON IRP: %x\\n\", Irp->IoStatus.Status )); } // // Set the user event - wakes up the mainline code doing this. // KeSetEvent(Irp->UserEvent, 0, FALSE); //清除我们创建的内存变量 if (Irp->MdlAddress) { MmUnmapLockedPages(MmGetSystemAddressForMdl(Irp->MdlAddress), Irp->MdlAddress); MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress); Irp->MdlAddress = NULL; } // // Free the IRP now that we are done with it. // IoFreeIrp(Irp); return STATUS_MORE_PROCESSING_REQUIRED; } :) |
|