Реферат: API Spying
написать обёртку;
добавить строчку в HookThemAll.
Это, конечно, довольно простые операции… Но представьте, что таким образом вам нужно перехватить несколько сотен функций. А если не у всех функций известны прототипы? А если некоторые dll загружается динамически, и вы пока даже не знаете, какие их функции используются приложением? А если после того, как вы всё успешно перехватите и просмотрите получившиеся логи, станет понятно, что для детального понимания работы приложения нужно было перехватить всего две функции и изучить их параметры :) ?
Когда все эти вопросы встали передо мной, я занялся API Spying-ом.
API Spying не исключает перехвата API, но эти методики используются находятся на разных стадиях анализа программы. Сначала при помощи API Spying-а определяется несколько наиболее интересных функций, потом, если необходимо, эти функции перехватываются и изучаются «в более тесном контакте».
Постановка задачи
В самом общем виде задача выглядит так:
Необходимо получать информацию о фактах вызова выбранных функций исследуемым приложением.
Для получения статистики не обязательно заранее знать имена функций, которые будут вызываться приложением. Тем более, не нужно знать их прототипы.
Сбор статистики для любого (в том числе заранее неизвестного) количества функций из любых (в том числе, из загружаемых динамически) модулей не должен представлять трудностей.
Работоспособность исследуемого приложения не должна нарушаться.
Формулировка ТЗ
Логически разовьём требования, высказанные в постановке задачи:
Мы рассматриваем только программные реализации. Это значит, что статистика собирается программно, и этим занимается наш код.
Поскольку при каждом вызове отслеживаемых функций управление должно передаваться нашему коду, все отслеживаемые функции нужно перехватить (тем или иным способом; подробное рассмотрение способов перехвата API выходит за рамки статьи). Нашу функцию, которой в результате перехвата будет передаваться управление, назовём функцией-шпионом (терминология моя, сожалею, если не прав).
Чтобы вести статистику вызовов и не нарушать работу приложения, функция-шпион должна определить, какую именно отслеживаемую функцию собиралось вызвать исследуемое приложение. Единственный способ реализовать это – сопоставить каждой отслеживаемой функции свою функцию-шпиона, «знающую», как минимум, адрес оригинала.
По возможности, присутствие функции-шпиона не должно влиять на выполнение отслеживаемой функции. Это получается не всегда, разумные исключения описаны ниже, в разделе «Почему приложение может перестать работать».
Так как количество отслеживаемых функций может быть велико или заранее не известно, функции-шпионы должны генерироваться автоматически в процессе исполнения.
Несколько дополнительных пожеланий:
Автоматически генерировать сложные функции-шпионы непросто. :) Их даже писать на ассемблере замаешься... Хорошо бы подсчёт статистики взял на себя кто-то другой.
ПРИМЕЧАНИЕ Вы классно знаете ассемблер, и считаете, что это пара пустяков? Возможно, вы не учли, что код функций будет расположен в произвольном месте адресного пространства и что (забегая вперёд; но вы-то это всё должны понимать) функции не могут модифицировать стек и регистры. Если и это для вас не проблема, то, во-первых, примите моё искреннее восхищение (без шуток!), во-вторых, прочитайте следующий пункт. :) |
Автоматическая генерация подразумевает выделение памяти для кода функций, а, так как их может быть много, желательно чтобы функции были короткими. Поэтому, опять же, хорошо бы подсчёт статистики взял на себя кто-то другой.
И несколько ограничений:
Эта реализация поддерживает только Intel x86-совместимые процессоры.
Для работы функции-шпиона от ОС требуется только одно: она должна позволять исполнять динамически сгенерированный код. Это условие соблюдается во всех версиях Windows и, скорее всего, в подавляющем большинстве остальных ОС общего пользования. Но, поскольку нам необходим ещё и способ перехвата, ограничимся линейкой Windows NT/2000/XP. Используя другие способы перехвата, можно реализовать API Spying для других ОС.
Неизвестно, как на исполнение сгенерированного кода будут реагировать антивирусы. Возможно, они будут недостаточно толерантны. :)
СОВЕТ О подобных ограничениях лучше не забывать и в реальных проектах, так как иначе выполнить ТЗ будет практически невозможно. |