Пути к файлам в нулевом кольце

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

  1. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Пардон, за столь долгое молчание.
    Возникают новые вопросы.
    1.
    Ведь если я вызову ZwCreateFile, то кроме того что я получу хендл я еще и, возможно, создам файл(или что-то еще...)!
    Но если мне придется его заблокировать, то придется удалять, а это уже не есть гуд.

    2.
    Побродив немного по Инету (и по форуму), попалось мнение, что ZwQueryObject виснет на именованных пайпах. Как быть?
     
  2. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Попробовал вот такой код (из-под перехваченой NtCreateFile):
    Код (Text):
    1.    
    2. POBJECT_TYPE_INFORMATION ObjectTypeInfo;
    3. ULONG uSize;
    4. ...
    5. ZwQueryObject( FileHandle, ObjectTypeInformation, NULL, 0, &uSize);
    6. ObjectTypeInfo = (POBJECT_TYPE_INFORMATION) ExAllocatePool(NonPagedPool, uSize);
    7. if(ZwQueryObject( FileHandle, ObjectTypeInformation, ObjectTypeInfo, uSize, &uSize) == 0)
    8. {
    9.  
    10. }
    11. ExFreePool(ObjectTypeInfo);
    Результат - через некоторое время (достаточно быстро, несколько секунд) = БСОД.
    Где напорол?
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    эээ с какой1 радости
     
  4. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Пардон, не выспался я тогда, фигню отмочил....

    Но с ZwQueryObject так и не разобрался....в чем там трабла...
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Да это действительно так. Как быть.. хз. как вариант разбирать ручками структуры
     
  6. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    А можно подробнее?
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    RetroCode
    OBJECT_HEADER* hdr = OBJECT_TO_OBJECT_HEADER(Object);
    hdr->Type
     
  8. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Извини, но все равно не догоняю.
    Это кто такие OBJECT_HEADER, OBJECT_TO_OBJECT_HEADER & Object?
    Не мог бы ты немного кодом показать что к чему....
     
  9. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Поиск немного прояснил ситуацию.
    Попробую.
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    структура - заголовок объекта в менеджере объектов
    макрос, вычитающий из указателя на объект размер заголовка
    твой указатель на объект, тип которого нужно получить.
     
  11. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Ок, спасибо, попробую. Интересно что из всего этого выйдет...
     
  12. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Таак.
    Вот результат моих страданий. Вроде бы работает. Хотелось бы услышать критику/рекомендации и т.п.

    Код (Text):
    1.     NTSTATUS Result;
    2.     ULONG uSize;
    3.     PWCHAR buffer = NULL;
    4.     ULONG len=512*4;
    5.     UNICODE_STRING uniFileName;
    6.     OBJECT_ATTRIBUTES oa;
    7.     HANDLE h;
    8.     PWCHAR DirToProcess=NULL;
    9.     PWCHAR Answer=NULL;
    10.     wchar_t *Res=NULL;
    11.     ULONG i=0;
    12. ....
    13. .....
    14. ......
    15.         buffer = (wchar_t *)ExAllocatePool(PagedPool, len);
    16.         if (!buffer) {
    17.             DPRINT("Not enough memory to continue");
    18.             goto done1;
    19.         }
    20.         RtlZeroMemory(buffer, len);
    21.  
    22.         DirToProcess = (wchar_t *)ExAllocatePool(PagedPool, len);
    23.         if (!DirToProcess) {
    24.             DPRINT("Not enough memory to continue");
    25.             ExFreePool (buffer);
    26.             goto done1;
    27.         }
    28.         RtlZeroMemory(DirToProcess, len);
    29.  
    30.         if(ObjectAttributes->RootDirectory!=0) {
    31.             DPRINT("CreateFile. Processing root directory for: %ws\n", ObjectAttributes->ObjectName->Buffer);
    32.  
    33.             if (ZwQueryObject(ObjectAttributes->RootDirectory,ObjectNameInformation,buffer,len,&len)==0) {
    34.                 DPRINT("CreateFile. Processed root directory: %ws\n", buffer);
    35.                 Res=wcsstr(buffer, L"\\Device\\");
    36.                 if (Res!=NULL) {
    37.                     wcscat(DirToProcess, Res);
    38.                     wcscat(DirToProcess, L"\\");
    39.                     wcscat(DirToProcess, ObjectAttributes->ObjectName->Buffer);
    40.                     DPRINT("CreateFile. Updated root directory: %ws", DirToProcess);
    41.                 }
    42.  
    43.             }
    44.         }
    45.  
    46.         if (wcslen(DirToProcess)==0) wcscpy(DirToProcess, ObjectAttributes->ObjectName->Buffer);
    47.         DPRINT("CreateFile. Full file-path proccesing: %ws", DirToProcess);
    48.  
    49.         // Now we have to resolve all symbolic links (if any)
    50.         if (wcslen(DirToProcess)>0) {
    51.             Res=wcsstr(DirToProcess, L"\\");
    52.             if (Res!=NULL) {
    53.                 i=Res-DirToProcess;
    54.                 if (i<wcslen(DirToProcess)) {
    55.                     Res=wcsstr(wcsstr(DirToProcess, L"\\")+2, L"\\");
    56.                     if (Res!=NULL) {
    57.                         i=Res-DirToProcess;
    58.                         while (i>0) {
    59.                             RtlZeroMemory(buffer, len);
    60.                             wcsncpy(buffer, DirToProcess, i);
    61.  
    62.                             RtlInitUnicodeString (&uniFileName, buffer);
    63.                             InitializeObjectAttributes(&oa,&uniFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
    64.  
    65.                             Result=ZwOpenSymbolicLinkObject(&h, 0x20001, &oa);
    66.                             if (NT_SUCCESS(Result)) {
    67.                                 DPRINT("CreateFile. Symbolic link is OPENED! Path: %ws\n", buffer);
    68.  
    69.                                 Answer = (wchar_t *)ExAllocatePool(PagedPool, 1024);
    70.                                 if (!Answer) {
    71.                                     DPRINT("Not enough memory to continue");
    72.                                     ExFreePool (DirToProcess);
    73.                                     ExFreePool (buffer);
    74.                                     goto done1;
    75.                                 }
    76.                                 RtlZeroMemory(Answer, 1024);
    77.                                 uniFileName.Buffer=Answer;
    78.                                 uniFileName.Length=1024;
    79.                                 uniFileName.MaximumLength=1024;
    80.  
    81.                                 Result=ZwQuerySymbolicLinkObject(h, &uniFileName, 0);
    82.  
    83.                                 if(NT_SUCCESS(Result)) {
    84.                                     DPRINT("CreateFile. Symbolic link is RESOLVED. Symbolic link: %ws; Result: %ws", buffer, uniFileName.Buffer);
    85.                                     RtlZeroMemory(buffer, len);
    86.                                     wcscpy(buffer, uniFileName.Buffer);
    87.                                     wcscat(buffer, DirToProcess+i);
    88.                                     i=wcsstr(DirToProcess, L"\\")-DirToProcess;
    89.                                     RtlZeroMemory(DirToProcess, len);
    90.                                     wcscpy(DirToProcess, buffer);
    91.                                     DPRINT("CreateFile. Full Resolved Path: %ws", DirToProcess);
    92.                                 } else {
    93.                                     DPRINT("Can not resolve symbolic link. Can not continue\n");
    94.                                     ExFreePool (Answer);
    95.                                     ExFreePool (DirToProcess);
    96.                                     ExFreePool (buffer);
    97.                                     goto done1;
    98.                                 }
    99.                                 ExFreePool (Answer);
    100.  
    101.                             }
    102.  
    103.                             if (wcslen(DirToProcess)>i+2) {
    104.                                 Res=wcsstr(DirToProcess+i+2, L"\\");
    105.                                 if (Res!=NULL) i=Res-DirToProcess; else i=0;
    106.                             } else {
    107.                                 i=0;
    108.                             }
    109.                         }
    110.                     }
    111.                 }
    112.             }
    113.         }
    114.  
    115.         ExFreePool (buffer);
    116.         // Now we can see. Is it denied file or not...
    117.  
    118.  
    119.  
    120.         // Work is complete
    121.         ExFreePool (DirToProcess);
    Код само собой не оптимален..... :)
    И небольшой комментарий. Честно говоря, не знаю, возможен ли symbolic link на symbolic link, т.е. ссылка на ссылку. Поиски в Инете ничего не дали и поэтому, дабы не рисковать, я этот вариант предусмотрел в этом коде (по крайне мере я на это надеюсь).
    Если код рабочий и кому-нибудь понадобится - дерзайте ;).
     
  13. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Хотя...не такой уж он и рабочий.
    Все было Ок, пока не залез в сетевое окружение со включенным драйвером. Он ничего плохого сразу делать не стал. А вот когда я его отключил - БСОД почти сразу.
    В чем трабла....не понятно пока. Может кто подскажет?
     
  14. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    RetroCode
    приаттач весь бсодогенератор:)
    посмотрим и позапускаем
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну что молчишь то.. давай уж весь вывод !analyze -v =)

    Да, возможен.
    Пример - \??\AUX ссылается на \DosDevices\COM1, который уже ссылается на \Device\Serial0
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    как я понял, это строковые буффера, достаточно занулить первый символ

    ойойой а ты правда думаешь, что UNICODE_STRING.Buffer обязан завершаться нулём? Специально же в нем длина указана, чтобы он мог не завершаться нулем.
    Я для этого функцию писал:
    Код (Text):
    1. WCHAR*
    2. DuplicateUnicodeStringZ(
    3.     PUNICODE_STRING Input
    4.     )
    5. {
    6.     WCHAR* Out;
    7.  
    8.     if( !Input )
    9.         return NULL;
    10.  
    11.     Out = (WCHAR*) ExAllocatePool( NonPagedPool, Input->Length + 2 );
    12.     if( Out )
    13.     {
    14.         memcpy( Out, Input->Buffer, Input->Length );
    15.         Out[ Input->Length/2 ] = 0;
    16.     }
    17.  
    18.     return Out;
    19. }
    Возвращает UNICODEZ строку, которую уже можно сконкатить с буффером.. а потом удалить через ExFreePool()
     
  17. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Все оказалось гораздо печальнее. У меня закрались подозрения что БСОД выскакивает при попытке отключения драйвера (и снятия перехвата) в момент, когда система активно дергает файлы. Решил проверить - закомментил всю смысловую нагрузку, запустил поиск файлов по содержимому и отключил драйвер - БСОД. Легенда подтверждена...

    Возможно как-то не правильно снимаю перехват....скажите, знающие люди, плиз.

    В аттаче весь драйвер

    Точно, забыл про этот момент. Спасибо.

    Перехват реализован через SDT, методом вполне известным....надеюсь на Вашу подсказку, мозг уже отключается...
     
  18. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    Пардон за каламбур, но...
    ...можно ли как-то приостановить остановку драйвера до тех пор, пока не отрабатает перехваченная функция (функции) во всех потоках, где она (они) на тот момент вызвана(-ны)?
    Очевидно, что проблема именно в этом - я жму на остановку драйвера и снятие перехвата, в тот момент когда перехваченная ф-ция еще выполняется...
    Других причин пока не вижу....
    Есть идеи?
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    RetroCode
    IoRemoveLock'и можешь попробовать, но лучше и проще сделать драйвер невыгружаемым.
    так же можешь сам попробовать реализовать самопальные счетчики-семафоры выгрузки. как говорится, флаг в руки.
     
  20. RetroCode

    RetroCode New Member

    Публикаций:
    0
    Регистрация:
    13 сен 2007
    Сообщения:
    25
    А как максимально корректно это сделать?