Обновить

Комментарии 32

Почитайте в гугле по запросу «Перехват API-функций», там и подробное описание и примеры есть.
У Рихтера подробно и с примерами. Читайте классику.
Функции работы с реестром находятся в библиотеке advapi32.dll, такие, как: RegOpenKeyEx, RegQueryValueEx, RegCloseKeyEx, etc…

При загрузке приложения, винда начинает искать эту библиотеку сначала в папке с экзэшником, далее в… не помню точно… в system32\windows и в конце в путях переменных PATH…

Что я предлагаю — я предлагаю реализовать библиотеку-фильтр с функциями «пустышками» внутри, естественно там не совсем пустышки, а просто вызов настоящей функции с фильтрацией параметров…

После чего достаточно поместить эту библиотеку рядом с исполняемым файлом, он её подхватит при загрузке.
Да, ещё для этого уж очень необходим MSDN…
деталями реализации я уже интересовался
этот вариант неудобен, так как нужно дублировать _все_ функции длл-ки, а не только необходимые
более правильный вариант — использовать лаунчер, который запустит нужный процесс в приостановленном состоянии, подменит указатели в процессе и разбудит его

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

я же спрашиваю о готовых программах или наработках
Тогда вот, уважаемый мною сайт — www.wasm.ru/series.php?sid=8
Там, как раз есть наработки и примеры и даже готовый модуль для перехвата (во второй части), там на Delphi…
Перехватывать нужно функции NtБлаБла, что бы меньше мороки было.
Видимо меня кто-то не понял, поэтому расшифрую свою фразу.
Что бы сделать свою заглушку для, например, функции RegOpenKeyEx нужно перехватить две функции
RegOpenKeyExA и RegOpenKeyExW, которые в итоге сводятся к одной NtRegOpenKeyEx, перехватив которую можно убить двух зайцев одним выстрелом.
В WinAPI есть два правила, которые в 90% случаев выполняются.

FooFuncA всегда вызывает FooFuncW (исключение вроде бы GetProcAddress)

Если есть FooFuncEx, FooFunc вызывает FooFuncEx
Вообще за работу с реестром отвечают:
ZwCreateKey, ZwDeleteKey, ZwEnumerateKey, ZwEnumerateValueKey, ZwFlushKey, ZwQueryKey, ZwQueryValueKey, ZwSetValueKey. (В первый раз хабр не пропустил список)
API ZwXxxxXxx не предназначены для использования прикладными программами. Завязываясь на них при проектировании приложений, вы напрашиваетесь на проблемы.
Zw == прямые jmp в ядро. (9x не рассматриваем? Если рассматриваем, то возможно надо писать драйвер для 9x, потому что Advapi32.dll может быть read-only)
Алло, прямые jmp в ядро Не. Предназначены. Для. Использования. Прикладными. Программами.

Функции ZwXxxxXxx (NT native API) не являются частью WinAPI.

В следующей версии винды Микрософт поменяет что-то и вашей программе кранты.
Zw не может поменяться просто так, для этого ms придется переписать:
1. все апи 3-го кольца.
2. поменять параметры для sysenter (рутина)
3. поменять интерфейс для драйверов.

Zw — нормальные ядерные функции и если надо что-то контролировать, то перехват Zw в ядре или на границе входа в ядро — самый лучший и самый надежный способ.
Microsoft очень большой кусок API уже переписала между 3.1 и 4.0, когда перетащила user/gdi в ядро. Чего гарантирует от? :)

Зачем нам ядерные функции, если мы можем уровнем ниже все сделать?

А уже driver model сколько раз меняли…
да, переписали. А почему они это сделали? Потому что держать gui в 3-ем кольце это суицид. Постоянные прыжки «туда-обратно» губят всю производительность. Те, кто до сих пор используют их, не могут удивит юзера скоростью реакции на действия пользователя.
Zw уже «устоялись» — с NT 4.0 по 2008 не изменилось ничего (никто не знает что будет завтра с ms, может они вообще win32 прикроют :)).

Перехват стоит делать в самом прямом месте. (тут заменив всего 1 jmp получаем _thread safe_ фильтр. Красота! :))

О какой конкретно driver model речь? (изменения прошли мимо :\)
Да, а WinApi устоялся значительно дольше. Функции работы с реестром у нас с Windows 3.11 вроде как HKEY_CLASSES_ROOT появился :)

API не предназначен для прикладных программ, пользовать его не надо. Амба :)

Driver model: Windows NT driver model —> WDM —> WDF
никаких холиваров, сугубо практика.
Если потребуется перехватить api, то я найду самое «узкое» место и поставлю самый надежный (== самый простой) хук. Далее уже можно сосредоточится на реализации фильтра и т.д.

P.S. Это скорее эволюция. WDM жив, его нельзя убивать, слишком много софта его использует… (правда, winapi использует намного больше софта и его тоже нельзя убивать)
добрался до рабочей машины (прошу прощения, за поздний ответ). Отрывок из msdn для «ZwOpenKey»:

Note If the call to this function occurs in user mode, you _should_ use the name «NtOpenKey» instead of «ZwOpenKey».

Это почти 99% гарантия, что апи менятся не будет. И прямые прыжки в ядро разрешены (раз ms считает что user mode может вызывать ядро).

P.S. NtOpenKey == ZwOpenKey (только что проверил в дебагере)
Обратите внимание также, что в ядре сделать, когда можно в userspace, противоречит не только пуристкому желанию не лезть в ядро когда не надо, но и следующим условиям задачи:
1. Нужен WinAPI хук (Zw не является часть WinAPI)
2. Самое идее portable. Сделать так, чтобы protable программа требовала драйвер…
я говорю только про 3-е кольцо.
1. Zw вполне относится к winapi (ms говорит в msdn, что вызывать можно)
2. Зачем драйвер? 1 jmp и фильтры. Когда приложение хочет реестр, оно доходит до входа в ядро (Zw), там наш обработчик перенаправляет на фильтр, фильтр пускает (или не пускает) в ядро.
вот люди! из чего угодно холивар устроят!
Не холивар, а рабочее обсуждение, сделать так или так :)
Я, кстати, горжусь, что вы знаете что такое NT native api.
:)
я драйверы пишу 0_o (win/lin/embedded)
Такие программы уже существуют, например JauntePE, BoxedApp.
спасибо большое! сейчас нет времени разбираться, но похоже, что это то, что надо.
Есть ещё thinstall. Он тоже эмулирует отдельные ветки реестра.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации