Не пойму причину "падения системы"..

Тема в разделе "WASM.BEGINNERS", создана пользователем test555, 2 дек 2008.

  1. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Драйвер, перехватываю ntClose
    Перехват идет успешно. Пытаюсь извлечь имя закрываемого для записи файла:

    Код (Text):
    1. NTSTATUS NewNtClose( IN HANDLE  Handle)
    2. {NTSTATUS D, status;
    3. PFILE_OBJECT pFileObject;
    4. UNICODE_STRING devpath, dev2;
    5. ANSI_STRING ansiStr;
    6.                 status = ObReferenceObjectByHandle(Handle,
    7.                                        0,
    8.                                        *IoFileObjectType,
    9.                                        KernelMode,
    10.                                        &pFileObject,
    11.                                        NULL
    12.                                        );
    13.                                        
    14.                                    
    15. if (status ==0 ) {
    16.  
    17. if ( pFileObject->WriteAccess)  {//до этого места доходит без проблем
    18.             //  RtlVolumeDeviceToDosName(pFileObject->DeviceObject , &devpath);
    19.                 RtlInitUnicodeString(&dev2, L"\\??\\F:");
    20.                
    21.         //  status =    RtlAppendUnicodeStringToString(&devpath, &pFileObject->FileName );
    22.             //RtlUnicodeStringToAnsiString( &ansiStr, &devpath, TRUE );
    23. ..
    24.            
    25.  
    26.                                    
    27.     //  DPRINT("FILE CLOSE =%S %S",devpath.Buffer ,  pFileObject->FileName.Buffer);
    28.     // если RtlVolumeDeviceToDosName включен, то выводится полный путь..           
    29.                                 //  ExFreePool(devpath.Buffer);
    30.                                     }
    31.  
    32. }
    33. if (pFileObject!=NULL) ObDereferenceObject(&pFileObject);
    34.  
    35. return TrueNtClose(Handle);
    36. }
    В таком виде код работает, ничего не падает.
    Если снять комментарий с первой строки на вторую,
    RtlVolumeDeviceToDosName(pFileObject->DeviceObject , &devpath);
    // RtlInitUnicodeString(&dev2, L"\\??\\F:");
    То тоже работает, причем
    DPRINT("FILE CLOSE =%S %S",devpath.Buffer , pFileObject->FileName.Buffer);
    выводит полный пусть к файлу, как и надо.

    А вот если поставить одновременно
    RtlVolumeDeviceToDosName(pFileObject->DeviceObject , &devpath);
    RtlInitUnicodeString(&dev2, L"\\??\\F:");
    То система падает.
    Я хотел в юникод строку RtlVolumeDeviceToDosName вначале внести имя диска, потом либо добавить
    RtlAppendUnicodeStringToString к ней путь файла, и потом уже с использованием AnsiString перенести это все в глобальную переменную, как это сделано в перехватчике ntOpenFile.

    Для примера:
    Код (Text):
    1. PVOID g_buffer;
    2. g_buffer= ExAllocatePool(NonPagedPool, MAX_PATH_2);
    3. ..
    4. ANSI_STRING ansiStr;
    5. RtlUnicodeStringToAnsiString( &ansiStr, ObjectAttributes->ObjectName, TRUE );
    6.     I= (ansiStr.Length > 99? 99: ansiStr.Length);
    7.        
    8.             memset(g_buffer, 0 ,MAX_PATH_2);
    9.             strncpy(g_buffer, ansiStr.Buffer, I);
    10.             strcat(g_buffer,"\0");
    11.             RtlFreeAnsiString(&ansiStr);
    работает.

    Если же в первом коде одновременно
    RtlVolumeDeviceToDosName(pFileObject->DeviceObject , &devpath);
    RtlUnicodeStringToAnsiString( &ansiStr, &devpath, TRUE );

    То происходит аналогичное падение системы.. То есть он не хочет инициализировать 2 разных юникод-строки подряд, или инит+добавить, или инит+копия в анси..
    Уже раз 15 перегружал комп, не знаю чего поделать... В других местах кода - работает.
    Спасибо.

    Солдатова читал (пример про копирование юникода в анси - взят из него..
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Покажи анализ крэш-дампа.
     
  3. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    А как это сделать?
     
  4. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Засунь в Windbg файл MEMORY.dmp из папки WINDOWS( если его нет то system properties -- advanced -- startup and recovery -- writing debug information выбери kernel memory dump и перезапусти дров, подожди пока в бсоде сохранится информация на диск) потом набери !analyze -v, и пришли, что он покажет.
     
  5. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Качается пакет символов..
     
  6. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Код (Text):
    1. kd> !analyze -v
    2. ERROR: FindPlugIns 8007007b
    3. *******************************************************************************
    4. *                                                                             *
    5. *                        Bugcheck Analysis                                    *
    6. *                                                                             *
    7. *******************************************************************************
    8.  
    9. KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e)
    10. This is a very common bugcheck.  Usually the exception address pinpoints
    11. the driver/function that caused the problem.  Always note this address
    12. as well as the link date of the driver/image that contains this address.
    13. Some common problems are exception code 0x80000003.  This means a hard
    14. coded breakpoint or assertion was hit, but this system was booted
    15. /NODEBUG.  This is not supposed to happen as developers should never have
    16. hardcoded breakpoints in retail code, but ...
    17. If this happens, make sure a debugger gets connected, and the
    18. system is booted /DEBUG.  This will let us see why this breakpoint is
    19. happening.
    20. Arguments:
    21. Arg1: c0000005, The exception code that was not handled
    22. Arg2: 53d638ae, The address that the exception occurred at
    23. Arg3: ae7753cf, Trap Frame
    24. Arg4: 00000000
    25.  
    26. Debugging Details:
    27. ------------------
    28.  
    29. PEB is paged out (Peb.Ldr = 7ffd400c).  Type ".hh dbgerr001" for details
    30. PEB is paged out (Peb.Ldr = 7ffd400c).  Type ".hh dbgerr001" for details
    31.  
    32. EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - Инструкция по адресу "0x%08lx" обратилась к памяти по адресу "0x%08lx". Память не может быть "%s".
    33.  
    34. FAULTING_IP:
    35. +53d638ae
    36. 53d638ae ??              ???
    37.  
    38. TRAP_FRAME:  ae7753cf -- (.trap 0xffffffffae7753cf)
    39. ErrCode = 00000010
    40. eax=c0000008 ebx=ba64e3e4 ecx=00000000 edx=00000000 esi=0007f3b4 edi=ae775444
    41. eip=53d638ae esp=ae775443 ebp=77544488 iopl=0         nv up ei pl zr na pe nc
    42. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
    43. 53d638ae ??              ???
    44. Resetting default scope
    45.  
    46. DEFAULT_BUCKET_ID:  DRIVER_FAULT
    47.  
    48. BUGCHECK_STR:  0x8E
    49.  
    50. PROCESS_NAME:  ctfmon.exe
    51.  
    52. UNALIGNED_STACK_POINTER:  ae774f7f
    53.  
    54. LAST_CONTROL_TRANSFER:  from 804fccef to 804f8cb5
    55.  
    56. STACK_TEXT:  
    57. ae774f97 804fccef 0000008e c0000005 53d638ae nt!KeBugCheckEx+0x1b
    58. ae77535f 8053e081 ae77537b 00000000 ae7753cf nt!KiDispatchException+0x3b1
    59. ae7753c7 8053e032 77544488 53d638ae badb0d00 nt!CommonDispatchException+0x4d
    60. ae7753cf 53d638ae badb0d00 00000000 07f3b4ae nt!KiExceptionExit+0x18a
    61. WARNING: Frame IP not in any known module. Following frames may be wrong.
    62. ae7753d3 badb0d00 00000000 07f3b4ae 64e3e400 0x53d638ae
    63. ae7753d7 00000000 07f3b4ae 64e3e400 3bd2a0ba 0xbadb0d00
    64.  
    65.  
    66. STACK_COMMAND:  kb
    67.  
    68. FOLLOWUP_IP:
    69. nt!KiDispatchException+3b1
    70. 804fccef cc              int     3
    71.  
    72. SYMBOL_STACK_INDEX:  1
    73.  
    74. SYMBOL_NAME:  nt!KiDispatchException+3b1
    75.  
    76. FOLLOWUP_NAME:  MachineOwner
    77.  
    78. MODULE_NAME: nt
    79.  
    80. IMAGE_NAME:  ntkrnlpa.exe
    81.  
    82. DEBUG_FLR_IMAGE_TIMESTAMP:  4802516a
    83.  
    84. FAILURE_BUCKET_ID:  0x8E_nt!KiDispatchException+3b1
    85.  
    86. BUCKET_ID:  0x8E_nt!KiDispatchException+3b1
    87.  
    88. Followup: MachineOwner
     
  7. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Все это удовольствие было при:
    Код (Text):
    1.             RtlVolumeDeviceToDosName(pFileObject->DeviceObject , &devpath);
    2.             RtlUnicodeStringToAnsiString( &ansiStr, &devpath, TRUE );
    3.             RtlFreeAnsiString(&ansiStr);
     
  8. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Или еще пример
    Код (Text):
    1. kd> !analyze -v
    2. ERROR: FindPlugIns 8007007b
    3. *******************************************************************************
    4. *                                                                             *
    5. *                        Bugcheck Analysis                                    *
    6. *                                                                             *
    7. *******************************************************************************
    8.  
    9. KERNEL_MODE_EXCEPTION_NOT_HANDLED (8e)
    10. This is a very common bugcheck.  Usually the exception address pinpoints
    11. the driver/function that caused the problem.  Always note this address
    12. as well as the link date of the driver/image that contains this address.
    13. Some common problems are exception code 0x80000003.  This means a hard
    14. coded breakpoint or assertion was hit, but this system was booted
    15. /NODEBUG.  This is not supposed to happen as developers should never have
    16. hardcoded breakpoints in retail code, but ...
    17. If this happens, make sure a debugger gets connected, and the
    18. system is booted /DEBUG.  This will let us see why this breakpoint is
    19. happening.
    20. Arguments:
    21. Arg1: c0000005, The exception code that was not handled
    22. Arg2: 53d638ae, The address that the exception occurred at
    23. Arg3: ae8ad7ff, Trap Frame
    24. Arg4: 00000000
    25.  
    26. Debugging Details:
    27. ------------------
    28.  
    29. PEB is paged out (Peb.Ldr = 7ffdd00c).  Type ".hh dbgerr001" for details
    30. PEB is paged out (Peb.Ldr = 7ffdd00c).  Type ".hh dbgerr001" for details
    31.  
    32. EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>
    33.  
    34. FAULTING_IP:
    35. +53d638ae
    36. 53d638ae ??              ???
    37.  
    38. TRAP_FRAME:  ae8ad7ff -- (.trap 0xffffffffae8ad7ff)
    39. ErrCode = 00000010
    40. eax=c0000008 ebx=ba5ce3f2 ecx=00000000 edx=00000000 esi=0012e408 edi=ae8ad874
    41. eip=53d638ae esp=ae8ad873 ebp=8ad87488 iopl=0         nv up ei pl zr na pe nc
    42. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010246
    43. 53d638ae ??              ???
    44. Resetting default scope
    45.  
    46. DEFAULT_BUCKET_ID:  DRIVER_FAULT
    47.  
    48. BUGCHECK_STR:  0x8E
    49.  
    50. PROCESS_NAME:  Project1.exe
    51.  
    52. UNALIGNED_STACK_POINTER:  ae8ad3af
    53.  
    54. LAST_CONTROL_TRANSFER:  from 804fccef to 804f8cb5
    55.  
    56. STACK_TEXT:  
    57. ae8ad3c7 804fccef 0000008e c0000005 53d638ae nt!KeBugCheckEx+0x1b
    58. ae8ad78f 8053e081 ae8ad7ab 00000000 ae8ad7ff nt!KiDispatchException+0x3b1
    59. ae8ad7f7 8053e032 8ad87488 53d638ae badb0d00 nt!CommonDispatchException+0x4d
    60. ae8ad7ff 53d638ae badb0d00 00000000 12e408ae nt!KiExceptionExit+0x18a
    61. WARNING: Frame IP not in any known module. Following frames may be wrong.
    62. ae8ad803 badb0d00 00000000 12e408ae 5ce3f200 0x53d638ae
    63. ae8ad807 00000000 12e408ae 5ce3f200 a3a090ba 0xbadb0d00
    64.  
    65.  
    66. STACK_COMMAND:  kb
    67.  
    68. FOLLOWUP_IP:
    69. nt!KiDispatchException+3b1
    70. 804fccef cc              int     3
    71.  
    72. SYMBOL_STACK_INDEX:  1
    73.  
    74. SYMBOL_NAME:  nt!KiDispatchException+3b1
    75.  
    76. FOLLOWUP_NAME:  MachineOwner
    77.  
    78. MODULE_NAME: nt
    79.  
    80. IMAGE_NAME:  ntkrnlpa.exe
    81.  
    82. DEBUG_FLR_IMAGE_TIMESTAMP:  4802516a
    83.  
    84. FAILURE_BUCKET_ID:  0x8E_nt!KiDispatchException+3b1
    85.  
    86. BUCKET_ID:  0x8E_nt!KiDispatchException+3b1
    87.  
    88. Followup: MachineOwner
    89. ---------
    Выскакивает при
    Код (Text):
    1. RtlInitUnicodeString(&devpath, L"\\??\\F:");
    2.             RtlUnicodeStringToAnsiString( &ansiStr, &devpath, TRUE );
    3.             RtlFreeAnsiString(&ansiStr);
     
  9. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Что делаать то....
     
  10. 0x56

    0x56 New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2008
    Сообщения:
    63
    ну 1е что хочется сказать есть пришпиленная тема в кернел разделе, как дебажить драйвера вам искать.
    нафиг крэшдампы без отладочной информации в драйвере?
     
  11. Osen

    Osen Рие

    Публикаций:
    0
    Регистрация:
    5 апр 2008
    Сообщения:
    283
    Адрес:
    Париж
    test555
    Просто проверяй ВСЕ вызовы на успех с помощью NT_SUCCESS(). Возврат всех функций, которые могут возвратить хоть что-то отличное от VOID.
     
  12. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Итак, пришел к вывочу, что в той процедуре можно использовать только ограниченное кол-во функций..
    Вынес весь обработчик в отдельную процедуру, в NewntClose вызываю ее..
    Ситуация такая же, т.е. если добавить какую-нибудь вполне легальную функцию, то происходит падение системы.
    Если же поставить заведомо ложный IF, и в нем написать что-либо, то сбоя не проиходит..

    Я уже не знаю что делать, проверил, вроде перехватываю нужный вызов, эти же операции в других обработчиков к падению системы не приводят...
    Может дело в том, что в процессе обработки вызывается каким-то образом рекурсивно ntClose ??
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    test555
    очень пахнет stack corruption'ом
    потому что badb0d00 это сигнатура в KTRAP_FRAME который в начале стека любого потока лежит если он в режиме ядра
    тогда был бы, вероятно, UNEXPECTED_KERNEL_TRAP double fault изза исчерпания стека ядра.

    UPD:
    но кстати может быть, поскольку RtlVolumeDeviceToDosName генерит IRP чтобы узнать имя. а обрабтчик IRP в драйвере может делать что угодно
     
  14. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Great, а что можно поделать с этим.. Хотя бы идеи..
    Мои - только перед каждым вызовом снимать перехват на нормальный обработчик ntClose а после заменить на мой..
     
  15. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    test555
    у тебя стопудово рекурсия
    клозе перехватывать можно только так:
    Код (Text):
    1. bBusy = FALSE;
    2. newClose(handle)
    3. {
    4.  if(!bBusy)
    5.  {
    6.    bBusy = TRUE;
    7.    ... // ZwQueryObject(handle, ObjectNameInformation ...)
    8.    bBusy = FALSE;
    9.  }
    10.   orgClose(handle);
    11. }
    и никак иначе! проверено электроникой
     
  16. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    Код (Text):
    1.  if(!bBusy)
    2.  {
    3.    bBusy = TRUE;
    Мне кажется, это будет не thread safe.
     
  17. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Partner,т.е. в тот момент когда обрабатывается
    Код (Text):
    1. bBusy = TRUE;
    2.    ... // ZwQueryObject(handle, ObjectNameInformation ...)
    Другой поток может в этот момент использовать ntClose для закрытия того что мне нужно и тем самым действие будет проигнорировано моим обработчиком?

    НЕ могу придумать, как с этим бороться.. Мьютексы здесь не подходят (
    Может в таком случае ввести массив, куда складывать что-то типа TreadId, и если они есть в списке, то пропустить, а потом удалить...
     
  18. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    на скорую руку придумал

    FAST_MUTEX Mutex;

    ntClose()
    {
    if (ExTryToAcquireFastMutex(&Mutex))
    {
    // do some actions
    ExReleaseFastMutex (&Mutex);
    }
    trueNtClose();
    }
     
  19. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    этот мой юзер-моде код хранил bBusy в TLS

    клозе из разных потоков наперегонки - это редчайшая редкость. ни разу не видел такого. если количество клозе равно количеству опен - то ниче страшного в этом случае не произойдет (вообще ниче не произойдет до последнего клозе)

    для ядерного кода - нормально будет
     
  20. test555

    test555 New Member

    Публикаций:
    0
    Регистрация:
    7 дек 2007
    Сообщения:
    241
    Great,
    Итого получиться что при первом вызове мьютекс будет установиться в состояние "занят", делаем операции, в них если вызывается ntclose то проходим мимо, освобождаем фастмьютекс...

    А что если другой поток во время работы // do some actions вызовет ntClose ?
    Обработчик прийдет мимо?

    Насколько я понимаю, мьютекс может быть захвачен и освобожден только одним потоком (в том числе рекурсивно) а фастмьютекс - только один раз...

    То есть один поток захыватывает, а остальные остаются в пролете?

    Я правильно понимаю, или еще идти читать документацию?