HDC в ядре.

Тема в разделе "WASM.NT.KERNEL", создана пользователем assorted, 2 июн 2011.

  1. assorted

    assorted New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    227
    Имеется колбэк NewNtGdiBitBlt(... HDC hDCSrc...). Пытаюсь передать данные заданной области HDC в юзермод. Проблема в том что документированные функции GDI используют функции с SURFOBJ аргументми. Как получить их из HDC не представляю.

    Есть мысль использовать юзермодный подход.
    NtGdiCreateCompatibleBitmap
    NtGdiCreateDIBSection
    NtGdiSelectBitmap
    NtGdiGetDIBitsInternal

    но уж больно сложно получается. Искать обявления недокументированные + NtGdiGetDIBitsInternal буфер возможно захочет исключительно юзермодный. Да и по задумке эти сервисы не вызываются из ядра и как себя поведут пока не ясно.

    Еще есть мысль использовать HDC юзермодный. Сделать ему ObReferenceObjectByHandle и вызывать TrueNtGdiBitBlt, а DIBits получать в юземоде, но тогда не понятно как реализовать очередь и обеспечить "Compatible" у обоих HDC.
     
  2. assorted

    assorted New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    227
    Проложая свою тему. Решил в своем обработчике NewNtGdiBitBlt делать прыжок в юзермод через KeUserModeCallback (APC не подходит, оно, я так понимаю, сразу же меня в контекст нужного процесса не переключит), и там уже с этим HDC работать. Возникли несколько вопросов касаемо KeUserModeCallback.

    1) Пишут "её можно вызывать если драйвер не был ранее приаттачен ни к одному процессу"
    тоесть вызывать перед ней KeAttachProcess к своему процессу не получится?

    2) Пишут "Для вызова кода режима пользователя нам необходимо выделить память где-нибудь пониже KernelCallbackTable (следует использовать флаг MEM_TOP_DOWN в ZwAllocateVirtualMemory)"
    Есть какая то разница повыше или пониже? Мой обработчик по адресу 401ХХХh

    3) пробовал подменить в адрес таблице на адрес свого юзермод обработчика и вызвать KeUserModeCallback(0x53...)

    В результате, что бы я не делал KeUserModeCallback возвращает c0000005. Но пример с MEM_TOP_DOWN рабоатет отлично.
     
  3. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    1. Нет смысла. Может потребоваться переключение между сессиями(MmAttachSession()).
    2. Адрес буфера значения не имеет(в пределах пользовательского сегмента кода). Его нужно заблочить(MmSecureVM()), запретить саспенд апк(KeEnterCriticalRegion()) и защитить код SEH. Иначе вы создадите уязвимость в системе. Пользовательский T-фрейм должен быть сформирован.
    3. Перед вызовом теневого колбека необходимо разрешить доставку саспенд апк. Пользовательский хэндлер должен быть зареган в apfnDispatch[] и заключён в сех. После возврата из колбека необходимо вновь запретить доставку саспенд апк. На время вызова колбека IRQL нельзя повышать(пассив).
     
  4. assorted

    assorted New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    227
    Удалось выяснить в чем проблема. Мой код с KeUserModeCallback отлично работает например из диспетчера IO. Но если его использовать из NewNtGdiBitBlt (драйвер уже приаттачен к какому-то процессу) то после вызова KeAttachProcess к своему приложению, KeUserModeCallback возвращает c0000005. Попробовал сделать так

    NewNtGdiBitBlt{

    KeDetachProcess()
    KeAttachProcess(мой процесс)
    KeUserModeCallback()
    KeDetachProcess()
    KeAttachProcess(тот процесс что вызывал NewNtGdiBitBlt)

    }

    ничего не поменялось.
     
  5. klzlk

    klzlk New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2011
    Сообщения:
    449
    assorted
    Ну давайте гадать. Вызывается ли хэндлер в apfnDispatch[] и если вызывается, то что возвращает ?
     
  6. assorted

    assorted New Member

    Публикаций:
    0
    Регистрация:
    7 авг 2006
    Сообщения:
    227
    Посмотреть не успел, скорее всего не вызывается. Сделал решение простое как три копейки - SetEvent в юзермод и с помощью KeWaitForSingleObject жду завершения операции через IO. Тема не актуальна. Спасибо klzlk.