Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: управляемый фильтр дисков  (Прочитано 19954 раз)
0 Пользователей и 1 Гость смотрят эту тему.
elDraco
Гость
« : 07-12-2008 17:29 » 

необходимо написать управляемый фильтр-драйвер для дисков под Win XP, который разрешает запись на выбранных дисках
возникло несколько вопросов связанных с управлением списком дисков:
для каждого физического диска будет создан свой фильтрующий FDO, в этот момент мне надо как-то узнать блокировать запись на этот диск или нет (я предполагаю грузить драйвер до драйверов файловых систем, чтобы они ничего не успели изменить во время монтирования), поэтому вопрос:
1) где лучше держать список разрешённых дисков(реестр или файл на диске) и соответственно когда загружать (лучше всего имхо в DriverEntry и там же создать управляющий FDO)? предполагается хранение в виде количество разрешённых и потом список их uid? запрещённые хранить не предполагается
2) как его адекватно хранить в период выполнения(учитывая что количество дисков может меняться за счёт флэшек например), так чтобы он был доступен всем фильтрующим FDO(им только читать надо будет своё разрешение) и управляющему FDO(он может менять разрешения)? предполагаю хранить количество дисков в системе массив их uid и массив байтов с разрешениями, проблема в неизвестном размере и том что это фактически получаются глобальные переменные (которых насколько я понимаю нужно избегать)
3) как определить что я загрузился с этого диска, соответственно запись запрещать нельзя (где-то подобное вроде видел, но так уж за компанию)?
4) сохранять список надо только в DriverUnload и в Shutdown или ещё где-то?
5) блокировать достаточно только IRP_MJ_WRITE? или есть ещё способы осуществить физическую запись на носитель?
6) смена разрешения во время исполнения я так полагаю вполне может привести к бсоду, есть ли рекомендации как этого избежать? и вообще если я на любую попытку записи буду отвечать access denied виндовс это переживёт?
7) работать собираюсь только с физическими дисками (партишены не интересуют), следовательно если я правильно понимаю цепляться мне нужно под или над disk.sys?

зы: извиняюсь если похоже на поток сознания, просто постарался разделить интересующие вопросы на мелкие
зыы: приложил файл с функцией которой собираюсь читать uid'ы, будет ли она работать так как предполагается?

* tools.c (4.98 Кб - загружено 1397 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 07-12-2008 20:33 » 

1. на ваше усмотрение. загружать наверное не AddDevice... мне кажется.
2. в данном случае глобольные переменные не только допустимы, это как раз тот случай когда их надо использовать.
3. поищите поиском по форуме - вобще эту тему уже не раз обсуждали. в каком то поле IRP содержится имя файла.
4. сохранять... опять же если не путаю ничего - то по IRP_MJ_PNP - по REMOVE и SUPRISE_REMOVE.
1 и 4 - это если я правильно понял к чему вы фильтр аттачить будете. будет там PNP или нет...
5 опять же зависит от того к чему атачить
6 переживет я думаю... смену разрешения надо аккуратно реализовать)
7 эээ...а вот тут как раз не знаю) гляньте форум. тут народ не раз такой фильтр строил)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #2 : 08-12-2008 07:25 » 

3) видимо я не достаточно чётко выразился, мне нужно уметь определять является ли диск системным(то есть на нём расположен раздел с загружающейся сейчас системой) ещё в AddDevice, если пошли IRP то я уже должен знать, можно мне блокировать этот диск или нет. То есть подразумевается, что запись на него разрешена по умолчанию
4) сохранять я собираюсь только при выгрузке драйвера, например во время останова системы или я что-то путаю? хотя щас подумал, обрабатывать удаление устройств всё равно придётся, иначе в пользовательском ПО я никак не узнаю, что диска больше нет в системе

зы: если я правильно всё понимаю (я в этом пока новичёк, так сказать "боевое крещение") то цепляться мне нужно чем ближе к железу тем лучше (чтобы иметь возможность перехватить не только пользовательские запросы на запись, но и системные типа установки времени последнего изменения файла и тп), а целевые устройства для меня это носители информации(харды, флэшки там)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 08-12-2008 13:30 » 

3. можно вытащить через реестр. там должен быть такой ключ.
4. лучше по удалению. PNP посылается для конкретного диска. а unload там общий для всех экземпляров.

по зы - ну тут вопрос странный. если совсем близко к диску - придется поди и файловую систему самому разбитать? оно вам надо?) впрочем тут я не специалист - не знаю точно. а запросы к файлам через вас пройдут я думаю...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #4 : 08-12-2008 14:12 » 

по зы - ну тут вопрос странный. если совсем близко к диску - придется поди и файловую систему самому разбитать? оно вам надо?) впрочем тут я не специалист - не знаю точно. а запросы к файлам через вас пройдут я думаю...

я думаю что драйверы файловых систем будут преобразовывать запросы типа "записать в этот файл" в запросы типа "записать на этот хдд по такому-то смещению" и мне останется только заблокировать запрос на запись, или я что-то неправильно понял в идеологии? в конечном счёте, по моему разумению, любое обращение к диску это либо read, либо write, мне по сути надо встроиться туда, где уже остаются только эти read/write, наверно это будет самый нижний общий для всех storage драйвер
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 08-12-2008 20:27 » 

увы, с дисками никогда не разбирался, надо их стек смотреть.
так ничего - не скажу...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #6 : 17-12-2008 15:51 » 

написал драйвер, еле понял как отлаживаться на вмваре в итоге обнаружил проблему...
драйвер грузится в boot time, в DriverEntry мне передают мой ключ в реестре... могу ли я им воспользоваться? при попытке его открыть получаю инвэлид хэндл

посему вопрос, а как хранить настройки драйверам которые стартуют в boot time? когда вызывается AddDevice я должен уже знать что мне делать с этим устройством

моя функция загрузки списка разрешений:
Код:
NTSTATUS MWBLoadPermitList(){
//Ok
UNICODE_STRING DeviceListValueName;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE handle;  // Stores the open handle
NTSTATUS status;
PKEY_VALUE_FULL_INFORMATION ValueInfo;
LONG ValueSize;
LONG InnerCounter;

RtlInitUnicodeString(&DeviceListValueName, L"PermissionList");//<<<mem allocation for local use<<<
ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, sizeof(KEY_VALUE_FULL_INFORMATION));//<<<mem allocation for local use<<<
if(!ValueInfo){
return STATUS_INSUFFICIENT_RESOURCES;
}
DeviceList.ListCapacity = 100;
//---
DefaultPermission = MWBPermitAlways;//if not changed then key not found(first run, permit new disks)
InitializeObjectAttributes(&ObjectAttributes,
   &MWBDriverRegistryPath,
   OBJ_KERNEL_HANDLE,
   NULL,
   NULL);

status = ZwOpenKey(&handle, KEY_SET_VALUE, &ObjectAttributes);
if (status == STATUS_SUCCESS) {//handle opened
status = ZwQueryValueKey(handle,
     &DeviceListValueName,
     KeyValueFullInformation,
     ValueInfo,
     sizeof(KEY_VALUE_FULL_INFORMATION),
     &ValueSize);
if ( (status == STATUS_BUFFER_OVERFLOW) || (status == STATUS_BUFFER_TOO_SMALL) ) {
ExFreePool(ValueInfo);//>>>freeing local mem>>>normal
ValueInfo = (PKEY_VALUE_FULL_INFORMATION)ExAllocatePool(PagedPool, ValueSize);//<<<mem allocation for local use<<<
if(!ValueInfo){
ZwClose(handle);
return STATUS_INSUFFICIENT_RESOURCES;
}
status = ZwQueryValueKey(handle,
&DeviceListValueName,
KeyValueFullInformation,
ValueInfo,
sizeof(KEY_VALUE_FULL_INFORMATION),
&ValueSize);
if(status == STATUS_SUCCESS){
PMWB_DEVICE_LIST CurrentList;
LONG CurrentOffset;
//---
ValueSize = ValueInfo->DataLength - sizeof(CHAR);
LoadedBuffer = (PCHAR)ExAllocatePool(NonPagedPool, ValueSize);//<<<mem allocation for global use<<<buffer for loaded uids
RtlCopyMemory(LoadedBuffer, (ValueInfo + ValueInfo->DataOffset), ValueSize);//copying strings array
ExFreePool(ValueInfo);//>>>freeing local mem>>>normal
//---global counters---
DeviceCount = 0;
LoadedDeviceCount = 0;
ConnectedDeviceCount = 0;
//---
CurrentList = &DeviceList;
CurrentOffset = 0;
InnerCounter = 0;
while(CurrentOffset < ValueSize){
if(InnerCounter == CurrentList->ListCapacity){
InterlockedCompareExchangePointer(CurrentList->NextBlock, (ExAllocatePool(NonPagedPool, sizeof(MWB_DEVICE_LIST))), NULL);//<<<mem allocation for global use<<<
CurrentList = CurrentList->NextBlock;
CurrentList->ListCapacity = 100;//crush may be
CurrentList->NextBlock = NULL;
InnerCounter = 0;
}
CurrentList->PermitList[InnerCounter].DeviceConnected = FALSE;
CurrentList->PermitList[InnerCounter].DevicePermission = MWBPermitAlways;
RtlInitAnsiString(&(CurrentList->PermitList[InnerCounter].DeviceUID), (LoadedBuffer + CurrentOffset));
CurrentOffset += CurrentList->PermitList[InnerCounter].DeviceUID.Length + sizeof(CHAR);
DeviceCount++;
InnerCounter++;
LoadedDeviceCount++;
}
DefaultPermission = MWBBlock;//not a first run, block new disks
} else {//error while loading key
LoadedBuffer = NULL;
//---global counters---
DeviceCount = 0;
LoadedDeviceCount = 0;
ConnectedDeviceCount = 0;
//---
ZwClose(handle);
#if DBG
DbgPrint("MWBLoadPermitList: Fail to read key value\n");
#endif
return STATUS_INSUFFICIENT_RESOURCES;
}
} else {//error while opening key
LoadedBuffer = NULL;
//---global counters---
DeviceCount = 0;
LoadedDeviceCount = 0;
ConnectedDeviceCount = 0;
//---
ZwClose(handle);
#if DBG
DbgPrint("MWBLoadPermitList: Fail to check key value\n");
#endif
return STATUS_INSUFFICIENT_RESOURCES;
}
status = ZwClose(handle);
} else {//can't open handle
LoadedBuffer = NULL;
//---global counters---
DeviceCount = 0;
LoadedDeviceCount = 0;
ConnectedDeviceCount = 0;
//---
#if DBG
DbgPrint("MWBLoadPermitList: Fail to open key handle\n");
#endif
return STATUS_INSUFFICIENT_RESOURCES;
}
return status;
}

в WinDBG при этом вижу
MWBLoadPermitList: Fail to open key handle

я что-то делаю не так или так вообще делать нельзя?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 18-12-2008 08:02 » 

хранить точно так же в реестре. правда сам никогда не использовал. исключение только для драйверов которые в реальном режиме стартуют. или это для 95го было...?
раздел
Kernel-Mode Driver Architecture: Windows DDK
Using the Registry in a Driver

не уверен что надо открывать только с KEY_SET_VALUE .
« Последнее редактирование: 18-12-2008 08:06 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #8 : 18-12-2008 08:32 » 

хранить точно так же в реестре. правда сам никогда не использовал. исключение только для драйверов которые в реальном режиме стартуют. или это для 95го было...?
раздел
Kernel-Mode Driver Architecture: Windows DDK
Using the Registry in a Driver

не уверен что надо открывать только с KEY_SET_VALUE .
да думаю насчёт KEY_SET_VALUE это не то, сам когда перебирал не понял откуда взял
более подробно получаю вот что:
MWBLoadPermitList: my key is \Registry\Machine\System\CurrentControlSet\Services\mwblock keyLength is 118
MWBLoadPermitList: Fail to open key handle [status = C000003A]// судя по ntstatus.h это STATUS_OBJECT_PATH_NOT_FOUND
MWBDriverEntry: Fail to load device list
//---
в чём может быть проблема? ключ точно создан, в реестре специально перед перезагрузкой смотрел
выглядит сейчас это так:
Код:
#if DBG
DbgPrint("MWBLoadPermitList: my key is %ws keyLength is %d\n", MWBDriverRegistryPath.Buffer, MWBDriverRegistryPath.Length);
#endif
InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath,
OBJ_KERNEL_HANDLE, NULL, NULL);

status = ZwOpenKey(&handle, KEY_READ, &ObjectAttributes);
if (status != STATUS_SUCCESS){//can't open handle
LoadedBuffer = NULL;
//---global counters---
DeviceCount = 0;
LoadedDeviceCount = 0;
ConnectedDeviceCount = 0;
//---
#if DBG
DbgPrint("MWBLoadPermitList: Fail to open key handle [status = %X]\n", status);
#endif
return STATUS_INSUFFICIENT_RESOURCES;
}
« Последнее редактирование: 18-12-2008 08:40 от elDraco » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 18-12-2008 08:35 » 

GENERIC_ALL - это где вы такое нашли?)хотя вроде есть... попробуйте KEY_ALL_ACCESS
и попробуйте ZwCreateKey()
PS и может быть не обязательно OBJ_KERNEL_HANDLE? это только если не в контексте системной нити...
в вы где вызываете функцию? подозреваю что AddDev...? тогда системная вроде должна быть...
« Последнее редактирование: 18-12-2008 08:39 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #10 : 18-12-2008 08:54 » 

GENERIC_ALL - это где вы такое нашли?)хотя вроде есть... попробуйте KEY_ALL_ACCESS
это я в документации потерялся:) поставил пока KEY_READ, сейчас попробую поиграться с параметрами ещё

и попробуйте ZwCreateKey()
PS и может быть не обязательно OBJ_KERNEL_HANDLE? это только если не в контексте системной нити...
в вы где вызываете функцию? подозреваю что AddDev...? тогда системная вроде должна быть...
нет функция вызывается в DriverEntry

сейчас вот пробовал после установки до перезагрузки вставить флэшку и... тоже улетел:) попробую помониторить
зы: а вообще к чему этот статус относится? не найден путь в реестре? путь пишется именно так?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 18-12-2008 10:04 » 

сами сообразите?
Что, съел?
примеры использования из DDK:
C:\DDK3790.1830\src\input\kbdclass\kbdclass.c
Код:
    NTSTATUS            status;
    HANDLE              hService, hParameters;
    ULONG               tmp;
    OBJECT_ATTRIBUTES   oa;
    InitializeObjectAttributes (&oa,
                                &Globals.RegistryPath,
                                OBJ_CASE_INSENSITIVE,
                                NULL,
                                (PSECURITY_DESCRIPTOR) NULL);

    status = ZwOpenKey (&hService, KEY_ALL_ACCESS, &oa);

    if (NT_SUCCESS (status)) {
        UNICODE_STRING parameters;

        RtlInitUnicodeString(&parameters, L"Parameters");
        InitializeObjectAttributes (&oa,
                                    &parameters,
                                    OBJ_CASE_INSENSITIVE,
                                    hService,
                                    (PSECURITY_DESCRIPTOR) NULL);

        status = ZwOpenKey (&hParameters, KEY_ALL_ACCESS, &oa);
        if (NT_SUCCESS (status)) {
....
            ZwClose (hParameters);
        }

        ZwClose (hService);
    }

Код:
    HANDLE serviceKey, paramsKey;
    UNICODE_STRING UnicodeString;
    OBJECT_ATTRIBUTES attributes;

    RtlInitUnicodeString(&UnicodeString,
                         L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\"
                         L"Control");

    //
    // Open the global hack key and retrieve the gloabl hack table
    //
    InitializeObjectAttributes(&attributes,
                               &UnicodeString,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL
                               );

    Status = ZwOpenKey(&serviceKey,
                       KEY_READ,
                       &attributes
                       );
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #12 : 18-12-2008 10:28 » 

может прозвучать смешно, но похоже дело было в
InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath, OBJ_CASE_INSENSITIVE, NULL, (PSECURITY_DESCRIPTOR) NULL);
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 18-12-2008 11:55 » 

вобще то я намекал на
InitializeObjectAttributes(&ObjectAttributes, &MWBDriverRegistryPath,  OBJ_CASE_INSENSITIVE, NULL,(PSECURITY_DESCRIPTOR) NULL);
вместо OBJ_KERNEL_HANDLE
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #14 : 18-12-2008 11:59 » 

я пробовал OBJ_CASE_INSENSITIVE до этого, но без приведения типа, сейчас думаю что просто невнимательно прочитал вывод дебаг принтов и результат был удовлетворительный
спасибо за помощь, продолжаю отлаживаться:)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 18-12-2008 13:39 » 

тут приведение типа только на варнинги должно было повлиять.
наверное)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #16 : 18-12-2008 20:34 » 

решил почти все проблемы
драйвер загружается, права сохраняются, меняются и восстанавливаются корректно, физическая запись вроде блокируется(дотошно не тестировал ещё)
но как обычно несколько проблем:)
1) управляющее приложение может открыть хэндл, пообщаться вдоволь с драйвером (результаты корректные судя по выводу проги), но при попытке закрыть хэндл получаю в отладчике вот такую бяку:
Access violation - code c0000005 (!!! second chance !!!)
nt!IofCallDriver+0x29:
804e37ee 8b7108          mov     esi,dword ptr [ecx+8]

функция слизана у Солдатова:
Код:
NTSTATUS MWBClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) {
PAGED_CODE();

UNREFERENCED_PARAMETER(DeviceObject);
#if DBG
DbgPrint("MWBClose: Started\n");
#endif

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

#if DBG
DbgPrint("MWBClose: Finished\n");
#endif
return STATUS_SUCCESS;
}// end MWBClose()
даже не могу понять что тут может произойти... я даже не вижу сообщения ни одного из этой функции
2) при попытке изменить файл на "защищённом от записи" диске получил попап в трее об ошибке отложенной записи... и потом винда постоянно пытается повторить запись:) пока предположение, что связано с тем что я возвращаю STATUS_MEDIA_WRITE_PROTECTED, завтра попробую ещё ACCESS_DENIED И может ещё что-нибудь, очень надеюсь что мне не придётся перехватывать более высокоуровневые функции (по сути запись произошла в кэш и я потом видел что запись произошла, хотя физически это не так), надо вернуть что-нибудь такое чтоб винда отменила запись в кэш в придачу иначе будет некрасиво
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 19-12-2008 11:02 » 

Irp->IoStatus.Information = 0 - не надо!
возврашайте ошибку записи)
« Последнее редактирование: 19-12-2008 11:07 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #18 : 19-12-2008 20:49 » 

дело похоже не в Information
вот вывод !analyze -v:
MODULE_NAME: nt

FAULTING_MODULE: 804d7000 nt

DEBUG_FLR_IMAGE_TIMESTAMP:  47d00080

FAULTING_IP:
nt!IofCallDriver+29
804e37ee 8b7108          mov     esi,dword ptr [ecx+8]

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 804e37ee (nt!IofCallDriver+0x00000029)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 00000008
Attempt to read from address 00000008

ERROR_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - <Unable to get error code text>

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  00000008

READ_ADDRESS: unable to get nt!MmSpecialPoolStart
unable to get nt!MmSpecialPoolEnd
unable to get nt!MmPoolCodeStart
unable to get nt!MmPoolCodeEnd
 00000008

FOLLOWUP_IP:
nt!IofCallDriver+29
804e37ee 8b7108          mov     esi,dword ptr [ecx+8]

BUGCHECK_STR:  ACCESS_VIOLATION

DEFAULT_BUCKET_ID:  WRONG_SYMBOLS

LAST_CONTROL_TRANSFER:  from 804e37f7 to 804e37ee

STACK_TEXT: 
WARNING: Stack unwind information not available. Following frames may be wrong.
f9648c60 804e37f7 81b88030 819623a8 819623a8 nt!IofCallDriver+0x29
f9648ca4 80567697 81a6bbc0 81b88030 0012019f nt!IofCallDriver+0x32
f9648cd4 8056783f 81a6bbc0 00000001 81bb8730 nt!RtlAddAtomToAtomTable+0x3f3
f9648cfc 805678b0 e190fe90 819fb308 000007c4 nt!RtlAddAtomToAtomTable+0x59b
f9648d44 805678fa 000007c4 00000001 00000000 nt!RtlAddAtomToAtomTable+0x60c
f9648d58 804de7ec 000007c4 0012ff58 7c90e4f4 nt!NtClose+0x1d
f9648e08 7c91003d 00143fe8 00140178 00145b94 nt!ZwYieldExecution+0xb78
f9648ecc 7c911432 00000483 7c97b120 7c911440 ntdll!RtlFreeHeap+0x647
f9648f04 7c911440 00140000 7c9113d2 0012f624 ntdll!RtlpFreeDebugInfo+0x5c
f9648f2c 7c91003d 00144bf4 00144be0 00000000 ntdll!RtlpFreeDebugInfo+0x6a
f9648fec 00000000 00000000 00000000 00000000 ntdll!RtlFreeHeap+0x647


STACK_COMMAND:  kb

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  nt!IofCallDriver+29

FOLLOWUP_NAME:  MachineOwner

IMAGE_NAME:  ntoskrnl.exe

BUCKET_ID:  WRONG_SYMBOLS

Followup: MachineOwner

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

дело в том что любая запись на носитель виндой кэшируется, попробую проверить ещё какие IOCTL ходят во время попытки записи и попутный вопрос, я видел что в DEVICE_OBJECT есть поле Characteristics а одно из его значений FILE_READ_ONLY_DEVICE, так вот что будет если я буду динамически выставлять и снимать эту характеристику в своём FDO?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 19-12-2008 22:06 » 

проверьте - всегда ли он падает, или только с случае если в работе запрещал какие то IRP?
READ_ONLY - это надо посмотреть чnо обозначает, но больше похоже на реакцию на ReadFile...
больше похоже на запорченную память
смущает вызов RtlpFreeDebugInfo в стеке вызовов... правда не знаю что за функция... и стек может быть выведен некорректно...
переполнение стека проверьте - в кернеле он помоему 4кб всего. ВЕЗДЕ  вставляйте проверку NTSTATUS() вызываемых функций... а то часто люди ленятся...
проверьте все ли функции могут быть вызваны и на используемых IRQL. вставьте проверку на всякий случай, где не уверены.

а теперь главная жо**...
        UNICODE_STRING parameters;
        RtlInitUnicodeString(&parameters, L"Parameters");
а кто размещает буфер для строки: parameters.Buffer??!? про RtlInitUnicodeString - это не сказано!?....
завтра полезу в примеры DDK...

ЗЫ посмотрел. ну да... забыл совсем)
проверьте на всякий случай выделение памяти под CurrentList->PermitList[InnerCounter].DeviceUID
в строке:
   RtlInitAnsiString(&(CurrentList->PermitList[InnerCounter].DeviceUID), (LoadedBuffer + CurrentOffset));
второй параметр - это верно? должен быть указатель на буфер со строкой... после этого CurrentList не живет без LoadedBuffer?
ЕСЛИ Я ПРАВИЛЬНО ПОНЯЛ (судя по примерам DDK):
  RtlInitUnicodeString/RtlInitAnsiString - память для буфера не выделют! однако если в качестве инициализации используется константное выражение... то видимо они просто подставляют его указатель?
Код:
    UNICODE_STRING      ntDeviceName;
    RtlInitUnicodeString( &ntDeviceName, NTDEVICE_NAME_STRING );
В случае, если сначала происходит инициализация константным выражением, а потом оно изменяется... то память выделяется ОБЯЗАТЕЛЬНО!
(кусок примера)
Код:
    UNICODE_STRING          fullPortName;
    .....
    fullPortName.MaximumLength = 0;
    RtlInitUnicodeString(&fullPortName, NULL);

    fullPortName.MaximumLength = sizeof(L"\\Device\\")
                                + basePortName.Length
                                + sizeof (UNICODE_NULL);

    fullPortName.Buffer = ExAllocatePool(PagedPool,
                                         fullPortName.MaximumLength);
    if (!fullPortName.Buffer) {
        status = STATUS_UNSUCCESSFUL;
        goto KeyboardClassInitializeExit;
    }
    RtlZeroMemory(fullPortName.Buffer, fullPortName.MaximumLength);
    RtlAppendUnicodeToString(&fullPortName, L"\\Device\\");
    RtlAppendUnicodeToString(&fullPortName, basePortName.Buffer);
    RtlAppendUnicodeToString(&fullPortName, L"0");

......................

    if (fullPortName.MaximumLength != 0){
        ExFreePool (fullPortName.Buffer);
    }
полез у себя проверять...)))
PPS не... я просто зайка) у меня все правильно)))
« Последнее редактирование: 20-12-2008 10:58 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
elDraco
Гость
« Ответ #20 : 20-12-2008 18:45 » 

таки свершилось:) отладил вроде:)
1) по висюку: что-то я действительно видимо затирал, но не из-за выделенной мной памяти, при создании управляющего FDO потерял 2 важных действия
ControlDeviceObject->Flags |= DO_BUFFERED_IO;//скорее всего память портилась из-за отсутствия именно этого флага
ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;//ну это просто косяк, особого влияния на падения он не оказывал
не знаю необходимо ли обрабатывать IRP_MJ_CLEANUP, но про него я тоже забыл
2) запись смог заблокировать полностью, но только до первого разрешения записи (то есть, если устройство стартануло в заблокированном состоянии, то запись блокируется полностью, а если сделать разрешить запись потом заблокировать, то начинает опять ругаться кэш) сделано было путём обработки IOCTL_DISK_IS_WRITEABLE, если нужно блокировать запись, то возвращаю тут STATUS_MEDIA_WRITE_PROTECTED иначе просто шлю дальше по стеку
с этим я ещё поработаю и протестирую по полной

Ochkarik, огромное спасибо за помощь и терпение:) надеюсь мои грабли помогут ещё кому-нить избежать лишних шишек:)

зы: руководство по управляемым фильтрам от мелкософта http://support.microsoft.com/kb/262305, я сделал интуитивно практически то же самое, но чуть проще (без инстанс каунтера просто создаю управляющий FDO в DriverEntry и удаляю в DriverUnload)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 20-12-2008 22:12 » 

и вам спасибо за интересный опыт)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines