阅读:2112回复:3
请问大虾们,为什么访问Irp->UserBuffer会蓝屏
我想把FileMon修改为一个可以截获读写内容,但是在访问Irp->UserBuffer的时候会蓝屏,我增加了一个函数
NTSTATUS FilemonCompleteRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) 然后在FilemonHookRoutine函数中做了一些修改,代码如下: NTSTATUS FilemonHookRoutine( PDEVICE_OBJECT HookDevice, IN PIRP Irp ) { 。。。。。。。。 case IRP_MJ_READ: if( FilterDef.logreads ) { //((PCHAR)Irp->AssociatedIrp.SystemBuffer hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, "%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( _strnicmp( PROCESS_NAME, name, sizeof(PROCESS_NAME)-1 ) == 0 && _strnicmp( FILE_NAME, fullPathName, sizeof(FILE_NAME)-1 ) == 0 ) { hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, "%s\tIRP_MJ_READ%c\t%s\tOffset: %d Length: %d Compare: OK", name, (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? '*' : ' ', fullPathName, currentIrpStack->Parameters.Read.ByteOffset.LowPart, currentIrpStack->Parameters.Read.Length ); *nextIrpStack = *currentIrpStack; strcpy( gProcessFullPath, fullPathName ); strcpy( gFileName, name ); IoSetCompletionRoutine(Irp, FilemonCompleteRead, NULL, TRUE, TRUE, TRUE); return IoCallDriver( hookExt->FileSystem, Irp ); } else { hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL, "%s\tIRP_MJ_READ%c\t%s\tOffset: %d Length: %d Compare: FAIL", name, (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? '*' : ' ', fullPathName, currentIrpStack->Parameters.Read.ByteOffset.LowPart, currentIrpStack->Parameters.Read.Length ); } } break; 。。。。。。。。。。。。。。。。。 } NTSTATUS FilemonCompleteRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); LARGE_INTEGER dateTime; LARGE_INTEGER perfTime; CHAR *pBuffer = NULL; ULONG seqNum; // // If measuring absolute time go and get the timestamp. // if(Irp->IoStatus.Status == STATUS_SUCCESS) { KeQuerySystemTime( &dateTime ); perfTime = KeQueryPerformanceCounter( NULL ); // // We want to watch this IRP complete // seqNum = (ULONG) -1; if (DeviceObject->Flags & DO_BUFFERED_IO) { //KdPrint(("*************Read complete in BUFFER_IO\n"));*/ pBuffer=(char *)Irp->AssociatedIrp.SystemBuffer; } else { if (Irp->MdlAddress!=NULL) { // KdPrint(("*************Read complete in Mdl\n"));*/ pBuffer = (char *)MmGetSystemAddressForMdl (Irp->MdlAddress); } else { if (Irp->UserBuffer!=NULL) { //KdPrint(("*************Read complete in USERBUFFER\n"));*/ pBuffer=(char*)Irp->UserBuffer; //蓝屏 } } } if( pBuffer != NULL ) LogRecord( TRUE, &seqNum, &dateTime, NULL, "%s\tIRP_MJ_READ%c\t%s\tBuffer: %s", gFileName, (Irp->Flags & IRP_PAGING_IO) || (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ? '*' : ' ', gProcessFullPath, pBuffer ); } memset( gProcessFullPath, 0, sizeof( gProcessFullPath ) ); memset( gFileName, 0, sizeof( gFileName ) ); if( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } return Irp->IoStatus.Status; } 烦劳各位大虾们指出错误,不胜感激,谢谢! |
|
最新喜欢:![]() |
沙发#
发布于:2009-04-21 10:19
竟然没有一个人留言,好伤心哦
|
|
板凳#
发布于:2009-04-21 13:26
UserBuffer不能随便访问,要根据具体情况使用不同的访问方式,如果有MDL,就用MDL;如果是系统缓冲区,就可以直接用;如果是用户缓冲区,需要在用户线程同样上下文中才能用,如果当前不是用户线程上下文,那就需要提交到用户线程上下文中再用。
这是基本要求啊,也就我这样的初学者才会回答这基本问题,老大们都不屑回答啊。 |
|
地板#
发布于:2009-04-21 13:43
谢谢
|
|