Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.07;
Скачать: [xml.tar.bz2];




Вниз

Загрузка DLL в чужой процесс 


JS   (2002-01-06 00:56) [0]

Как загрузить DLL в чужой процесс?
Буду очень благодарен за любые ответы или ссылки по данному вопросу.
Пожалуйста, не надо только ссылаться на Джеффри Рихтера - у меня нет возможности прочесть его книги. Если знаете где достать электронные варианты его книг - пишите или высылайте на jek_s@rambler.ru
Заранее благодарен.



Suntechnic   (2002-01-06 10:10) [1]

Например поставить ловушку, на подходящее для твоего случая событие. См. SetWindowHookEx.



Wizard   (2002-01-06 14:52) [2]

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
ключ AppInit_DLLs - загрузится во всЕ GUI программы :)



Aleksey Pavlov   (2002-01-08 10:42) [3]

Вообще говоря, ваша программа впринципе не может "навязать" другой программе какую-то dll. Это противоречит самому механизму работы Windows.
DLL может быть загружена только в адресное пространство процесса, её загрузившего.
Но возможны некоторые ухищрения, благодаря которым мы можем "заставить" некоторые Windows программы размещать в своём АП наши библиотеки.

Смотрите:
На hackzone была статья Tanak-и на эту тему - поищите.
Мои скромные мысли:
http://www.delphikingdom.com/helloworld/usesdll.htm



paul_shmakov   (2002-01-08 12:16) [4]

есть множество способов загрузки dll в адресное пространство процесса. разделить их можно на два вида: динамическая подгрузка и "статическая" (осуществляемая правкой exe-шника). у каждого из видов есть свои достоинства и недостатки.

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

статический метод позволяет либо добавить свой код, который вызовет LoadLibrary; либо изменить таблицу импорта, так, чтобы на этапе запуска exe-шника загрузчик подгрузил нашу dll. метод хорощ тем, что для дальнейшей работы не требуется никаких loader.exe - остается только программа-жертва и наша dll. достоинства являются и недостатками :( меняется исходный файл, что, безусловно, плохо. особенно если нужно внедрять dll в несколько процессов.

в каждом конкретном случае в зависимости от задачи нужно выбирать подходящий метод.

теперь несколько вариантов реализации статического и динамического внедрения. введем для удобства несколько обозначений. program.exe - программа, в которую мы внедряем нашу dll, mydll.dll - наша dll, loader.exe - программа, которая загружает нашу dll в адресное пространство program.exe (нужна для динамического метода).



paul_shmakov   (2002-01-08 12:16) [5]

динамические:

1. см. выше Wizard (06.01.02 14:52). недостатки метода - mydll.dll грузиться во все неконсольные процессы.
2. с помощью хуков. создается библиотека (inject.dll), из которой экспортируется функция (InjectMyDll), которая устанавливает глобальную ловушку на посылку любого сообщения. В этой же dll находиться функция-обработчик хука. Далее, процесс-загрузчик (loader.exe) подгружает inject.dll, вызывает InjectMyDll, та, в свою очередь, сразу же посылает главному окну
program.exe сообщение SendMessage(hWnd, WM_NULL, 0, 0) для того, чтобы program.exe первым подгрузил inject.dll. после того, как inject.dll загрузилась, вызывается код функции-обработчика хука. Эта функция и должна вызвать LoadLibrary("mydll.dll"). После того ловушку сразу снимаем, чтобы inject.dll не грузилась во все работающие процессы.
почему нельзя сразу было грузить mydll.dll вместо inject.dll? Потому что inject.dll выгрузиться виндами после снятия ловушки. Это самый простой способ.
этот способ не работает на консольных приложениях.
3. загрузка с помощью удаленного потока. в адресном пространстве процесса program.exe выделяем память (pMem = VirtualAllocEx), копируем в нее название нашей dll, т.е. строку "mydll.dll". Далее вызываем функцию CreateRemoteThread(..,..,.., @LoadLibraryA, pMem, .., ..). Т.е. создаем поток в чужом процессе, передавая в качестве функции потока адрес LoadLibrary, а в качксве параметра - адрес строки "mydll.dll". поток запускается, вызывается LoadLibrary и подгружается наша dll. очень удобный и простой метод. единственный недостаток - не работает под win9x.
4. более сложный метод. можно загрузить program.exe для отладки (флаг DEBUG_ONLY_THIS_PROCESS в CreateProcess). Тогда вашему процессу будет выдаваться куча уведомлений о том, что происходит в отлаживаемом процессе. Одно из таких уведомлений приходит, когда загрузчик windows загрузил процесс и все импортируемые им библиотеки, и процесс готов выполнить свою первую команду. вот в этот-то момент и можно вручную (программно) выделить в этом процессе себе память, записать туда название вашей dll, машинные инструкции для загрузки вашей dll и переход на оригинальную точку входа, после этого подправить структуру CONTEXT (исправить в ней регистр eip для того, чтобы он указывал на начало вашего "патча"), установить этот новый контекст (SetThreadContext) и запустить program.exe на дальнейшее выполнение. метод сложный, но универсальный. работает для любых приложений на всех операционках.



paul_shmakov   (2002-01-08 12:17) [6]

статические (статические методы более сложны и требуют понимания формата pe - portable executable):

1. добавление в pe-файл program.exe нескольких инструкций:

call loadlib
db "mydll.dll", 0
loadlib:
call LoadLibraryA
jmp OriginalEntryPoint

этот код можно добавить либо в существующую секцию с кодом (обычно .text) (если там есть свободное место), либо создать свою секцию. После этого подправить несколько полей в pe-заголовке, в частности EntryPoint, чтобы он указывал на новый код.
кроме того, program.exe должен импортировать функцию LoadLibrary. если нет - то все становиться намного сложнее. можно либо попытаться самостоятельено добавить эту функцию в секцию импорта, или находить ее адрес динамически. первый вариант может не пройти, т.к. место в таблице импорта не резиновое; второй тоже достаточно трудоемок. зато это все работает для всех версий виндов :)
2. изменение таблицы импорта. идея состоит в том, чтобы заставить стандартный виндовый загрузчик подумать, что программа статически использует вашу dll. Для этого необходимо, чтобы ваша dll экспортировала хотя бы одну произвольную функцию (функция может быть абсолютно любая, т.к. никто и никогда ее на самом деле вызывать не будет). Добавляем в таблицу импорта pe-файла новую запись, имя вашей dll, количество импортируемых функций равное 1, имя или ординал импортируемой функции и поле для адреса этой функции. у этого способа есть достоинства и, к сожалению, недостатки. загружать вашу dll будет уже не какой-то loader.exe, а стандартный виндусовый загрузчик pe-файлов, что конечно очень хорошо. а недостатки, опять же, технические: в секции импорта должно быть достаточно места для вышеназванных данных, что не всегда так. если я не ошибаюсь, то на эту тему очень хорошо писал Крис Касперски.

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




Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.07;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.75 MB
Время: 0.046 c
1-19227           AlexandrdD            2002-02-19 15:34  2002.03.07  
переменные класса?


4-19389           Igor_thief            2002-01-08 16:15  2002.03.07  
Как перехватывать нажатие кнопочки минимизации?


1-19138           cahek20000            2002-02-13 18:55  2002.03.07  
Синхронный скролинг


3-19099           kserg@ukr.net         2002-02-07 10:53  2002.03.07  
Нужен совет: что лучше использовать для создания отчетов?


3-19111           Alexy                 2002-02-11 15:24  2002.03.07  
Откат и обновление