Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Создание эффективных приложений для Windows Джеффри Рихтер 2004 (Книга).pdf
Скачиваний:
377
Добавлен:
15.06.2014
Размер:
8.44 Mб
Скачать

}

else

{

nLen = GetModuleFileNameA((HINSTANCE) mbi.AllocationBase;

szModName, chDIMOF(szModName));

}

if (nLen > 0)

{

wspnntfA(strchr(szBuf, 0), "\n%08X-%s", mbi.AllocationBase, szModName);

}

pb += mbi.RegionSize;

}

chMB(&szBuf[1]);

Сначала я проверяю, не совпадает ли базовый адрес региона с базовым адресом внедренной DLL Если да, я обнуляю nLen, чтобы не показывать в окне имя внедренной DLL. Нет — пьтаюсь получить имя модуля, загруженного по базовому адресу данного региона, Если значение nLen больше 0, система распознает, что указанный адрес идентифицирует загруженный модуль, и помещает в буфер szModName полное имя (вместе с путем) этого модуля. Затем я присоединяю HINSTANCE данного модуля (базовый адрес) и его полное имя к строке szBuf, которая в конечном счете и появится в окне Когда цикл заканчивается, DLL открывает на экране окно со списком.

Внедрение троянской DLL

Другой способ внедрения состоит в замене DLL, загружаемой процессом, на другую DLL. Например, зная, что процессу нужна Xyz.dll, Вы можете создать свою DLL и присвоить ей то же имя. Конечно, перед этим Вы должны переименовать исходную Xyz.dll.

В своей Xyz dll Вам придется экспортировать те же идентификаторы, что и в исходной Xyz.dll. Это несложно, если задействовать механизм персадресации функций (см. главу 20); однако его лучше не применять, иначе Вы окажетесь в зависимости от конкретной версии DLL Если Вы замените, скажем, системную DLL, a Microsoft потом добавит в нее новые функции, в Вашей версии той же DLL их не будет. А значит, не удастся загрузить приложения, использующие эти новые функции.

Если Вы хотите применить этот метод только для одного приложения, то можете присвоить своей DLL уникальное имя и записать его в раздел импорта исполняемого модуля приложения. Дело в том, что раздел импорта содержит имена всех DLL, нужных ЕХЕ-модулю. Вы можете "покопаться" в этом разделе и изменить его так, чтобы загрузчик операционной системы загружал Вашу DLL. Этот прием совсем неплох, но требует глубоких знаний о формате EXE- и DLL-файлов.

Внедрение DLL как отладчика

Отладчик может выполнять особые операции над отлаживаемым процессом. Когда отлаживаемый процесс загружен и его адресное пространство создано, но первичный поток сщс нс выполняется, система автоматически уведомляет o6 этом отладчик. В этот момент отладчик может внедрить в него нужный код (используя, например, WriteProcessMemory), а затем заставить его первичный поток выполнить внедренный код.

Этот метод требует манипуляций со структурой CONTEXT потока отлаживаемого процесса, а значит, Ваш код будет зависим оттипа процессора, и его придется модифицировать при переносе на другую процессорную платформу Кроме того, Вам почти наверняка придется вручную корректировать машинный код, который должен быть выполнен отлаживаемым процессом. Не забудьте и о жесткой связи между отладчиком и отлаживаемой программой как только отладчик закрывается, Windows немедленно закрывает и отлаживаемую программу. Избежать этого нельзя.

Внедрение кода в среде Windows 98 через проецируемый в память файл

Эта задача в Windows 98, по сути, тривиальна. В ней все 32-разрядные приложения делят верхние два гигабайта своих адресных пространств. Выделенный там блок памяти доступен любому приложению. С этой целью Вы должны использовать проецируемые в память файлы (см. главу 17). Сначала Вы создаете проекцию файла, а потом вызываете MapViewOfFile и делаете ее видимой. Далсс Вы записываете нужную информацию в эту область своего адресного пространства (она одинакова во всех адресных пространствах). Чтобы все это работало, Вам, вероятно, придется вручную писать машинные коды, а это затруднит перенос программы на другую процессорную платформу. Но вряд ли это должно Вас волновать — все равно Windows 98 работает только на процессорах типа x86.

Данный метод тоже довольно труден, потому что Вам нужно будет заставить потокдругого процесса выполнять код в проекции файла. Для этого понадобятся какието средства управления удаленным потоком. Здесь пригодилась бы функция CreateRemoteThread, но Windows 98 ее не поддерживает. Увы, готового решения этой проблемы у мсня нет.

Внедрение кода через функцию CreateProcess

Если Ваш процесс порождает дочерний, в который надо внедрить какой-то код, то задача значительно упрощается. Родительский процесс может создать новый процесс и сразу же приостановить его. Это позволит изменить состояние дочернего процесса до начала его выполнения. В то же время родительский процесс получает описатель первичного потока дочернего процесса. Зная его, Вы можете модифицировать код, который будет выполняться этим потоком. Тем самым Вы решите проблему, упомянутую в предыдущем разделе: в данном случае нетрудно установить регистр указателя команд, принадлежащий потоку, на код в проекции файла.

Вот один из способов контроля за тем, какой код выполняется первичным потоком дочернего процесса: