Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 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.



Страницы: 1 вся ветка

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

Наверх





Память: 0.48 MB
Время: 0.005 c
14-19348
Сержик
2002-01-24 15:59
2002.03.07
А чё, правда, что Delphi6 на русском языке бывает?


1-19132
_Pavel
2002-02-20 20:52
2002.03.07
C++ DLL Delphi


1-19242
Miwa
2002-02-19 19:32
2002.03.07
Вывод сообщения


4-19376
DrDrew
2002-01-09 01:09
2002.03.07
Программа перехватчик Сообщений и Ответов на них


1-19204
macinsoft
2002-02-18 09:27
2002.03.07
Есть StringGrid, есть PopUpMenu на странице ...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский