Pull to refresh

Comments 32

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

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

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

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

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

я же спрашиваю о готовых программах или наработках
Там, как раз есть наработки и примеры и даже готовый модуль для перехвата (во второй части), там на 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)
спасибо большое! сейчас нет времени разбираться, но похоже, что это то, что надо.
Есть ещё thinstall. Он тоже эмулирует отдельные ветки реестра.
Sign up to leave a comment.

Articles