BSOD при ZwCreateFile

Тема в разделе "WASM.BEGINNERS", создана пользователем RUStx88, 10 июн 2011.

  1. RUStx88

    RUStx88 New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2010
    Сообщения:
    25
    объясните знающие люди, что не хватает винде (или моему моску), чего винда валится в бсод? уже руки опускаются

    опишу проблему:
    при попытке доступа к файлу читаем этот файл (первые 1024 байта) и сравниваем с эталоном, хранящимся в буфере, если == возврат STATUS_ACCESS_DENIED, если различные - разрешаем доступ
    у мня на виртуалке отрабатывает норм, не открывает такие файлы (если маска совпадает), НО, по непонятным причинам иногда всё равно вываливается в блю скрин, далее, диспетчер задач не может запуститься и система почти намертво зависает, выгружаю дров, сразу же запускается диспетчер задач и через пару моментов снова валится

    вот приаттаченный код
    NewZw*** - "моя" функция
    OldZw*** - настоящая функция

    Код (Text):
    1. NTSTATUS NewZwCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength) {
    2.   NTSTATUS
    3.     ns = STATUS_ACCESS_DENIED;
    4.   HANDLE
    5.     pH;
    6.   OBJECT_ATTRIBUTES
    7.     attr = { 0 };
    8.   IO_STATUS_BLOCK
    9.     ios = { 0 };
    10.   CHAR
    11.     bufer [MAXBUF];
    12.   LARGE_INTEGER
    13.     liOffset = { 0 };
    14.  
    15.   RtlZeroMemory(bufer, MAXBUF);
    16.      
    17.   __try {
    18.     InitializeObjectAttributes(&attr, ObjectAttributes->ObjectName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
    19.  
    20.     ns = IoCreateFile(&pH, NULL, &attr, &ios, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, 0, 0, CreateFileTypeNone, NULL, IO_NO_PARAMETER_CHECKING);
    21.  
    22.     if (NT_SUCCESS(ns)) {
    23.       ns = ZwReadFile(pH, NULL, NULL, NULL, &ios, bufer, MAXBUF, &liOffset, NULL);
    24.       ZwClose(pH);
    25.  
    26.       if (NT_SUCCESS(ns)) {
    27.         if (checkBufer(bufer, data.myBuf, data.myBufCount)) {
    28.           return STATUS_ACCESS_DENIED;
    29.         }
    30.       }
    31.     }
    32.   }
    33.   __finally {
    34. #ifdef DBG
    35.     DbgPrint("%ws\n", ObjectAttributes->ObjectName->Buffer);
    36. #endif
    37.   }
    38.  
    39.   return OldZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);
    40. }
    если все эти приблуды удалить с проверкой буфера и чтением файла - всё работает нормально, загружается\выгружается, никаких бсодов нет, значит, хук функции ставится верно и снимается тоже

    буфер выделяется так (поправьте меня, если глупо здесь всё)

    Код (Text):
    1. data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount);
    2. if (!data.myBuf)
    3.   return STATUS_FATAL_APP_EXIT;
    4. for (i = 0; i < data.myBufCount; i++) {
    5.   data.myBuf[i] = (CHAR *)ExAllocatePool(PagedPool, MAXBUF);
    6.   if (!data.myBuf[i])
    7.     return STATUS_FATAL_APP_EXIT;
    8.   RtlCopyMemory(data.myBuf[i], tmp->myBuf[i], MAXBUF);
    9. }
    сравнение буферов
    Код (Text):
    1. BOOLEAN checkBufer(CHAR * pBufer, CHAR ** pFake, UINT32 count) {
    2.  
    3.   CHAR
    4.     * pS = NULL;
    5.   UINT32
    6.     i, j;
    7.   __try {
    8.     for (i = 0; i < count; i++) {
    9.       pS = &pFake[i][0];
    10.       for (j = 0; j < MAXBUF; j++) {
    11.         if (*pBufer++ != *pS++) {
    12.           return FALSE;
    13.         }
    14.       }
    15.     }
    16.   }
    17.   __except (EXCEPTION_EXECUTE_HANDLER) {
    18.     return FALSE;
    19.   }
    20.  
    21.   return TRUE;
    22. }
    всем спасибо, очень нужна помощь..)
     
  2. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    1. а если оставить чтение из фала, но убрать проверку что будет?
    2. сколки ядерная машина?
    3. не сочтите за придирку но имя bufer меня вводит в ступор назовите buffer)))

    гы а что это у сервера со временем???)
     
  3. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
  4. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    трудно сказать сразу, реентерабельна ли функция NewZwCreateFile, можно поисследовать этот вопрос или попробовать поставить блокировку. и нужен дамп
     
  5. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    такое чувство, что проблема в многопроцессорности
     
  6. RUStx88

    RUStx88 New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2010
    Сообщения:
    25
    проверку буферов убирал - также падает, причем подозрение у мня в том, что падает именно при обращении к файлу функцией ZwCreateFile либо IoCreateFile, мб я с флагами что начудил? уже и так и так их ставил, не помогает...

    эти Create то выдают ошибки c0000005 (STATUS_ACCESS_VIOLATION), либо c000000d (STATUS_INVALID_PARAMETER)

    а система валится с ошибкой 0x0000008E

    пробовал открывать ZwOpenFile, фалы открывает, читает, НО все равно падает, причем проверку ставил KeGetCurrentIrql == PASSIVE_LEVEL, и мне интересно, пчму не отлавливает ошибку __try {...} ?

    от зависания диспетчера задач удалось избавиться простым сравнением имени обращения с запросом pipe

    _wcnicmp(ObjectAttributes->ObjectName->Buffer, L"\\??\\PIPE", 8)

    это из-за них зависал диспетчер...

    тестировал на одноядерном проце и на двухядерном - трабла одна...

    вот дампы
     
  7. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    RUStx88
    вот это ds:0023:00000000=???? всегда говорит об указателе " в никуда", т.е. попытке обратиться в невыделенную область памяти
    отладчик тебе в помощь
     
  8. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    ну у вас, похоже, ObjectAttributes->ObjectName->Buffer равен нулю

    _wcnicmp(ObjectAttributes->ObjectName->Buffer, L"\\??\\PIPE", 8)
    ba507bac ba40106d 00000000 ba4020d0 00000008 nt!_wcsnicmp+0x15
     
  9. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Код (Text):
    1. 1: kd> .trap 0xffffffffba507b34
    2. ErrCode = 00000000
    3. eax=00000000 ebx=ba401010 ecx=ba507ccc edx=00000000 esi=ba4020d0 edi=ba507c1c
    4. eip=8053a014 esp=ba507ba8 ebp=ba507bac iopl=0         nv up ei pl zr na pe nc
    5. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00210246
    6. nt!_wcsnicmp+0x15:
    7. 8053a014 668b02          mov     ax,word ptr [edx]        ds:0023:00000000=????
    Вот как раз на проверки и свалился ...
     
  10. RUStx88

    RUStx88 New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2010
    Сообщения:
    25
    всем огромное спасибо!
    появилась еще одна трабла - BSOD при выгрузке дрова
    WinDBG говорит, что падение происходит тут (при освобождении буфера занимаемой памяти)

    Код (Text):
    1. STACK_COMMAND:  kb
    2.  
    3. FOLLOWUP_IP:
    4. driver!UnLoadDriver+f9 [c:\driver.c @ 468]
    5. f882fd49 ??              ???
    6.  
    7. FAULTING_SOURCE_CODE:  
    8.    464:         data.myBuf[i] = NULL;
    9.    465:       }
    10.    466:     }
    11.    467:     ExFreePool(data.myBuf);
    12. >  468:     data.myBuf = NULL;
    13.    469:   }
    14.    470:   IoDeleteSymbolicLink(&SymbolicLinkName);
    15.    471:   IoDeleteDevice(DeviceObject);
    16.    472: #ifdef DBG
    17.    473:   DbgPrint("driver stop\n");
    18.  
    19.  
    20. SYMBOL_STACK_INDEX:  2
    21.  
    22. SYMBOL_NAME:  driver!UnLoadDriver+f9
    кусок кода выделения буфера был приведен выше

    вот полный код выгрузки драйвера

    Код (Text):
    1. VOID UnLoadDriver(IN PDRIVER_OBJECT DriverObject) {
    2.   ULONG
    3.     i = 0;
    4.  
    5.   {
    6.     InterlockedExchange((PLONG)&MappedSystemCallTable[procCreateFile], (LONG)OldZwCreateFile);
    7.     InterlockedExchange((PLONG)&MappedSystemCallTable[procWriteVirtualMemory], (LONG)OldZwWriteVirtualMemory);
    8.     InterlockedExchange((PLONG)&MappedSystemCallTable[procOpenProcess], (LONG)OldZwOpenProcess);
    9.     InterlockedExchange((PLONG)&MappedSystemCallTable[procQuerySystemInformation], (LONG)OldZwQuerySystemInformation);
    10.   }
    11.  
    12.   if (g_pmdlSystemCall) {
    13.     MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall);
    14.     IoFreeMdl(g_pmdlSystemCall);
    15.   }
    16.  
    17.   if (data.myBuf) {
    18.     for (i = 0; i < data.myBufCount; i++) {
    19.       if (data.myBuf[i]) {
    20.         ExFreePool(data.myBuf[i]);
    21.         data.myBuf[i] = NULL;
    22.       }
    23.     }
    24.     ExFreePool(data.myBuf);
    25.     data.myBuf = NULL;
    26.   }
    27.  
    28.   IoDeleteSymbolicLink(&SymbolicLinkName);
    29.   IoDeleteDevice(DeviceObject);
    30. #ifdef DBG
    31.   DbgPrint("driver stop\n");
    32. #endif
    33. }
    разве я неправильно освобождаю память? или в чем проблема никак не пойму...
     
  11. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    RUStx88
    Код (Text):
    1.   if (data.myBuf) {
    2.     for (i = 0; i < data.myBufCount; i++) {
    3.       if (data.myBuf[i]) {
    4.         ExFreePool(data.myBuf[i]);
    5.         data.myBuf[i] = NULL;
    6.       }
    7.     }
    8.     ExFreePool(data.myBuf);
    9.     data.myBuf = NULL;
    10.   }
    Дважды одну и ту же память освобождаешь
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    steelfactor
    Нет, там не дважды. myBuf -- массив указателей, каждый из которых указывает на выделенную память. Сначала освобождается память по указателю из массива, затем сам массив.

    RUStx88
    А какой BSoD? BAD_POOL_HEADER? Если да, значит произошел выход за границы массива указателей при записи.
     
  13. RUStx88

    RUStx88 New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2010
    Сообщения:
    25
    проблема была в выделении памяти, лажанулся я
    Код (Text):
    1. data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount);
    нужно так

    Код (Text):
    1. data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount * sizeof(CHAR *));