liht215
驱动牛犊
驱动牛犊
  • 注册日期2008-07-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1991回复:3

请问大虾们,为什么访问Irp->UserBuffer会蓝屏

楼主#
更多 发布于:2009-04-17 18:24
我想把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;
}


烦劳各位大虾们指出错误,不胜感激,谢谢!

最新喜欢:

rhpengrhpeng
liht215
驱动牛犊
驱动牛犊
  • 注册日期2008-07-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-04-21 10:19
竟然没有一个人留言,好伤心哦
zzbwang
驱动牛犊
驱动牛犊
  • 注册日期2009-03-18
  • 最后登录2016-01-09
  • 粉丝1
  • 关注0
  • 积分62分
  • 威望611点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分1分
板凳#
发布于:2009-04-21 13:26
UserBuffer不能随便访问,要根据具体情况使用不同的访问方式,如果有MDL,就用MDL;如果是系统缓冲区,就可以直接用;如果是用户缓冲区,需要在用户线程同样上下文中才能用,如果当前不是用户线程上下文,那就需要提交到用户线程上下文中再用。

这是基本要求啊,也就我这样的初学者才会回答这基本问题,老大们都不屑回答啊。
liht215
驱动牛犊
驱动牛犊
  • 注册日期2008-07-21
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望101点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-04-21 13:43
谢谢
游客

返回顶部