Пытаясь разобраться в механизмах общения win32k.sys с драйвером дисплая, выбрал в качестве "подопытной" функции NtUserBitBlt. Дизассемблю-дизассемблю - ничего не проясняется. Как понимаю взаимодействие между графической подсистемой Windows и драйвером дисплая должно быть очень "интимным" для достижения максимальной производетелности. Может у кого-нибудь есть информация как это работает?
Чисто случайно только что запостил в своем блоге http://the-gr8.cih.ms/2010/01/blog-post_555.html В догонку к посту в блоге: может быть ты имел в виду NtGdiBitBlt? Она в конце концов уходит в EngCopyBits; при копировании на поверхность экрана - в DrvCopyBits.
Кусок NtGdiBitBlt: Код (Text): if ( *((_BYTE *)hDCDest + 73) & 4 ) copyBits = *(int (__stdcall **)(_SURFOBJ *, _SURFOBJ *, int, _XLATEOBJ *, int, int))(v33 + 1508); else copyBits = EngCopyBits; v35 = copyBits( (_SURFOBJ *)(hDCDest + 4), (_SURFOBJ *)(v21 + 16), Width_Clip, (_XLATEOBJ *)Xlate, (int)&RectObj, (int)&PointObj); Соответственно If'ом выбирается указатель - при копировании во временную поверхность используется EngCopyBits, которая просто копирует попиксельно из ОЗУ в ОЗУ. А при копировании на поверхность дисплея выбирается каллбек DrvCopyBits из драйвера дисплея и он копирует уже на собственно экран.
Great Спасибо, намнго понятнее. А стуктуры которые содержат колбеки типа EngCopyBits хоть более менее документированны? Можно ли дбратся до колбеков более-менее универсальным способом?
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).
Great У меня возникла более простая идея как найти DrvCоpyВits. Можно написать драйвер загружаемый перед win32k.sys который ждет загрузки драйвера дисплея. При появлении драйвера дисплея подменяем в его PE адрес функции Entery Point (которая в случае драйвера дисплая является ничем иным как DrvЕnаblеDrivеr) на свою функцию. В таком своего-роде патче получаем DrvCоpyВits
Great А как найти имя видео драйвера? Т.е., скажем, как определить, что в текущей системе видео драйвер это vboxdisp.dll ?
Извиняюсь - неправильно сформулировал вопрос. Как найти имя драйвер дисплея, т.е., файла погружаемого из win32k.sys. В случае VBox это vboxdisp.dll. Еще очень нужно, чтоб имя этого драйвера было известно до того как win32k.sys загружет его. Хочу перехватить DrvEnableDriver...
Кстати, смотрю исходники Great. Там есть строчка Код (Text): HANDLE hDrv = EngLoadImage (L"vid_copy.dll"); Что такое "vid_copy.dll"? Просто физическая копия файла драйвера дисплея?
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.