объясните знающие люди, что не хватает винде (или моему моску), чего винда валится в бсод? уже руки опускаются опишу проблему: при попытке доступа к файлу читаем этот файл (первые 1024 байта) и сравниваем с эталоном, хранящимся в буфере, если == возврат STATUS_ACCESS_DENIED, если различные - разрешаем доступ у мня на виртуалке отрабатывает норм, не открывает такие файлы (если маска совпадает), НО, по непонятным причинам иногда всё равно вываливается в блю скрин, далее, диспетчер задач не может запуститься и система почти намертво зависает, выгружаю дров, сразу же запускается диспетчер задач и через пару моментов снова валится вот приаттаченный код NewZw*** - "моя" функция OldZw*** - настоящая функция Код (Text): 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) { NTSTATUS ns = STATUS_ACCESS_DENIED; HANDLE pH; OBJECT_ATTRIBUTES attr = { 0 }; IO_STATUS_BLOCK ios = { 0 }; CHAR bufer [MAXBUF]; LARGE_INTEGER liOffset = { 0 }; RtlZeroMemory(bufer, MAXBUF); __try { InitializeObjectAttributes(&attr, ObjectAttributes->ObjectName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); 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); if (NT_SUCCESS(ns)) { ns = ZwReadFile(pH, NULL, NULL, NULL, &ios, bufer, MAXBUF, &liOffset, NULL); ZwClose(pH); if (NT_SUCCESS(ns)) { if (checkBufer(bufer, data.myBuf, data.myBufCount)) { return STATUS_ACCESS_DENIED; } } } } __finally { #ifdef DBG DbgPrint("%ws\n", ObjectAttributes->ObjectName->Buffer); #endif } return OldZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength); } если все эти приблуды удалить с проверкой буфера и чтением файла - всё работает нормально, загружается\выгружается, никаких бсодов нет, значит, хук функции ставится верно и снимается тоже буфер выделяется так (поправьте меня, если глупо здесь всё) Код (Text): data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount); if (!data.myBuf) return STATUS_FATAL_APP_EXIT; for (i = 0; i < data.myBufCount; i++) { data.myBuf[i] = (CHAR *)ExAllocatePool(PagedPool, MAXBUF); if (!data.myBuf[i]) return STATUS_FATAL_APP_EXIT; RtlCopyMemory(data.myBuf[i], tmp->myBuf[i], MAXBUF); } сравнение буферов Код (Text): BOOLEAN checkBufer(CHAR * pBufer, CHAR ** pFake, UINT32 count) { CHAR * pS = NULL; UINT32 i, j; __try { for (i = 0; i < count; i++) { pS = &pFake[i][0]; for (j = 0; j < MAXBUF; j++) { if (*pBufer++ != *pS++) { return FALSE; } } } } __except (EXCEPTION_EXECUTE_HANDLER) { return FALSE; } return TRUE; } всем спасибо, очень нужна помощь..)
1. а если оставить чтение из фала, но убрать проверку что будет? 2. сколки ядерная машина? 3. не сочтите за придирку но имя bufer меня вводит в ступор назовите buffer))) гы а что это у сервера со временем???)
трудно сказать сразу, реентерабельна ли функция NewZwCreateFile, можно поисследовать этот вопрос или попробовать поставить блокировку. и нужен дамп
проверку буферов убирал - также падает, причем подозрение у мня в том, что падает именно при обращении к файлу функцией 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) это из-за них зависал диспетчер... тестировал на одноядерном проце и на двухядерном - трабла одна... вот дампы
RUStx88 вот это ds:0023:00000000=???? всегда говорит об указателе " в никуда", т.е. попытке обратиться в невыделенную область памяти отладчик тебе в помощь
ну у вас, похоже, ObjectAttributes->ObjectName->Buffer равен нулю _wcnicmp(ObjectAttributes->ObjectName->Buffer, L"\\??\\PIPE", 8) ba507bac ba40106d 00000000 ba4020d0 00000008 nt!_wcsnicmp+0x15
Код (Text): 1: kd> .trap 0xffffffffba507b34 ErrCode = 00000000 eax=00000000 ebx=ba401010 ecx=ba507ccc edx=00000000 esi=ba4020d0 edi=ba507c1c eip=8053a014 esp=ba507ba8 ebp=ba507bac iopl=0 nv up ei pl zr na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00210246 nt!_wcsnicmp+0x15: 8053a014 668b02 mov ax,word ptr [edx] ds:0023:00000000=???? Вот как раз на проверки и свалился ...
всем огромное спасибо! появилась еще одна трабла - BSOD при выгрузке дрова WinDBG говорит, что падение происходит тут (при освобождении буфера занимаемой памяти) Код (Text): STACK_COMMAND: kb FOLLOWUP_IP: driver!UnLoadDriver+f9 [c:\driver.c @ 468] f882fd49 ?? ??? FAULTING_SOURCE_CODE: 464: data.myBuf[i] = NULL; 465: } 466: } 467: ExFreePool(data.myBuf); > 468: data.myBuf = NULL; 469: } 470: IoDeleteSymbolicLink(&SymbolicLinkName); 471: IoDeleteDevice(DeviceObject); 472: #ifdef DBG 473: DbgPrint("driver stop\n"); SYMBOL_STACK_INDEX: 2 SYMBOL_NAME: driver!UnLoadDriver+f9 кусок кода выделения буфера был приведен выше вот полный код выгрузки драйвера Код (Text): VOID UnLoadDriver(IN PDRIVER_OBJECT DriverObject) { ULONG i = 0; { InterlockedExchange((PLONG)&MappedSystemCallTable[procCreateFile], (LONG)OldZwCreateFile); InterlockedExchange((PLONG)&MappedSystemCallTable[procWriteVirtualMemory], (LONG)OldZwWriteVirtualMemory); InterlockedExchange((PLONG)&MappedSystemCallTable[procOpenProcess], (LONG)OldZwOpenProcess); InterlockedExchange((PLONG)&MappedSystemCallTable[procQuerySystemInformation], (LONG)OldZwQuerySystemInformation); } if (g_pmdlSystemCall) { MmUnmapLockedPages(MappedSystemCallTable, g_pmdlSystemCall); IoFreeMdl(g_pmdlSystemCall); } if (data.myBuf) { for (i = 0; i < data.myBufCount; i++) { if (data.myBuf[i]) { ExFreePool(data.myBuf[i]); data.myBuf[i] = NULL; } } ExFreePool(data.myBuf); data.myBuf = NULL; } IoDeleteSymbolicLink(&SymbolicLinkName); IoDeleteDevice(DeviceObject); #ifdef DBG DbgPrint("driver stop\n"); #endif } разве я неправильно освобождаю память? или в чем проблема никак не пойму...
RUStx88 Код (Text): if (data.myBuf) { for (i = 0; i < data.myBufCount; i++) { if (data.myBuf[i]) { ExFreePool(data.myBuf[i]); data.myBuf[i] = NULL; } } ExFreePool(data.myBuf); data.myBuf = NULL; } Дважды одну и ту же память освобождаешь
steelfactor Нет, там не дважды. myBuf -- массив указателей, каждый из которых указывает на выделенную память. Сначала освобождается память по указателю из массива, затем сам массив. RUStx88 А какой BSoD? BAD_POOL_HEADER? Если да, значит произошел выход за границы массива указателей при записи.
проблема была в выделении памяти, лажанулся я Код (Text): data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount); нужно так Код (Text): data.myBuf = (CHAR **)ExAllocatePool(PagedPool, data.myBufCount * sizeof(CHAR *));