Вот, возникла необходимость использовать пользовательские сервисы win32k.sys в драйвере ядра - необходимо эмулировать работу таких функций, как, например GetForegroundWindow(). Поскольку для потоков ядра существует только один не нулевой дескриптор сервисов по адресу KeServiceDescriptorTable+0, то вызовы int2e c еах>0x0FFFh попросту обламываются диспетчером вызовов. Для юзерских потоков используется теневая таблица дескрипторов, с дескриптором сервисов win32k.sys, по адресу KeServiceDescriptorTableShadow+10h.
Тут мне видится два возможных варианта:
1. Из теневой таблицы дескрипторов для сервисов win32k.sys вычислять адреса функций, выполняющих необходимые мне сервисы и вызывать их напрямую;
2. С помощью KeAddSystemServiceTable() в основной таблице дескрипторов создать дескриптор
№3 (считаем от нуля) - копию первого дескриптора теневой таблицы. Тогда, например, сервис 1189h будет вызываться просто как 3189h.
Вся проблема в том, чтобы найти адрес KeSystemServiceTableShadow - эта
переменная, в отличии от KeSystemServiceTable, не экспортируется, и в общем случае, теневая таблица может находиться где угодно (обязательно за основной таблицей?). В принципе, проблема решаема: накрайняк, можно искать вниз от KeSystemServiceTable строку байт, соответствующую нулевому дескриптору KeSystemServiceTable - это, скорее всего и будет теневая таблица, но может быть есть более изящные способы?
Наверняка в вышеизложенных вариантах есть свои тонкости и подводные камни... :)
Может быть, есть какие-нибудь другие способы заставить kernel-mode драйвер вызывать необходимые сервисы? С какими проблемами можно столкнуться, реализуя описанные варианты?
Заранее благодарен за дельные советы и конструктивную критику... :)
|