Как win32k общается с драйвером дисплея

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 12 янв 2010.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Пытаясь разобраться в механизмах общения win32k.sys с драйвером дисплая, выбрал в качестве "подопытной" функции NtUserBitBlt. Дизассемблю-дизассемблю - ничего не проясняется. Как понимаю взаимодействие между графической подсистемой Windows и драйвером дисплая должно быть очень "интимным" для достижения максимальной производетелности.

    Может у кого-нибудь есть информация как это работает?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Чисто случайно только что запостил в своем блоге http://the-gr8.cih.ms/2010/01/blog-post_555.html
    В догонку к посту в блоге: может быть ты имел в виду NtGdiBitBlt? Она в конце концов уходит в EngCopyBits; при копировании на поверхность экрана - в DrvCopyBits.
     
  3. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Кусок NtGdiBitBlt:
    Код (Text):
    1.             if ( *((_BYTE *)hDCDest + 73) & 4 )
    2.               copyBits = *(int (__stdcall **)(_SURFOBJ *, _SURFOBJ *, int, _XLATEOBJ *, int, int))(v33 + 1508);
    3.             else
    4.               copyBits = EngCopyBits;
    5.             v35 = copyBits(
    6.                     (_SURFOBJ *)(hDCDest + 4),
    7.                     (_SURFOBJ *)(v21 + 16),
    8.                     Width_Clip,
    9.                     (_XLATEOBJ *)Xlate,
    10.                     (int)&RectObj,
    11.                     (int)&PointObj);
    Соответственно If'ом выбирается указатель - при копировании во временную поверхность используется EngCopyBits, которая просто копирует попиксельно из ОЗУ в ОЗУ.
    А при копировании на поверхность дисплея выбирается каллбек DrvCopyBits из драйвера дисплея и он копирует уже на собственно экран.
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Great
    Спасибо, намнго понятнее. А стуктуры которые содержат колбеки типа EngCopyBits хоть более менее документированны? Можно ли дбратся до колбеков более-менее универсальным способом?
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    EngCopyBits не каллбек, а функция win32k.sys.
    Она документирована в MSDN вместе со структурами SURFOBJ, XLATOBJ и пр. Она используется в драйверах дисплея.
    А DrvCopyBits - каллбек, да. Имеет точно такой же прототип, как можно наблюдать из куска листинга hexrays, приведенного мною выше.

    Как получить адрес DrvCopyBits: http://www.wasm.ru/forum/viewtopic.php?id=30224 там описана технология вывода на экран из ядра, используемая в разрабатываемом мною отладчике NGdbg. Там есть и поиск самой DrvCopyBits и хендла первичной поверхности.

    Чтобы создать поверхность (для копирования с/на экран) нужно вызвать EngCreateBitmap для создания битмапа и EngLockSurface для залочивания его поверхности. Последняя заполнит SURFOBJ. Они так же документированы в MSDN.

    Замечу, что при копировани _С_ экрана требуется EngCopyBits, видимо у нее есть кеш в оперативной памяти, где содержатся пиксели. DrvCopyBits нужна только при копировании _на_ поверхность экрана (это и видно по приведенному выше куску - проверка только на destination surface).
     
  6. katrus

    katrus New Member

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

    У меня возникла более простая идея как найти DrvCоpyВits. Можно написать драйвер загружаемый перед win32k.sys который ждет загрузки драйвера дисплея. При появлении драйвера дисплея подменяем в его PE адрес функции Entery Point (которая в случае драйвера дисплая является ничем иным как DrvЕnаblеDrivеr) на свою функцию. В таком своего-роде патче получаем DrvCоpyВits
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Да, но для этого нужна перезагрузка. Мой же вариант можно замутить и на работающей системе.
     
  8. katrus

    katrus New Member

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

    А как найти имя видео драйвера? Т.е., скажем, как определить, что в текущей системе видео драйвер это vboxdisp.dll ?
     
  9. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    \Device\Video0 ---> \Driver\VBoxVideo ?
     
  10. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Извиняюсь - неправильно сформулировал вопрос. Как найти имя драйвер дисплея, т.е., файла погружаемого из win32k.sys. В случае VBox это vboxdisp.dll. Еще очень нужно, чтоб имя этого драйвера было известно до того как win32k.sys загружет его.

    Хочу перехватить DrvEnableDriver...
     
  11. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Кстати, смотрю исходники Great. Там есть строчка
    Код (Text):
    1. HANDLE hDrv = EngLoadImage (L"vid_copy.dll");
    Что такое "vid_copy.dll"? Просто физическая копия файла драйвера дисплея?
     
  12. T800

    T800 Member

    Публикаций:
    0
    Регистрация:
    7 дек 2006
    Сообщения:
    293
    Адрес:
    Moscow
    katrus
    Я тоже вчера посмотрел. Хотя даже больше - настругал свой дров, в который положил всё, что касается только "перехвата" виндового видео (всё это дело даже скомпилилось и запускается).

    vid_copy.dll - это копия текущего установленого драйвера.
    Т.е. прога, которая загружает дров, должна:
    1) вот по этому алгосу http://wasm.ru/forum/viewtopic.php?id=30143 найти файлик этого драйвера (например system32\nv4_disp.dll)
    2) сделать копию этого дрова, обозвав его как vid_copy.dll (в system32)
    3) прописать в реестре \\Registry\\Machine\\Software\\NGdb параметр DisplayDriver (например nv4_disp)

    В итоге в логе получил:
    Got shared 8xxxxxxx Sign DEADBEEF Surf 0

    Теперь только осталось определить Surf через NewDrvCopyBits.