风化血 发表于 2019-9-10 16:16

微过滤器引发的堆栈bug

前几天编了个minifilter试着拦截一些文件操作,结果功能是实现了,但是开驱动过1-2天必定会BSOD,蓝屏码是0xF7(DRIVER_OVERRAN_STACK_BUFFER),实在搞不太懂我这代码哪里触发了堆栈溢出的bug,求求各位大佬帮我看看是哪里错了。
相关代码:
FLT_PREOP_CALLBACK_STATUS
NPPreCreate(
__inout PFLT_CALLBACK_DATA Data,
__in PCFLT_RELATED_OBJECTS FltObjects,
__deref_out_opt PVOID *CompletionContext
)
{
NTSTATUS status;
PFLT_FILE_NAME_INFORMATION nameInfo;
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
PAGED_CODE();
__try
{
status = FltGetFileNameInformation(
Data,
FLT_FILE_NAME_NORMALIZED |
FLT_FILE_NAME_QUERY_DEFAULT,
&nameInfo
);
if (!NT_SUCCESS(status))
{
DbgPrint("folderprotect!Get file name fail");
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
char fileName = "";
FltParseFileNameInformation(nameInfo);
if (!KStrUniToChar(&nameInfo->Name, fileName))
{
DbgPrint("folderprotect!Unicode string to char fail");
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
else
{
if (fileName == NULL)
{
DbgPrint("folderprotect!fileName is NULL");
FltReleaseFileNameInformation(nameInfo);
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
}

    SHORT pos = 0;
    TIME_FIELDS time;
    UNICODE_STRING timeStr;
    UNICODE_STRING operStr;
    UNICODE_STRING totalStr;
    KStrInitUni(&timeStr, MAX_PATH_FOL, FOLDER_POOL_TAG);
    KStrInitUni(&operStr, MAX_PATH_FOL, FOLDER_POOL_TAG);
    KStrInitUni(&totalStr, MAX_PATH_FOL, FOLDER_POOL_TAG);

    for (int i = 0; i < pathCount; i++)
    {
      UNICODE_STRING indexStr;
      KStrInitUni(&indexStr, MAX_PATH_FOL, FOLDER_POOL_TAG);
      RtlUpcaseUnicodeString(&indexStr, &folprotect, FALSE);
      RtlAppendUnicodeToString(&indexStr, L"\\");
      if (RtlEqualUnicodeString(&folprotect, &nameInfo->Name, TRUE) ||
            KStrStartWith(&nameInfo->Name, &indexStr,TRUE, FOLDER_POOL_TAG))
      {
            if (Data->Iopb->MajorFunction == IRP_MJ_SET_INFORMATION)
            {
                switch (Data->Iopb->Parameters.SetFileInformation.FileInformationClass)
                {
                case FileRenameInformation:
                case FileDispositionInformation:
                case FileRenameInformationBypassAccessCheck:
                case FileShortNameInformation:
                  break;
                default:
                  KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                  return FLT_PREOP_SUCCESS_NO_CALLBACK;
                }
                time = GetTime();
                timmm(FOLDER_POOL_TAG, &timeStr);
                RtlAppendUnicodeToString(&operStr, L"filedelete|");
                KStrUniAddThree(&timeStr, &operStr, &nameInfo->Name, &totalStr);
                AddFile(totalStr, time);
                Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                Data->IoStatus.Information = 0;
                FltReleaseFileNameInformation(nameInfo);
                KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                return FLT_PREOP_COMPLETE;
            }
            if (Data->Iopb->MajorFunction == IRP_MJ_WRITE)
            {
                time = GetTime();
                timmm(FOLDER_POOL_TAG, &timeStr);
                RtlAppendUnicodeToString(&operStr, L"file write|");
                KStrUniAddThree(&timeStr, &operStr, &nameInfo->Name, &totalStr);
                AddFile(totalStr, time);
                Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                Data->IoStatus.Information = 0;
                FltReleaseFileNameInformation(nameInfo);
                KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                return FLT_PREOP_COMPLETE;
            }
            if (Data->Iopb->MajorFunction == IRP_MJ_CREATE)
            {
                if (((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_CREATE ||
                  ((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_OPEN_IF ||
                  ((Data->Iopb->Parameters.Create.Options >> 24) & 0x000000ff) == FILE_OVERWRITE_IF)
                {
                  time = GetTime();
                  timmm(FOLDER_POOL_TAG, &timeStr);
                  RtlAppendUnicodeToString(&operStr, L"file create|");
                  KStrUniAddThree(&timeStr, &operStr, &nameInfo->Name, &totalStr);
                  AddFile(totalStr, time);
                  Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                  Data->IoStatus.Information = 0;
                  FltReleaseFileNameInformation(nameInfo);
                  KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                  return FLT_PREOP_COMPLETE;
                }
                if (Data->Iopb->OperationFlags == '\x05')
                {
                  time = GetTime();
                  timmm(FOLDER_POOL_TAG, &timeStr);
                  RtlAppendUnicodeToString(&operStr, L"file rename|");
                  KStrUniAddThree(&timeStr, &operStr, &nameInfo->Name, &totalStr);
                  AddFile(totalStr, time);
                  Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                  Data->IoStatus.Information = 0;
                  FltReleaseFileNameInformation(nameInfo);
                  KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                  return FLT_PREOP_COMPLETE;
                }
                if (Data->Iopb->Parameters.Create.Options == FILE_DELETE_ON_CLOSE)
                {
                  time = GetTime();
                  timmm(FOLDER_POOL_TAG, &timeStr);
                  RtlAppendUnicodeToString(&operStr, L"other operation|");
                  KStrUniAddThree(&timeStr, &operStr, &nameInfo->Name, &totalStr);
                  AddFile(totalStr, time);
                  Data->IoStatus.Status = STATUS_ACCESS_DENIED;
                  Data->IoStatus.Information = 0;
                  FltReleaseFileNameInformation(nameInfo);
                  KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&operStr, FOLDER_POOL_TAG);
                  KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
                  return FLT_PREOP_COMPLETE;
                }
            }
            KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
            break;
      }
      KStrFreeUni(&indexStr, FOLDER_POOL_TAG);
    }
    KStrFreeUni(&timeStr, FOLDER_POOL_TAG);
    KStrFreeUni(&operStr, FOLDER_POOL_TAG);
    KStrFreeUni(&totalStr, FOLDER_POOL_TAG);
    FltReleaseFileNameInformation(nameInfo);

    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
    return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
}

windbg分析的dump:
DRIVER_OVERRAN_STACK_BUFFER (f7)
A driver has overrun a stack-based buffer. This overrun could potentially
allow a malicious user to gain control of this machine.
DESCRIPTION
A driver overran a stack-based buffer (or local variable) in a way that would
have overwritten the function's return address and jumped back to an arbitrary
address when the function returned. This is the classic "buffer overrun"
hacking attack and the system has been brought down to prevent a malicious user
from gaining complete control of it.
Do a kb to get a stack backtrace -- the last routine on the stack before the
buffer overrun handlers and bugcheck call is the one that overran its local
variable(s).
Arguments:
Arg1: 90d93ce4, Actual security check cookie from the stack
Arg2: d4eaac15, Expected security check cookie
Arg3: 2b1553ea, Complement of the expected security check cookie
Arg4: 00000000, zeroDebugging Details:*** WARNING: Unable to verify timestamp for qutmdrv.sys
*** ERROR: Module load completed but symbols could not be loaded for qutmdrv.sys
*** WARNING: Unable to verify timestamp for TsQBDrv.sys
*** ERROR: Module load completed but symbols could not be loaded for TsQBDrv.sys
*** WARNING: Unable to verify timestamp for QQFrmMgr.sys
*** ERROR: Module load completed but symbols could not be loaded for QQFrmMgr.sys
*** WARNING: Unable to verify timestamp for Hookport.sys
*** ERROR: Module load completed but symbols could not be loaded for Hookport.sysDEFAULT_BUCKET_ID: GS_FALSE_POSITIVE_MISSING_GSFRAMESECURITY_COOKIE: Expected d4eaac15 found 90d93ce4CUSTOMER_CRASH_COUNT: 1BUGCHECK_STR: 0xF7PROCESS_NAME: svchost.exeCURRENT_IRQL: 0LAST_CONTROL_TRANSFER: from 9bdf5825 to 8432ecc4STACK_TEXT:
c48a7398 9bdf5825 000000f7 90d93ce4 d4eaac15 nt!KeBugCheckEx+0x1e
WARNING: Stack unwind information not available. Following frames may be wrong.
c48a73b8 9bdf50b7 00000000 87480000 00000800 folderprotect+0x2825
c48a75a8 85771aeb 9f25a148 c48a75c8 c48a75f4 folderprotect+0x20b7
c48a7614 857749f0 c48a7658 87e4f2b8 00000000 FLTMGR!FltpPerformPreCallbacks+0x34d
c48a762c 857881fe c48a7658 8578bf3c 00000000 FLTMGR!FltpPassThroughInternal+0x40
c48a7640 857888b7 c48a7658 87e4f4fc 00000000 FLTMGR!FltpCreateInternal+0x24
c48a7684 84285f87 8a746230 8a7b5318 87e4f2b8 FLTMGR!FltpCreate+0x2c9
c48a769c 95172cd0 00000000 8abf8698 c585f848 nt!IofCallDriver+0x63
c48a7730 84285f87 8abf8698 87e4f2b8 87e4f2b8 qutmdrv+0x12cd0
c48a7748 8577520c 87e4f2b8 00000000 87e4f520 nt!IofCallDriver+0x63
c48a776c 857888c9 c48a778c 9f331768 00000000 FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
c48a77b8 84285f87 9f331768 9f3395b8 a08ac2c4 FLTMGR!FltpCreate+0x2db
c48a77d0 8449fdab e87780bb 87a80328 8af4fd20 nt!IofCallDriver+0x63
c48a78b0 844db58a 9f331768 85537900 8781ca18 nt!IopParseDevice+0xf08
c48a78f0 8447eff8 87a80328 87537900 8781ca18 nt!IopParseFile+0x51
c48a796c 8448f674 0000019c c48a79c0 00000040 nt!ObpLookupObjectName+0x510
c48a79cc 94a6714d 00ecf320 87537900 00ecf301 nt!ObOpenObjectByName+0x165
c48a7a48 84485f6b 00ecf320 87537900 00ecf301 TsQBDrv+0xc14d
c48a7ac4 8448c2f4 00ecf348 00100080 00ecf320 nt!IopCreateFile+0x6c3
c48a7b0c 94d52310 00ecf348 00100080 00ecf320 nt!NtOpenFile+0x2a
c48a7b4c 8d531e6c 00ecf348 00100080 00ecf320 QQFrmMgr+0x6310
c48a7c14 8428ca6a 00ecf348 00100080 00ecf320 Hookport+0xe6c
c48a7c14 77936c04 00ecf348 00100080 00ecf320 nt!KiSystemServicePostCall
00ecf34c 00000000 00000000 00000000 00000000 0x77936c04STACK_COMMAND: kbFOLLOWUP_IP:
folderprotect+2825
9bdf5825 ?? ???SYMBOL_STACK_INDEX: 1SYMBOL_NAME: folderprotect+2825FOLLOWUP_NAME: MachineOwnerMODULE_NAME: folderprotectIMAGE_NAME: folderprotect.sysDEBUG_FLR_IMAGE_TIMESTAMP: 5d6cc8a4FAILURE_BUCKET_ID: 0xF7_MISSING_GSFRAME_folderprotect+2825BUCKET_ID: 0xF7_MISSING_GSFRAME_folderprotect+2825Followup: MachineOwner0: kd> kb
ChildEBP RetAddr Args to Child
c48a7398 9bdf5825 000000f7 90d93ce4 d4eaac15 nt!KeBugCheckEx+0x1e
WARNING: Stack unwind information not available. Following frames may be wrong.
c48a73b8 9bdf50b7 00000000 87480000 00000800 folderprotect+0x2825
c48a75a8 85771aeb 9f25a148 c48a75c8 c48a75f4 folderprotect+0x20b7
c48a7614 857749f0 c48a7658 87e4f2b8 00000000 FLTMGR!FltpPerformPreCallbacks+0x34d
c48a762c 857881fe c48a7658 8578bf3c 00000000 FLTMGR!FltpPassThroughInternal+0x40
c48a7640 857888b7 c48a7658 87e4f4fc 00000000 FLTMGR!FltpCreateInternal+0x24
c48a7684 84285f87 8a746230 8a7b5318 87e4f2b8 FLTMGR!FltpCreate+0x2c9
c48a769c 95172cd0 00000000 8abf8698 c585f848 nt!IofCallDriver+0x63
c48a7730 84285f87 8abf8698 87e4f2b8 87e4f2b8 qutmdrv+0x12cd0
c48a7748 8577520c 87e4f2b8 00000000 87e4f520 nt!IofCallDriver+0x63
c48a776c 857888c9 c48a778c 9f331768 00000000 FLTMGR!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
c48a77b8 84285f87 9f331768 9f3395b8 a08ac2c4 FLTMGR!FltpCreate+0x2db
c48a77d0 8449fdab e87780bb 87a80328 8af4fd20 nt!IofCallDriver+0x63
c48a78b0 844db58a 9f331768 85537900 8781ca18 nt!IopParseDevice+0xf08
c48a78f0 8447eff8 87a80328 87537900 8781ca18 nt!IopParseFile+0x51
c48a796c 8448f674 0000019c c48a79c0 00000040 nt!ObpLookupObjectName+0x510
c48a79cc 94a6714d 00ecf320 87537900 00ecf301 nt!ObOpenObjectByName+0x165
c48a7a48 84485f6b 00ecf320 87537900 00ecf301 TsQBDrv+0xc14d
c48a7ac4 8448c2f4 00ecf348 00100080 00ecf320 nt!IopCreateFile+0x6c3
c48a7b0c 94d52310 00ecf348 00100080 00ecf320 nt!NtOpenFile+0x2a
c48a7b4c 8d531e6c 00ecf348 00100080 00ecf320 QQFrmMgr+0x6310
c48a7c14 8428ca6a 00ecf348 00100080 00ecf320 Hookport+0xe6c
c48a7c14 77936c04 00ecf348 00100080 00ecf320 nt!KiSystemServicePostCall
00ecf34c 00000000 00000000 00000000 00000000 0x77936c04
0: kd> lmvm folderprotect
start end module name
9bdf3000 9bdfc000 folderprotect T (no symbols)
Loaded symbol image file: folderprotect.sys
Image path: folderprotect.sys
Image name: folderprotect.sys
Timestamp: Mon Sep 02 15:45:40 2019 (5D6CC8A4)
CheckSum: 0000F0CA
ImageSize: 00009000
Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4
页: [1]
查看完整版本: 微过滤器引发的堆栈bug