Клизма для файрвола Николай «GorluM» Андреев Хакер, номер #072, стр. 072-112-3 Основан он целиком и полностью на использовании функции копирования памяти в чужое адресное пространство (WriteProcessMemory) и заключается в следующем. В пространстве требуемого процесса выделяется памяти ровно столько, сколько занимает образ программы с инжектируемым кодом. Причем память выделяется по тому же линейному адресу, что находится наша программа, только в другом пространстве. Затем программа аккуратно, байт за байтом, включая PE-заголовок, глобальные переменные и прочий стафф, копируется в выделенный участок. Запустить внедренный код после этого можно обыкновенным созданием нити в удаленном процессе. Ах, какие красота и удобство кроются в таком простом решении! (Да, Горл – настоящий гик. Половина его восхищений и весь мат были вырезаны :). - Прим. Dr.). За счет того, что копирование образа происходило по тому же адресу, что он был загружен, доступ ко ВСЕМ глобальным переменным в инжектируемом коде сохранится! Все адреса АПИ по-прежнему будут сидеть в таблице импорта (только скопированной в другое адресное пространство), поэтому их не придется вручную искать и передавать через параметры создаваемой нити. Но главное, не будут использоваться никакие DLL! Вся разработка программы, внедряющей свой код в чужой процесс, будет происходить в одном проекте. Словом, способ классный. Конечно, в его реализации есть масса маленьких хитростей, но о них мы поговорим ниже, сейчас пока можно просто немного похвалить ребят из «Культа Мертвой Коровы». Мастерим клизму Для того чтобы иметь доступ к памяти чужого процесса, его требуется открыть. Делается это с помощью функции OpenProcess, в параметрах которой передаются уровень получаемого доступа (у нас - PROCESS_ALL_ACCESS) и ID процесса, который мы хотим изнасиловать. Идентификатор этот можно получить как из Process Manager’а, так и программно. Я выбрал второй способ и с помощью специально собранной мной функции, работающей с ToolHelp API, получил ID по имени процесса (на диске в файле rat.h ты найдешь сорец этой функции). Обладая хэндлом открытого процесса, мы можем делать с ним все, что заблагорассудится, например, можем выделить в нем память для копирования в нее образа нашей программы. Функция VirtualAllocEx справится с этой задачей очень просто, стоит только указать ей, по какому адресу, сколько и зачем выделять памяти. Если адрес для выделения поймать легко – это всего лишь адрес базы нашего процесса, который получается с помощью GetModuleHandle(NULL), то вот объем выделяемой памяти нужно будет вычислять. Можно, конечно, выделить наугад полтора мега, но вряд ли из этого выйдет что-нибудь хорошее. Необходимый объем памяти, т.е. размер образа, можно прочесть в одной из ячеек PE-заголовка нашего процесса, если быть точным, то в SizeOfImage опционального заголовка (в коде это выглядит страшновато, но если разобраться в формате, станет все ясно). |