Делаем собственный инжектор

Давным-давно, во времена мифов и легенд, когда древние Боги были мстительны и жестоки и обрушивали на программистов все новые и новые проклятия… На хабре была опубликована статья про сплайсинг.

В качестве примера в статье был приведен довольно масштабный код, который воспринимался не особо легко. Захотелось разобраться в процессе инжекта, а также написать более простой и менее громоздкий код.
Вкратце, инжектинг — это подгрузка нашей библиотеки в сторонний процесс, а сплайсинг — перехват какой-либо функции (мы перехватывали WinAPI) и модификация её работы средствами этой самой библиотеки.
Пример будет состоять из двух частей: 1 — библиотека, 2 — инжектор, который будет внедрять библиотеку в целевой процесс. Библиотеку будем писать на masm, что позволит в разы сократить объемы кода, а инжектор — на Си.

Начнем с кода библиотеки [last updated on 15 aug 2010]. Что она делает? При подгрузке она заменяет первые 5 байт функции WinAPI, которую мы хотим перехватить, на JUMP на наш перехватчик. Мы можем это сделать в большинстве случаев, когда функция имеет пролог (то есть 100%, если функция принимает больше нуля аргументов, в этом случае в начале ее будут инструкции mov edi,edi; push ebp; mov ebp;esp, или же если функция имеет локальные переменные). Иногда функция не имеет пролога, но мы все равно можем осуществить перехват, если в начале функции имеются несущественные команды, например, NOP’ы (такое было обнаружено в функции GetTickCount на Windows Vista x64). Таких функций мало, судя по всему. Я приведу пример перехвата GetTickCount, но далеко не факт, что он сработает на вашей системе. Скажем, в XP SP3 кучи NOP’ов в начале тела функции нет. Всегда смотрите, как начинается функция без аргументов в системных библиотеках, прежде чем осуществлять ее перехват. У меня GetTickCount начиналась так:

Слишком короткие функции без пролога перехватить так просто не удастся (например, GetCurrentProcess или GetCommandLineA), потому что первые 5 байт — это уже их тело. Их перехват можно осуществить, например, изменив адреса в таблице импортов, если они там есть, но этот материал в данной статье не затронут. Что ж, теперь к коду. Я решил написать несколько макросов, чтобы удобно ставить и убирать хуки, а также вызывать оригинал функции.

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

Теперь рассмотрим код самого инжектора:

Исходный код dll’ки и инжектора одним архивом: скачать

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

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

В общем, делайте инжекты, ломайте чужой софт. Этот мир интересней, чем вам кажется. (с)

Оставьте первый комментарий

Оставить комментарий

Ваш электронный адрес не будет опубликован.


*