информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медSpanning Tree Protocol: недокументированное применение
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / operating systems
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Вызов сервисов Win32k.sys из Kernel-mode драйвера 12.02.03 09:02  Число просмотров: 2681
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
вот еще чего вспомнил:

есть ф-я KeUserModeCallback, с помощью нее можно вызывать некоторые ф-ии... ее описания я не нашел - есть только это:

http://www.cmkrnl.com/arc-userapc.html

цитата:
"2. KeUserModeCallback(). This is an undocumented function used by Win32 subsystem running in the kernel in NT 4.0 (win32k.sys). It's used when the subsystem either needs to know some information stored in user-mode (for example, in user32.dll's data), or needs to call a thread's window procedure (for example, when you move your mouse, the subsystem eventually receives notification of it in kernel mode, and it calls your window procedure with WM_MOUSEMOVE message using this function). A catch here is that this mechanism is predefined to call only some specified functions: one of parameters to KeUserModeCallback() is an index to a special table from which later in user mode an address to call is fetched."

cb.
<operating systems>
Вызов сервисов Win32k.sys из Kernel-mode драйвера 10.02.03 13:34  
Автор: Alexander N. Brandt Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Вот, возникла необходимость использовать пользовательские сервисы 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 драйвер вызывать необходимые сервисы? С какими проблемами можно столкнуться, реализуя описанные варианты?

Заранее благодарен за дельные советы и конструктивную критику... :)
Вызов сервисов Win32k.sys из Kernel-mode драйвера 20.02.03 15:19  
Автор: Alexander N. Brandt Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Всем огромное спасибо за дельные советы, все ссылки скачаны, все ходы записаны... :) Сейчас пришлось переключиться на немного другой поект и сабжевая тема временно потеряла актуальность...
Пока, вроде, работает через создание третьего дескриптора в основной таблице - копии первого дескриптора теневой, но вопрос стабильности системы в данном случае по-прежнему остаётся.
Существуют какие-нибудь стандартные критерии стабильности? Например, какой-нибудь тест, запустив который, можно было было бы с уверенностью сказать, что раз система за сутки, например, не выпала в синий экран, то и в дальнейшем (при такой же конфигурации, разумеется) с ней ничего не случится?
Вызов сервисов Win32k.sys из Kernel-mode драйвера 10.02.03 15:10  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> Вот, возникла необходимость использовать пользовательские
> сервисы win32k.sys в драйвере ядра

вообще это не самая хорошая мысль... стабильности системе это явно не способствует...

> В принципе, проблема решаема: накрайняк, можно искать вниз
> от KeSystemServiceTable строку байт, соответствующую
> нулевому дескриптору KeSystemServiceTable - это, скорее
> всего и будет теневая таблица, но может быть есть более
> изящные способы?

посмотри здесь:

http://2cb.smtp.ru/__he4hook_v21a_20021110.zip
kernelmode\source\he4hookinv\misc\misc.cpp => LPSSDT FindShadowTable(void)

в принципе тоже не самый красивый способ (на всякий случай - его придумал не я ;)) - подсмотрел в rootkit-e), но по другому вряд ли получится.

> Может быть, есть какие-нибудь другие способы заставить
> kernel-mode драйвер вызывать необходимые сервисы?

на мой взгляд эти сервисы не зря вынесли в отдельную таблицу - скорее всего их нельзя "безопасно" вызвать из ядра, а посему это плохой путь....

может ты изложишь проблему в целом? может без этого можно обойтись?

cb.
Вызов сервисов Win32k.sys из Kernel-mode драйвера 11.02.03 13:58  
Автор: Alexander N. Brandt Статус: Незарегистрированный пользователь
<"чистая" ссылка>
> > сервисы win32k.sys в драйвере ядра
>
> вообще это не самая хорошая мысль... стабильности системе
> это явно не способствует...

Вот я тоже это нутром чувствую, а доказать не могу... :)
Вчера попробовал софтайсом скопировать первый дескриптор теневой таблицы в третий основной - всё работало, сервисы вызывались, система за два часа (не интенсивного, правда) пользования так и не упала... :)
Что интересно - компоненты ядра системы сами пытаются вызывать сервисы из диапазона номеров win32k, но поскольку дескриптора в основной таблице нет - благополучно обламываются, а вот если теневую таблицу скопировать на место основной - система живёт какое-то время (каждый раз по-разному) а потом выпадает в синий экран с ошибкой в win32k.sys

> посмотри здесь:
> в принципе тоже не самый красивый способ (на всякий случай
> - его придумал не я ;)) - подсмотрел в rootkit-e), но по
> другому вряд ли получится.

Пасиб. Выкачал, буду думать... :)

> > Может быть, есть какие-нибудь другие способы заставить
> > kernel-mode драйвер вызывать необходимые сервисы?
>
> на мой взгляд эти сервисы не зря вынесли в отдельную

Тут вот ставил эксперимент. Повесил фильтр на клавиатуру, при каждом нажатии вызывался 11BAh (NtUserMapvirtualkeyEx()) которому передавался сканкод клавиши, возвращаемый результат писался в файл. В результате выяснилось, что в большинстве случаев вызов, как ему и положенно, обламывался (ЕАХ=0), но иногда благополучно возвращал virtual-key code.
Это и есть обещаная нестабильность? Если у кого-то есть объяснение этому - просьба меня просветить... :) Есть мысль, что можно не мудрить с SDT, а просто стабилизировать единично возникающий ненулевой результат... :)

> таблицу - скорее всего их нельзя "безопасно" вызвать из
> ядра, а посему это плохой путь....

Хз. Будем думать, будем тестировать... :)

> может ты изложишь проблему в целом? может без этого можно
> обойтись?

Наверняка можно, осталось только выяснить, как... :)
Проблема на данный момент - найти нужное окно по заголовку, и ввести в него определённый текст с учётом текущей раскладки клавиатуры.
Понятно, что на уровне приложения такое делается просто, но вот надо чтоб всё было сделано в коде драйвера. Ясен пень, что глупость, но вот надо.... :)
Вызов сервисов Win32k.sys из Kernel-mode драйвера 12.02.03 09:02  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
вот еще чего вспомнил:

есть ф-я KeUserModeCallback, с помощью нее можно вызывать некоторые ф-ии... ее описания я не нашел - есть только это:

http://www.cmkrnl.com/arc-userapc.html

цитата:
"2. KeUserModeCallback(). This is an undocumented function used by Win32 subsystem running in the kernel in NT 4.0 (win32k.sys). It's used when the subsystem either needs to know some information stored in user-mode (for example, in user32.dll's data), or needs to call a thread's window procedure (for example, when you move your mouse, the subsystem eventually receives notification of it in kernel mode, and it calls your window procedure with WM_MOUSEMOVE message using this function). A catch here is that this mechanism is predefined to call only some specified functions: one of parameters to KeUserModeCallback() is an index to a special table from which later in user mode an address to call is fetched."

cb.
Вызов сервисов Win32k.sys из Kernel-mode драйвера 11.02.03 14:34  
Автор: cb <cb> Статус: Member
<"чистая" ссылка>
> Что интересно - компоненты ядра системы сами пытаются
> вызывать сервисы из диапазона номеров win32k, но поскольку
> дескриптора в основной таблице нет - благополучно
> обламываются,

любопытно...
А какие именно сервисы вызываются? пример можешь привести?

> В результате выяснилось, что в большинстве случаев вызов, как
> ему и положенно, обламывался (ЕАХ=0), но иногда
> благополучно возвращал virtual-key code.
> Это и есть обещаная нестабильность? Если у кого-то есть
> объяснение этому - просьба меня просветить... :) Есть
> мысль, что можно не мудрить с SDT, а просто стабилизировать
> единично возникающий ненулевой результат... :)

может быть вызов завершался успешно когда он был сделан в контексте нужного процесса? если да томножно попробовать использовать KeAttachProcess....

> Проблема на данный момент - найти нужное окно по заголовку,
> и ввести в него определённый текст с учётом текущей
> раскладки клавиатуры.
> Понятно, что на уровне приложения такое делается просто, но
> вот надо чтоб всё было сделано в коде драйвера.

логин/пароль что-ли? ;)))

можно попробовать такой путь:
переключиться в контекст нужного процесса (KeAttachProcess), выделить память в пользовательской области (NtAllocateVirtualMemory), скопировать в выделенный кусок заранее подготовленный код, найти UserMode поток в этом процессе - переключить его на исполнение скопированного кода, после чего вырнуть поток в исходное состояние (вместо нахождения существующего потока можно попробовать создать свой)... ну а какой код ты положишь в эту память - тебе видней...

выглядит все это дико и я не уверен в "реализуемости" некоторых шагов, плюс видимо потребуется знание недокументированных структур описывающих поток, но попробовать можно... мне кажется я где-то встречал реализацию подобной вещи....

cb.
Вызов сервисов Win32k.sys из Kernel-mode драйвера 12.02.03 01:22  
Автор: SerpentFly <Vadim Smirnov> Статус: Member
<"чистая" ссылка>
> может быть вызов завершался успешно когда он был сделан в
> контексте нужного процесса? если да томножно попробовать
> использовать KeAttachProcess....

Скорее все-таки потока. Если этот поток вызывал GUI, то в его TEB лежит указатель на ServiceDescriptorTableShadow вместо ServiceDescriptorTable.

Дискуссия на похожую тему тут:

http://forum.ntkernel.com/viewtopic.php?t=7
Мои мысли 11.02.03 19:01  
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
Можно создать поток в UserMode (желательно в процессе System) - для таких дел даже какая-то функция есть.

Вот как это сделано в strace для винды
/*
 * Find the address of the KeServiceDescriptorTableShadow.
 * Uses technique from Undocumented Windows NT.
 */
static struct srv_table *
find_shadow_table ()
{
    unsigned char *check = (unsigned char *)KeAddSystemServiceTable;
    int i;
    struct srv_table *rc=0;

    for (i=0; i<100; i++) {
        __try {
            rc = *(struct srv_table**)check;
            if (!MmIsAddressValid (rc)
               |(rc == KeServiceDescriptorTable)
               |(memcmp (rc, KeServiceDescriptorTable, sizeof (*rc))
                    != 0)) {
                check++;
                rc = 0;
            }
        } __except (EXCEPTION_EXECUTE_HANDLER) {
            rc = 0;
        }
        if (rc)
            break;
    }
    return rc;
}

---

Короче, так как и предлагалось с самого начала
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach