Подмена NtOpenFile: в чем проблема???

Тема в разделе "WASM.NT.KERNEL", создана пользователем DoZENT, 17 май 2007.

  1. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Привет фсем! Что-то я, наверное, туплю.... Заменяю настоящую функцию NtOpenFile:
    Код (Text):
    1. NTSTATUS NewNtOpenFile (OUT PHANDLE  FileHandle,
    2.                         IN ACCESS_MASK  DesiredAccess,
    3.                         IN POBJECT_ATTRIBUTES  ObjectAttributes,
    4.                         OUT PIO_STATUS_BLOCK  IoStatusBlock,
    5.                         IN ULONG  ShareAccess,
    6.                         IN ULONG  OpenOptions
    7.                         )
    8. {
    9.  
    10.  
    11.  
    12.    
    13.     LPWSTR OpenedFileName;
    14.  
    15.     __try
    16.     {
    17.            
    18.         OpenedFileName = ObjectAttributes->ObjectName->Buffer;
    19.  
    20.  
    21.         if (IsAdded (ObjectsList, OpenedFileName))
    22.         {
    23.             DPRINT ("%S: Access denided", OpenedFileName);
    24.             return STATUS_ACCESS_DENIED;
    25.         }
    26.         else
    27.         {
    28.             DPRINT ("%S: Access OK", OpenedFileName);
    29.             return TrueNtOpenFile (FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,OpenOptions);
    30.         }
    31.        
    32.        
    33.     }
    34.     __except(EXCEPTION_EXECUTE_HANDLER)
    35.     {
    36.         DPRINT("Exception on NewNtOpenFile");
    37.         return STATUS_INVALID_PARAMETER;
    38.     }
    39.  
    40.  
    41. }
    В DbgView выдаются сообщения типа "D:\Games: Access OK" и "C:\BP: Access denided". Но директория все равно видна и не блокируется!!! В чем дело?
     
  2. pushick

    pushick New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2007
    Сообщения:
    95
    DoZENT

    А яснее задачу можно сформулировать?
    Или вообще сформулировать задачу?
     
  3. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Задача: есть некий список директорий и файлов (ObjectsList), реализация неважна. Есть перехват функции NtOpenFile. В ней нужно проверить наличие в списке открываемой директории или файла функцией IsAdded (реализация опять же неважна, т.к. она точно работает правильно). В случае, если в этом списке открываемый файл/директория есть, заблокировать к ней/ему доступ.
     
  4. Slavic

    Slavic New Member

    Публикаций:
    0
    Регистрация:
    11 май 2007
    Сообщения:
    14
    Возможно, директория видна потому, что список файлов и вложенных директорий возвращается функциями FindFirstFileEx, FindNextFile, которые обращаются к NtQueryDirectoryFile. Причем для этого нужен Handle папки, в которой находится скрываемая папка или файл.
    А если директория открывается не функцией NtOpenFile, а функцией NtCreateFile?
     
  5. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Дело еще в том, что абсолютно тот же самый код (просто с другой реализацией IsAdded, что несущественно) месяц назад работал отлично!
    А вот про это я забыл. Спасибо, попробую.
     
  6. nitrotoluol

    nitrotoluol New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2006
    Сообщения:
    848
    IsAdded (ObjectsList, OpenedFileName))
    функцию выкладывай

    и еще давай , как хук ставишь


    А то дал код типа
    int somefunc(int somepar1, int somepar2)
    и спрашиваешь почему функция не работает?

    Телепатов нет
     
  7. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    В общем дело действительно в функциях, которые отвечают за работу односвязного списка. Вот исходный текст, что в нем неправильно? Общий смысл такой: драйверу приходит структура из ринг3, где одно из полей - путь к директории, которую надо заблокировать.

    Типы:

    Код (Text):
    1. typedef struct _blockedObjectData
    2. {
    3.  
    4.     LPWSTR DirPath;
    5.         ....
    6.  
    7.    
    8.  
    9. }blockedObjectData, *PblockedObjectData;
    10.  
    11.  
    12. typedef struct _ObjectList
    13. {
    14.     PVOID NextItem;
    15.     LPWSTR FileName;
    16.  
    17. } TObjectList, *PObjectList;
    18.  
    19.  
    20. PObjectList ObjectsList = NULL;
    21.  
    22.  
    23. typedef struct _DRIVERDATA
    24. {
    25.  
    26.     int driverAction;
    27.     blockedObjectData bObjectData;
    28.  
    29.  
    30. } DRIVERDATA, *PDRIVERDATA;
    Сам код:

    Код (Text):
    1. NTSTATUS DriverDispatcher( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    2. ...
    3. pisl = IoGetCurrentIrpStackLocation(Irp);
    4. if ( pisl->MajorFunction == IRP_MJ_WRITE) {
    5. ...
    6.  
    7.         LPWSTR AddingString = NULL;
    8.  
    9.         Data = Irp->UserBuffer;
    10.  
    11.         __try
    12.         {
    13.        
    14.        
    15.             switch(Data->driverAction)
    16.             {
    17.             case 1:
    18.  
    19.  
    20.                 AddingString = Data->bObjectData.DirPath;
    21.  
    22.                 DPRINT ("AddingString = %S", AddingString);
    23.  
    24.                 if (!IsAdded (ObjectsList, AddingString))
    25.                 {
    26.                     DPRINT ("Item %S is not added\n",AddingString);                
    27.  
    28.                     AddItem (&ObjectsList, AddingString);
    29.                     //AddItem(&ObjectsList, L"\\??\\C:\\BP\\"); //ВОТ ТАК РАБОТАЕТ!
    30.                 }
    31.                 else
    32.                     DPRINT ("Item %S is already added\n",Data->bObjectData.DirPath);
    33.                        
    34.                 break;
    Функции для работы с односвязным списком:

    Код (Text):
    1. BOOLEAN IsAdded(PObjectList List, LPWSTR CheckedFileName)
    2. {
    3.  
    4.  
    5.     PObjectList Item = List;
    6.     while (Item)
    7.     {
    8.         DPRINT ("In List: %S", Item->FileName);
    9.         if (wcsncmp (Item->FileName,CheckedFileName, wcslen(CheckedFileName)) == 0) return TRUE;       
    10.         Item = Item->NextItem;
    11.     }
    12.     return FALSE;  
    13.  
    14.  
    15. }
    16.  
    17. void AddItem(PObjectList *List, LPWSTR AddingFileName)
    18. {
    19.  
    20.     PObjectList wNewItem;
    21.     wNewItem = ExAllocatePool(NonPagedPool, sizeof(TObjectList));
    22.     wNewItem->NextItem = *List;
    23.     *List = wNewItem;  
    24.     wNewItem->FileName = AddingFileName;
    25.  
    26.     DPRINT ("Adding %S", wNewItem->FileName);
    27.  
    28.     return;
    29.  
    30. }
    В итоге валятся одни исключения((
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    думаю, вот тут ошибка:wNewItem->FileName = AddingFileName;
    Когда ты непосредственно пишешь L"\\??\\C:\\BP\\" - выделяется память, доступная для чтения из драйвера при проверке списка. А когда сохраняешь адрес строки (AddingString) и потом пытаешься прочитать эту строку, адрес AddingString оказывается недоступен для чтения и приводит к исключению.

    Выделяй память под строку wNewItem = ExAllocatePool(NonPagedPool, 4 + 512); где 512 - место под строку, и в это место копируй имя директории. Эта память не будет приводить к исключениям.

    Код (Text):
    1. typedef struct _ObjectList
    2. {
    3.     PVOID NextItem;
    4.     WCHAR FileName[256];
    5.  
    6. } TObjectList, *PObjectList;
    Естественно, надо будет
    wNewItem->FileName = AddingFileName;
    заменить на
    wcscpy (wNewItem->FileName, AddingFileName);
     
  9. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Спасибо большое, все работает! Я и раньше делал wcscpy (wNewItem->FileName, AddingFileName);, но забывал выделить память! Только, наверное, wNewItem->FileName = ExAllocatePool(NonPagedPool, 4 + wcslen(AddingFileName)); ?
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    смотря в каком варианте. Если для структуры cresta, то он всё верно написал.
     
  11. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Можно и так выделять. Просто код будет дольше работать (лишний вызов wcslen).
    И в функции IsAdded можно заменить wcsncmp на wcscmp, опять же это избавляет от необходимости вызова wcslen при проверке списка.

    P.S.
    Хотя если количество элементов списка велико, то выделение памяти ровно под длину строки позволит сэкономить некоторое количество nonpaged-памяти. Есть ли в этом смысл - не знаю...

    P.P.S.
    А чего это ты не проверяешь, какое значение вернула ExAllocatePool? Количество памяти в кернеле не так велико, как в юзере, тем более памяти nonPaged. Вполне можешь и получить ноль (ошибку выделения) в результате вызова ExAllocatePool, что неизбежно приведет к исключению.
     
  12. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Так я же выделил уже память под структуру:
    Код (Text):
    1.     PObjectList wNewItem;
    2.     wNewItem = ExAllocatePool(NonPagedPool, sizeof(TObjectList));
    Код (Text):
    1. А чего это ты не проверяешь, какое значение вернула ExAllocatePool?
    Надо будет добавить... Привык, что под ринг3 память под структуры выделяется 100% :)
     
  13. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    угу, но выделять память еще и отдельно под строку не надо.
     
  14. DoZENT

    DoZENT New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2007
    Сообщения:
    50
    Если ее не выделять, то при выполнении строчки wcscpy (wNewItem->FileName, AddingFileName); валится синий экран