Не совсем понятный BSOD при ExFreePoolWithTag

Тема в разделе "WASM.NT.KERNEL", создана пользователем h0t, 13 янв 2012.

  1. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    История такая в драйвере нужно прочитать файл с диска читаю так:

    Код (Text):
    1. ULONG  _ReadFile(
    2.     PDEVICE_OBJECT DeviceObject,
    3.     PFILE_OBJECT FileObject,
    4.     PLARGE_INTEGER pReadOffset,
    5.     PVOID FileReadBuffer,
    6.     ULONG FileReadBufferLength
    7.     )
    8. {
    9.     PIRP irp;
    10.     KEVENT event;
    11.     IO_STATUS_BLOCK IoStatusBlock;
    12.     PIO_STACK_LOCATION ioStackLocation;
    13.        
    14.    
    15.     KeInitializeEvent(&event, SynchronizationEvent, FALSE);
    16.  
    17.    
    18.     irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    19.     if(!irp)  return FALSE;
    20.    
    21.  
    22.  
    23.     irp->AssociatedIrp.SystemBuffer = NULL;
    24.     irp->UserEvent = &event;                       
    25.     irp->UserIosb = &IoStatusBlock;            
    26.     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    27.     irp->Tail.Overlay.OriginalFileObject = FileObject;
    28.     irp->RequestorMode = KernelMode;               
    29.     irp->Flags = 0;
    30.     irp->UserBuffer = FileReadBuffer;
    31.     irp->MdlAddress = NULL;
    32.        
    33.  
    34.     ioStackLocation = IoGetNextIrpStackLocation(irp);
    35.     //IRP_MJ_READ
    36.     ioStackLocation->MajorFunction = IRP_MJ_READ;
    37.    
    38.     ioStackLocation->DeviceObject = DeviceObject;              
    39.     ioStackLocation->FileObject = FileObject;
    40.     ioStackLocation->Parameters.Read.Length = FileReadBufferLength;
    41.     if (pReadOffset) ioStackLocation->Parameters.Read.ByteOffset = *pReadOffset;
    42.    
    43.     IoSetCompletionRoutine(irp,  ReadFileComplete, 0, TRUE, TRUE, TRUE);
    44.  
    45.  
    46.     IoCallDriver(DeviceObject, irp);
    47.  
    48.     KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
    49.    
    50.  
    51.     IoFreeIrp(irp);
    52.    
    53.     return IoStatusBlock.Information;
    54.    
    55. }
    56.  
    57.  
    58. NTSTATUS  ReadFileComplete(
    59.     PDEVICE_OBJECT DeviceObject,
    60.     PIRP Irp,
    61.     PVOID Context
    62.     )
    63. {
    64.  
    65.     *Irp->UserIosb = Irp->IoStatus;
    66.     if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
    67.  
    68.         DbgPrint((" READ  ERROR ON IRP: %x\n", Irp->IoStatus.Status ));
    69.     }
    70.  
    71.     KeSetEvent(Irp->UserEvent, 0, FALSE);
    72.  
    73.     return STATUS_MORE_PROCESSING_REQUIRED;
    74. }
    читает к функции вопросов нет, но эта функция вызывается вот в таком куске

    Код (Text):
    1.            buffer = ExAllocatePoolWithTag(NonPagedPool, BUFFERSIZE, ALLOCATEPOOLTAG);  
    2.    
    3.     ....
    4.         readFileSize = _ReadFile(hookExt->FileSystemDevice,fileObject,&filePos,buffer,BUFFERSIZE);
    5.     ....
    6.  
    7.     ExFreePoolWithTag(buffer,ALLOCATEPOOLTAG); // <- тут возникает BSOD
    и иногда (замечено только на 7ке) вылетает такой BSOD


    Код (Text):
    1. PFN_LIST_CORRUPT (4e)
    2. Typically caused by drivers passing bad memory descriptor lists (ie: calling
    3. MmUnlockPages twice with the same list, etc).  If a kernel debugger is
    4. available get the stack trace.
    5. Arguments:
    6. Arg1: 0000009a,
    7. Arg2: 0007fc9c
    8. Arg3: 00000006
    9. Arg4: 00000002
    10.  
    11. ......
    12.  
    13.  
    14. FAULTING_MODULE: 8283c000 nt
    15.  
    16. DEBUG_FLR_IMAGE_TIMESTAMP:  4f1021e8
    17.  
    18. BUGCHECK_STR:  0x4E_9a
    19.  
    20. DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT
    21.  
    22. CURRENT_IRQL:  0
    23.  
    24. LAST_CONTROL_TRANSFER:  from 82926544 to 8291af20
    25.  
    26. STACK_TEXT:  
    27. WARNING: Stack unwind information not available. Following frames may be wrong.
    28. 8b399ce0 82926544 0000004e 0000009a 0007fc9c nt!KeBugCheckEx+0x1e
    29. 8b399dd8 8295def1 8569c000 00010000 88e7bd6f nt!MmTrimAllSystemPagableMemory+0x44a9
    30. 8b399e44 89602ae5 8569c000 72767346 00005000 nt!ExFreePoolWithTag+0x437
    31. 8b39a79c 89603a48 87416c98 8662cf58 88e7bd90 DRIVER+0x2ae5
    32. 8b39a7cc 828b4933 8662cea0 88e7bbb8 00000000 DRIVER+0x3a48
    33. 8b39a810 837639a7 8b39a830 83763aa1 88e7bbb8 nt!RtlCaptureContext+0x29f
    34. 8b39a818 83763aa1 88e7bbb8 00000000 88e7bbb8 fltmgr!FltGetIrpName+0xc13
    35. 8b39a830 837642e9 8664bdd8 88e7bbb8 00000000 fltmgr!FltGetIrpName+0xd0d
    36. 8b39a858 837778c9 8b39a878 00000000 00000000 fltmgr!FltGetIrpName+0x1555
    37. 8b39a8a4 82873593 865f91b8 8662c960 88e7bdb4 fltmgr!FltProcessFileLock+0x1f7d
    38. 8b39a8bc 896039bd 00000000 8662cea0 88e7bd90 nt!IofCallDriver+0x64
    39. 8b39a8d8 8960320f 8662cea0 88e7bbb8 8b39a900 DRIVER+0x39bd
    40. 8b39a8e8 82873593 8662cea0 88e7bbb8 88e7bbb8 DRIVER+0x320f
    41. 8b39a900 8376420c 88e7bbb8 00000000 88e7bdb4 nt!IofCallDriver+0x64
    42. 8b39a924 837778c9 8b39a944 8728c5a0 00000000 fltmgr!FltGetIrpName+0x1478
    43. 8b39a970 82873593 8728c5a0 8728d008 87416cf4 fltmgr!FltProcessFileLock+0x1f7d
    44. 8b39a988 82a832a9 b20158ac 8b39ab30 00000000 nt!IofCallDriver+0x64
    45. 8b39aa60 82a62ac5 865a8978 8561f7e0 8631fd20 nt!NtClose+0xf2f
    46. 8b39aadc 82a72ed6 00000000 8b39ab30 00000040 nt!ObCreateObject+0x8c4
    47. 8b39ab38 82a699b4 0297ec5c 8561f7e0 873c4c01 nt!ObOpenObjectByName+0x165
    48. 8b39abb4 82a8d218 0297ecb8 00100080 0297ec5c nt!NtAllocateVirtualMemory+0x1f52
    49. 8b39ac00 8287a1ea 0297ecb8 00100080 0297ec5c nt!NtCreateFile+0x34
    50. 8b39ac48 96c8b149 034186ba 00000006 8b39ac98 nt!ZwYieldExecution+0xb56
    51. 8b39ac4c 034186ba 00000006 8b39ac98 0000003b Syser!DllUnload+0x5118b
    52. 8b39ac50 00000000 8b39ac98 0000003b 00000000 0x34186ba
    53.  
    54.  
    55. STACK_COMMAND:  kb
    56.  
    57. FOLLOWUP_IP:
    58. DRIVER+2ae5
    59. 89602ae5 8b4dfc          mov     ecx,dword ptr [ebp-4]
    60.  
    61. SYMBOL_STACK_INDEX:  3
    62.  
    63. SYMBOL_NAME:  DRIVER+2ae5
    64.  
    65. FOLLOWUP_NAME:  MachineOwner
    66.  
    67. MODULE_NAME: DRIVER
    68.  
    69. IMAGE_NAME:  DRIVER.sys
    70.  
    71. BUCKET_ID:  WRONG_SYMBOLS
    72.  
    73. Followup: MachineOwner
    74. ---------
    В общем мне не понятна причина вылета, все таки nonpaged и mdl я не использую.
     
  2. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    х64 на Вас последняя надежда.
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    А чо я-то сразу?
    Ну Verifier включи.
    И ещё стек какой-то левый.
    Подгрузи символы нормальные.
     
  4. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Просто в прошлый раз хорошо подсказали, Verifier не поймал ничего.
    С почему стек левый?
     
  5. Magnum

    Magnum New Member

    Публикаций:
    0
    Регистрация:
    29 дек 2007
    Сообщения:
    925
    h0t
    1. Покажите пожалуйста тело функции FileSaverReadFile
    2. Перед освобождением пула попробуйте выполнить KeLowerIrql(0)
    3. Попробуйте выделить пул размером BUFFERSIZE + 0x1000 (догадка)

    Если дадите кодес с бряками, помогу отладить
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    h0t
    Видимо, поэтому. После '.reload' в WinDbg картина меняется?
     
  7. Malfoy

    Malfoy New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2012
    Сообщения:
    698
    Зачем символы, по мойму колстек весьма конкретный. Проблема не в отложенном вызове, так как бсодит из текущего потока. Нужно видеть что делает функа перед освобождением пула.

    Единственное что в дампе не понятно, это контекст:
    Код (Text):
    1. FOLLOWUP_IP:
    2. DRIVER+2ae5
    3. 89602ae5 8b4dfc          mov     ecx,dword ptr [ebp-4]
    Почему это не адрес возврата, его не видно в колстеке. Что там за код ?

    Будем гадать на кофейной гуще =)
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Malfoy
    Кто сказал, что не возврата? В стеке лежит на месте.
    h0t
    В моей гуще вырисовывается повторное освобождение памяти.
     
  9. Malfoy

    Malfoy New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2012
    Сообщения:
    698
    l_inc
    Точно, не заметил.
     
  10. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Да когда писал оштбся, теперь поправил там выше кусок кода _ReadFile и был

    Не совсем понятно чем поможет в данной ситуации.

    Вроде как не переполнение.

    Это именно адрес возврата из ExFreePoolWithTag.
    Перед освобождением _ReadFile вызывается, просто ошибся когда на форум забивал, не заметил извиняюсь.

    P.S. точно не повторное освобождение.

    P.S.1. символы могу подгрузить, но вот смысла большого не вижу, вроде как и так стек понятен.

    P.S.2. Есть подозрение на функцию _ReadFile, но вроде IRP для чтения создается в моем понимании адекватно, может ошибаюсь.
     
  11. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Выложи дамп уже, сами разберёмся, что надо, а что не надо. А ещё лучше выложи все файлы сразу: исходники, бинарники и символы.

    Перепиши с использованием IoBuildAsynchronousFsdRequest(), не занимайся самодеятельностью. Да, и событие следует инициализировать как NotificationEvent, а не как у тебя.
     
  12. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Как делал? Надо так:
    Потому что русским языком написано, что WRONG_SYMBOLS.
    И потому что NtClose() и FltGetIrpName() никак не могут посылать IRP-запросы.
     
  13. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Делал, verifier молчит как партизан, если вылетает в BSOD то только с той же ошибкой что и без verifier'a.

    Дамп с символами

    Код (Text):
    1. *******************************************************************************
    2. *                                                                             *
    3. *                        Bugcheck Analysis                                    *
    4. *                                                                             *
    5. *******************************************************************************
    6.  
    7. PFN_LIST_CORRUPT (4e)
    8. Typically caused by drivers passing bad memory descriptor lists (ie: calling
    9. MmUnlockPages twice with the same list, etc).  If a kernel debugger is
    10. available get the stack trace.
    11. Arguments:
    12. Arg1: 0000009a,
    13. Arg2: 0005c53b
    14. Arg3: 00000006
    15. Arg4: 00000002
    16.  
    17. Debugging Details:
    18. ------------------
    19.  
    20. PEB is paged out (Peb.Ldr = 7ffdc00c).  Type ".hh dbgerr001" for details
    21. PEB is paged out (Peb.Ldr = 7ffdc00c).  Type ".hh dbgerr001" for details
    22.  
    23. BUGCHECK_STR:  0x4E_9a
    24.  
    25. DEFAULT_BUCKET_ID:  VISTA_DRIVER_FAULT
    26.  
    27. PROCESS_NAME:  svchost.exe
    28.  
    29. CURRENT_IRQL:  0
    30.  
    31. LAST_CONTROL_TRANSFER:  from 82934544 to 82928f20
    32.  
    33. STACK_TEXT:  
    34. 87dc6c08 82934544 0000004e 0000009a 0005c53b nt!KeBugCheckEx+0x1e
    35. 87dc6c20 8296a12a 00000000 00011000 00000000 nt!MiBadRefCount+0x26
    36. 87dc6d00 8296bef1 81e3a000 00011000 81e241bf nt!MiFreePoolPages+0x124
    37. 87dc6d68 82b7cf90 81e3a000 72767346 81e24008 nt!ExFreePoolWithTag+0x436
    38. 87dc6d7c 85997ae5 81e3a000 72767346 00005000 nt!VerifierExFreePoolWithTag+0x30
    39. 87dc76d4 85998a48 81e1ef80 8ab91f58 81e241e0 driver!isProtected+0x305 [f:\driver\driver.c @ 1311]
    40. 87dc7704 828c2933 8ab91ea0 81e24008 00000000 driver!HookDone+0x78 [f:\driver\driver.c @ 2034]
    41. 87dc7748 82b7bb64 00000000 81e24008 00000000 nt!IopfCompleteRequest+0x128
    42. 87dc77b0 837499a7 87dc77d0 83749aa1 81e24008 nt!IovCompleteRequest+0x133
    43. 87dc77b8 83749aa1 81e24008 00000000 81e24008 fltmgr!FltpCompleteRequest+0x2d
    44. 87dc77d0 8374a2e9 8a92fc18 81e24008 00000000 fltmgr!FltpSynchronizeIoCleanup+0x4f
    45. 87dc77f8 8375d8c9 87dc7818 00000000 00000000 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x387
    46. 87dc7844 82b7b6c3 8ab49808 8abdc008 81e241e0 fltmgr!FltpCreate+0x2db
    47. 87dc7868 8288154a 00000000 81e24204 8ab49808 nt!IovCallDriver+0x258
    48. 87dc787c 859989bd 870c1880 81e24008 81e241e0 nt!IofCallDriver+0x1b
    49. 87dc7898 8599820f 8ab91ea0 81e24008 87dc78cc driver!HookDispatchRoutine+0x5d [f:\driver\driver.c @ 2013]
    50. 87dc78a8 82b7b6c3 8ab91ea0 81e24008 00000000 driver!driverDispatchRoutine+0x2f [f:\driver\driver.c @ 1625]
    51. 87dc78cc 8288154a 00000000 81e24008 8ab91ea0 nt!IovCallDriver+0x258
    52. 87dc78e0 8374a20c 81e24008 00000000 81e24204 nt!IofCallDriver+0x1b
    53. 87dc7904 8375d8c9 87dc7924 871fbed8 00000000 fltmgr!FltpLegacyProcessingAfterPreCallbacksCompleted+0x2aa
    54. 87dc7950 82b7b6c3 871fbed8 871fb998 81e1ef80 fltmgr!FltpCreate+0x2db
    55. 87dc7974 8288154a 00000000 81e1efdc 871fbed8 nt!IovCallDriver+0x258
    56. 87dc7988 82a912a9 bc4c3936 87dc7b30 00000000 nt!IofCallDriver+0x1b
    57. 87dc7a60 82a70ac5 8aaf9948 855f7330 87047008 nt!IopParseDevice+0xed7
    58. 87dc7adc 82a80ed6 00000000 87dc7b30 00000040 nt!ObpLookupObjectName+0x4fa
    59. 87dc7b38 82a779b4 014def38 855f7330 81e1ef01 nt!ObOpenObjectByName+0x165
    60. 87dc7bb4 82a9b218 014def94 00100080 014def38 nt!IopCreateFile+0x673
    61. 87dc7c00 828881ea 014def94 00100080 014def38 nt!NtCreateFile+0x34
    62. 87dc7c00 77cf70b4 014def94 00100080 014def38 nt!KiFastCallEntry+0x12a
    63. WARNING: Frame IP not in any known module. Following frames may be wrong.
    64. 014def9c 00000000 00000000 00000000 00000000 0x77cf70b4
    65.  
    66.  
    67. STACK_COMMAND:  kb
    68.  
    69. FOLLOWUP_IP:
    70. driver!isProtected+305 [f:\driver\driver.c @ 1311]
    71. 85997ae5 8b4dfc          mov     ecx,dword ptr [ebp-4]
    72.  
    73. SYMBOL_STACK_INDEX:  5
    74.  
    75. SYMBOL_NAME:  driver!isProtected+305
    76.  
    77. FOLLOWUP_NAME:  MachineOwner
    78.  
    79. MODULE_NAME: driver
    80.  
    81. IMAGE_NAME:  driver.sys
    82.  
    83. DEBUG_FLR_IMAGE_TIMESTAMP:  4f1021e8
    84.  
    85. FAILURE_BUCKET_ID:  0x4E_9a_VRF_driver!isProtected+305
    86.  
    87. BUCKET_ID:  0x4E_9a_VRF_driver!isProtected+305
    88.  
    89. Followup: MachineOwner
    90. ---------
     
  14. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Во первых x64 прав используйте IoBuildAsynchronousFsdRequest

    Вообще кодес должен быть что то вроде
     
  15. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Понимаете, мне в целом интересно что не так, на худой конец я всегда могу ZwReadFile заюзать.
    Интересно почему это происходит в моем коде.

    Возможно, но не стыкуется вот с каким фактом: я работаю только с одним DeviceObject'om. Часть запросов проходит
    а какой-то выносит освобождение памяти. Причем, если поменять динамическое выделение на статическое то
    обвалы, вроде как, прекращаются.
    В любом случае за идею с DO_DIRECT_IO спасибо я подумаю что это может за собой повлечь.
     
  16. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    h0t
    Что не понятного это ведь очевидно как дважды два!!! Имхо проще не куда!
    Простыми словами: У вас есть лок на память, а потом вы делаете фри не хорошо ведь, правильно?:
    На вашу память был кол типо **DeferredLockPages.
    Вообщем вывод:
    1) Дебажить устройство с Flags
    2) Юзать годную функту IoBuildAsynchronousFsdRequest. (Но походу в вашем контексте годится IoBuildSynchronousFsdRequest, ну или проще Zw**** - но это немного уныло).
     
  17. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    П.С. либо первый вариант юзаем в качестве интереса так как впринице кодес все равно не годный и очень не красиво это все ... а бы удалил такой кодес. Второй вариант верный.
     
  18. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    h0t
    Из кода вообще не ясно, как оно умудряется работать. Ни SystemBuffer, ни MdlAddress не заполнены. Насколько я помню, IRP::UserBuffer используется только для IRP_BUFFERED_IO -- туда копируется информация из SystemBuffer. Как целевой драйвер вернет информацию?
     
  19. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    shchetinin
    Спасибо еще раз)
     
  20. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    Не правильно помните. Для IRP_BUFFERED_IO нужен SystemBuffer.