суббота, 4 марта 2023 г.

 

Сканер установленных перехватчиков в памяти процесса

 


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

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

Где-то полгода назад у нас появилась очередная идея, есть очень много разноплановых ошибок которые достаточно проблематично покрыть тестами, но по результатам накопленного методом проб и ошибок опыта было выяснено что большая часть из них происходит по причине вмешательства стороннего софта в тело нашего процесса. Это могут быть как антивирусы, так и всякие DLP, а то и вовсе зловреды, которые лезут к нам в процесс, перехватывают некоторые критичные для выполнения API на себя и в обработчиках перехваченных функций ломают полностью логику исполнения кода.

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

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

Правда при общей простоте идеи реализация получилось достаточно трудоемкая.
Самая большая проблема при этом была в том что утилита 32 битная, а софт, работающий у пользователя может быть как 32 бита, так и 64 (второе более вероятно), поэтому для работы с 64 битным процессом пришлось писать соответствующую обвязку.

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

Короче в итоге получилось такое, как бы это назвать... антивирусный сканер на минималках :)

В этой статье я пройдусь по всем этапам построения такого сканера с нуля, постаравшись подробно описать каждый шаг чтобы было не только понимание что именно тут происходит, а чтобы вы (при желании, конечно) могли бы реализовать свой вариант такого сканера, даже не пользуясь моими наработками.

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