Защита драйвера режима ядра (kernel аналог VirtualProtect и т.п.)

Тема в разделе "WASM.BEGINNERS", создана пользователем Platon, 13 апр 2009.

  1. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    Здавствуйте.
    Мне задали такую задачку для курсовой - блокирование нежелательных процессов.
    Вобщем обдумав ее, я решил попробывать написать драйвер (заодно прокачаться в этой области, все-же интересно :)) Да и из user mode такую штуку только если с помощью WMI сделать удастся, что имхо ненадежно.
    Все бы ничего (почитал документацию, полазил здесь по форуму, поэкспериментировал - вроде бы получается), но тут возникла ситуация с защитой управления драйвером и "черным списком". Т.е. по сути нужно "запаролить" все эти действия. Ничего умного в голову не пришло кроме как зашифровать код в драйвере отвечающий за снятие колбэка (PsRemoveLoadImageNotifyRoutine) и т.п. действий, а при посылке сообщения драйверу от управляющй программы, слать заодно пароль. В драйвере из пароля вычислять хеш и сравнивать его с оригинальным. В случае совпадения - кусок кода дешифруется этим паролем и выполняется. Раньше я такое проделывал из user mode, а с ядерным режимом сразу же возникли вопросы:
    1) как снять дамп участка кода ? (возможно тупо просканить кусок памяти и вывести DbgPrint)
    2) есть-ли и какой аналог функции VirtualProtect ?
    Ну вообще конечно можно было бы и не геммороится с этим шифрованием, просто интересно - получится-ли такое.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Зачем это делать, разве есть какието подводные камни при ручном удалении калбаки из списка в ядре ?
     
  3. k3internal

    k3internal New Member

    Публикаций:
    0
    Регистрация:
    11 янв 2007
    Сообщения:
    607
    Platon
    как вариант создать подобие проактивки. Не позволять запускать непроверенные драйвера, не давать доступа к объекту физикалмемори, не давать открывать легальные дровы и ехеки имеющие отношение к режиму ядра для записи в них. Больше я хз чего тут предложить. Но остаются ещё и сплойты. Тут уже сам думай. А война на уровне ядра бессмыслена.
     
  4. k3internal

    k3internal New Member

    Публикаций:
    0
    Регистрация:
    11 янв 2007
    Сообщения:
    607
    Да, и ещё не забудь похучить из ядра известные функции, которые так бдят промышленные проактивки.
     
  5. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    Clerk
    Дело не в этом, это нужно чтобы снятие легальным способом (посылкой управляющего кода) было авторизировано. А ручное удаление это да, тут надо думать. Хотя снять из юзермода вроде нельзя, а из ядра - запуск-то не санкционированых процессов запрещен, инструменты не запустишь, соответственно и снять не получится, наверное :) Хотя из этого следует что и возится с шифрованием не стоит, достаточно просто сравнивать хеш пароля - опять таки снять проверку не получится из-за невозможности юзать нужные инструменты. :)
    k3internal
    Спасибо, попробую.

    ЗЫ
    Тему думаю стоит закрыть, действительно война на уровне ядра бессмыслена :)
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Platon
    Можно снять из юзермода нотификатор. Ядерная память открыта для модификации из контекста csrss. Достаточно исполнить в его контексте юзермодный код.
     
  7. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    не дать копировать матерых хендлов..
    сталобыть нельзя туда никого пускать
     
  8. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    Clerk
    Возьму на заметку, пасиба.
    Freeman
    Каких хендлов?:)
    Думаю что это можно переложить на плечи антивиря. Если понадобится без него работать, попробую порешать, можт чего получится.
     
  9. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    Решил пойти другим путем и не юзать колбэк. Попробывал перехватывать ZwCreateProcessEx и там из секции дергать полное имя образа. Все получилось кроме того что после выдергивания пути (конкретнее - после копирования буквы винта функцией RtlCopyUnicodeString) оригинальная ZwCreateProcessEx стала возвращать STATUS_INVALID_PARAMETERS, что очень странно. Если букву не копировать то нормально все, чудеса какие-то :)
    Код (Text):
    1. NTSTATUS NtCreateProcessExHook(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ParentProcess, ULONG Flags, HANDLE SectionHandle, HANDLE DebugPort, HANDLE ExceptionPort, BOOLEAN InJob) {
    2.     PSECTION        Section;
    3.     PSEGMENT        Segment;
    4.     PCONTROL_AREA   ControlArea;
    5.     PFILE_OBJECT    FileObject;
    6.     UNICODE_STRING  DeviceLetter;
    7.    
    8.     __try {
    9.         if (ObReferenceObjectByHandle(SectionHandle, SECTION_QUERY, *MmSectionObjectType, UserMode, &Section, NULL) == STATUS_SUCCESS) {
    10.             Segment = Section->Segment;
    11.             if (MmIsAddressValid(Segment)) {
    12.                 ControlArea = Segment->ControlArea;
    13.                 if (MmIsAddressValid(ControlArea)) {
    14.                     if (ControlArea->Segment == Segment) {
    15.                         FileObject = ControlArea->FilePointer;
    16.                         if (MmIsAddressValid(FileObject)) {
    17.                             if (IoVolumeDeviceToDosName(FileObject->DeviceObject, &DeviceLetter) == STATUS_SUCCESS) {
    18.                                 RtlCopyUnicodeString(&SectionSource, &DeviceLetter); // Из-за этого облом :(
    19.                                 ExFreePool(DeviceLetter.Buffer);
    20.                             }
    21.                             SectionSource.Length = 0;
    22.                             RtlAppendUnicodeStringToString(&SectionSource, &FileObject->FileName);
    23.                             DbgPrint("NtCreateProcessExHook: %S", SectionSource.Buffer);
    24.                         }
    25.                     }
    26.                 }
    27.             }
    28.             ObDereferenceObject(Section);
    29.         }
    30.     } __except(EXCEPTION_EXECUTE_HANDLER) {
    31.         DbgPrint("NtCreateProcessExHook: raise exception!");
    32.     }
    33.     return NtCreateProcessExTrue(ProcessHandle, DesiredAccess, ObjectAttributes, ParentProcess, Flags, SectionHandle, DebugPort, ExceptionPort, InJob);
    34. }
    Где я накосячил?
     
  10. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    на
    Код (Text):
    1. SectionSource.Length = 0;
    не обращайте внимания, забыл убрать когда постил, это нужно было после комментирования RtlCopyUnicodeString
     
  11. Platon

    Platon New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    6
    Что странно, замена RtlCopyUnicodeString на копирование с помощью RtlMoveMemory работает
    Код (Text):
    1. RtlMoveMemory(SectionSource.Buffer, DeviceLetter.Buffer, DeviceLetter.Length);
    2. SectionSource.Length = DeviceLetter.Length;
    ЗЫ
    А как здесь свои сообщения отредактировать? В упор нужной кнопочки не вижу :)