filemon hook IRP_MJ_READ 读用户名问题

在IRP_MJ_READ的处理函数filemonread中,调用了获得当前用户名方法:

NTSTATUS
GetUserName(
    char* a
     )
{
     NTSTATUS status = STATUS_SUCCESS;
    HANDLE         TokenHandle;
    ULONG         ReturnLength;
    ULONG       size;
     UNICODE_STRING SidString;
     PTOKEN_USER TokenInformation = NULL;
    char SidStringBuffer[MAXPATHLEN];
    ANSI_STRING sid_a;

    if(PASSIVE_LEVEL != KeGetCurrentIrql())
    {
        return status;
    }
     status = ZwOpenThreadTokenEx (NtCurrentThread(),
                                   TOKEN_READ,
                                  TRUE,
                                   OBJ_KERNEL_HANDLE,
                                   &TokenHandle);

    if ( !NT_SUCCESS( status ) ) {
         status = ZwOpenProcessTokenEx (NtCurrentProcess(),
                                   TOKEN_READ,
                                   OBJ_KERNEL_HANDLE,
                                   &TokenHandle);

        if ( !NT_SUCCESS( status )) {
            return status;
         }
     }



    // 获取token信息
     size = 0x1000;
     TokenInformation = ExAllocatePool( NonPagedPool, size );

    do {
         status = ZwQueryInformationToken( TokenHandle,
                                         TokenUser,
                                         TokenInformation,
                                         size,
                                         &ReturnLength );

        if (status == STATUS_BUFFER_TOO_SMALL) {
             ExFreePool( TokenInformation );
             size *= 2;
             TokenInformation = ExAllocatePool( NonPagedPool, size );

         } else if ( !NT_SUCCESS (status) ) {
             DbgPrint(" ZwQueryInformationToken error\n");
             if(NULL!=TokenInformation)
             ExFreePool( TokenInformation );
             ZwClose( TokenHandle );

            return STATUS_UNSUCCESSFUL;
         }

     } while (status == STATUS_BUFFER_TOO_SMALL);

    
     ZwClose( TokenHandle );

 
    RtlZeroMemory( SidStringBuffer, sizeof(SidStringBuffer) );
     SidString.Buffer = (PWCHAR)SidStringBuffer;
     SidString.MaximumLength = sizeof( SidStringBuffer );

     status = RtlConvertSidToUnicodeString( &SidString,
                         ((PTOKEN_USER)TokenInformation)->User.Sid,
                        FALSE );
     if(NULL!=TokenInformation)
     ExFreePool( TokenInformation );
    

 //    KdPrint(("sudami's PC Name: %ws\n", SidStringBuffer));
     status = RtlUnicodeStringToAnsiString(&sid_a,&SidString,TRUE);
    if(NT_SUCCESS(status))
    {
        
        strcpy(a,sid_a.Buffer);
        RtlFreeAnsiString(&sid_a);
    }
 //    a = SidStringBuffer;
    return STATUS_SUCCESS;
}

运行几天以后蓝屏重启,用windbg看dump文件,堆栈如下

STACK_TEXT:  

8f885234 915b4f3c 8f885790 00000000 00000000 mmdogflps!GetUserName+0x15 [d:\´©É½¼×\´úÂë¹ÜÀí\code\process.c @ 315]
8f8858a0 81878976 83bd7a70 83f911f0 00000000 mmdogflps!FilemonRead+0x12c [d:\´©É½¼×\´úÂë¹ÜÀí\code\sfilter.c @ 8078]
8f8858b8 8186d74e 83dab1f0 82f0903c 82f09008 nt!IofCallDriver+0x63
8f8858d4 818abf07 00000043 83dab1f0 82f09048 nt!IoPageRead+0x172
8f885990 818cd325 90033228 00000000 00000000 nt!MiDispatchFault+0xd14
8f885a0c 81881db4 00000000 90033228 00000000 nt!MmAccessFault+0x10c6
8f885a0c 81a65dcf 00000000 90033228 00000000 nt!KiTrap0E+0xdc
8f885aa8 81a65db4 90033230 00000001 8f885ae4 nt!ObDereferenceSecurityDescriptor+0x12
8f885ab8 81a65fb9 90033230 00000000 82db29a8 nt!ObReleaseObjectSecurity+0x26
8f885ae4 81a631c3 901c0440 8f885c01 00000001 nt!ObCheckObjectAccess+0xde
8f885b5c 81a62a15 00000001 82dd3860 901c0440 nt!ObpIncrementHandleCount+0x2c6
8f885bd0 81a4adec 00000001 901c0440 862000b0 nt!ObpCreateHandle+0x182
8f885cc4 81a324d6 901c0440 00000200 00000000 nt!ObOpenObjectByPointer+0xbc
8f885d30 8187ec7a ffffffff 00020008 00000200 nt!NtOpenProcessTokenEx+0xb4
8f885d30 8187d215 ffffffff 00020008 00000200 nt!KiFastCallEntry+0x12a
8f885db8 915b5c74 ffffffff 00020008 00000200 nt!ZwOpenProcessTokenEx+0x11
8f88620c 915b4f3c 8f886768 00000000 00000000 mmdogflps!GetUserName+0x84 [d:\´©É½¼×\´úÂë¹ÜÀí\code\process.c @ 338]
8f886878 81878976 83bd7a70 83d56830 00000000 mmdogflps!FilemonRead+0x12c [d:\´©É½¼×\´úÂë¹ÜÀí\code\sfilter.c @ 8078]
8f886890 8186d74e 83dab1f0 83445654 83445620 nt!IofCallDriver+0x63
8f8868ac 818abf07 00000043 83dab1f0 83445660 nt!IoPageRead+0x172
8f886968 818cd325 90033228 00000000 00000000 nt!MiDispatchFault+0xd14
8f8869e4 81881db4 00000000 90033228 00000000 nt!MmAccessFault+0x10c6
8f8869e4 81a65dcf 00000000 90033228 00000000 nt!KiTrap0E+0xdc
8f886a80 81a65db4 90033230 00000001 8f886abc nt!ObDereferenceSecurityDescriptor+0x12
8f886a90 81a65fb9 90033230 00000000 82db29a8 nt!ObReleaseObjectSecurity+0x26
8f886abc 81a631c3 901c0440 8f886b01 00000001 nt!ObCheckObjectAccess+0xde
8f886b34 81a62a15 00000001 82dd3860 901c0440 nt!ObpIncrementHandleCount+0x2c6
8f886ba8 81a4adec 00000001 901c0440 862000b0 nt!ObpCreateHandle+0x182
8f886c9c 81a324d6 901c0440 00000200 00000000 nt!ObOpenObjectByPointer+0xbc
8f886d08 8187ec7a ffffffff 00020008 00000200 nt!NtOpenProcessTokenEx+0xb4
8f886d08 8187d215 ffffffff 00020008 00000200 nt!KiFastCallEntry+0x12a
8f886d90 915b5c74 ffffffff 00020008 00000200 nt!ZwOpenProcessTokenEx+0x11
8f8871e4 915b4f3c 8f887740 00320039 00320034 mmdogflps!GetUserName+0x84 [d:\´©É½¼×\´úÂë¹ÜÀí\code\process.c @ 338]
8f887850 81878976 83bd7a70 83c5d530 00000000 mmdogflps!FilemonRead+0x12c [d:\´©É½¼×\´úÂë¹ÜÀí\code\sfilter.c @ 8078]
8f887868 8186d74e 83dab1f0 83446674 83446640 nt!IofCallDriver+0x63
8f887884 818abf07 00000043 83dab1f0 83446680 nt!IoPageRead+0x172
8f887940 818cd325 90033232 00000000 00000000 nt!MiDispatchFault+0xd14
8f8879bc 81881db4 00000000 90033232 00000000 nt!MmAccessFault+0x10c6
8f8879bc 818e30c9 00000000 90033232 00000000 nt!KiTrap0E+0xdc
8f887a6c 818e2022 02000000 90033230 901c0440 nt!SepMandatoryIntegrityCheck+0x3e
8f887aa0 81a65f5a 90033230 8f887c34 00000001 nt!SeAccessCheck+0xbb
8f887aec 81a631c3 901c0440 8f887c18 00000001 nt!ObCheckObjectAccess+0x7f
8f887b64 81a62a15 00000001 83d55d90 901c0440 nt!ObpIncrementHandleCount+0x2c6
8f887bd8 81a4adec 00000001 901c0440 900b0f38 nt!ObpCreateHandle+0x182
8f887cc8 81a324d6 901c0440 00000000 00000000 nt!ObOpenObjectByPointer+0xbc
8f887d34 81a3560e ffffffff 02000000 00000000 nt!NtOpenProcessTokenEx+0xb4
8f887d50 8187ec7a ffffffff 02000000 0a7becf4 nt!NtOpenProcessToken+0x16
8f887d50 76fc5e74 ffffffff 02000000 0a7becf4 nt!KiFastCallEntry+0x12a



从堆栈看,在filemonread中调用了GetUserName,GetUserName调用了NtOpenProcessTokenEx,这个调用引起了缺页中断KiTrap0E,这个中断处理函数向磁盘发起读请求,这个读IRP又被hook到,陷入FilemonRead。这样陷入死循环。

之所以不容易复现,是因为只有缺页才会引起,如果NtOpenProcessTokenEx这个系统调用需要的信息在内存中,应该不会出。

这个问题需要解决重入问题。我们希望GetUserName引起的磁盘IRP我们驱动不处理。关键问题是如何识别这个IRP,还是用楚狂人教程里的办法,把GetUserName放到单独的线程中去运行,通过线程ID来识别当前IPR是否是这个单独线程发起的,如果是,则直接向后面驱动转发。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值