Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выгрузить чужую DLL 
:(
    Опции темы
Domoffou
Дата 26.6.2008, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Здравствуйте.
Каким образом можно выгрузить из памяти чужую DLL?
Моя DLL работает самостоятельно =)
При скачивании более новой версии, моя программа (updater)
должна заменять старый длл на новый, а вот как это сделать без выгрузки - не знаю,
возможно обмен данными между "чужим" процессом (апдейтером) и местной длл,
и выгрузка в последствии из самой себя? (если такое вообще возможно).

Это сообщение отредактировал(а) Domoffou - 26.6.2008, 00:42
PM MAIL ICQ   Вверх
Riply
Дата 26.6.2008, 05:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Domoffou @  26.6.2008,  00:07 Найти цитируемый пост)
Каким образом можно выгрузить из памяти чужую DLL?
Моя DLL работает самостоятельно =)


Так чужую или свою ?   smile 

Цитата(Domoffou @  26.6.2008,  00:07 Найти цитируемый пост)
и выгрузка в последствии из самой себя? (если такое вообще возможно).


FreeLibraryAndExitThread  ?


PM MAIL   Вверх
Domoffou
Дата 26.6.2008, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Цитата

Так чужую или свою ? 

Ну вообще свою smile
Но, получается, выгрузка своей библиотеки, запущенной от своей же (но другой) программы, которая уже не работает smile

Библиотека загружается посредством Loadlibrary в одной программе,
далее программы выходит БЕЗ FeeeLibrary.
DLL остается в памяти.
Мне необходимо заменить длл, находящийся на диске, но, соответственно, изменить его не могу, пока не будет перезагружен комп,
а его перезагружать не желательно.

FreeLibraryAndExitThread   - не помогает :(

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

Это сообщение отредактировал(а) Domoffou - 26.6.2008, 09:19
PM MAIL ICQ   Вверх
CodeMonkey
Дата 26.6.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Код
либо послать сообщение ДЛЛ, а она в свою очередь сама самостоятельно отсоединится от всех процессов и завершит работу и с файлом можно будет делать все что угодно.

Эту фичу стоило бы назвать: "случайным образом обрушь программы, использующие мою DLL". Вы представляете, что будет, если приложение попробует воспользоваться DLL после того, как вы её выгрузили?


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Riply
Дата 26.6.2008, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Domoffou @  26.6.2008,  09:00 Найти цитируемый пост)
Но, получается, выгрузка своей библиотеки, запущенной от своей же (но другой) программы, которая уже не работает 


Вот это сформулировал - так сформулировал !  smile 

Я поняла так:
1. есть твоя библиотека, которую загрузил некий процесс.
2. у тебя есть возможность общения с ней (библиотекой)

Ну и отлично: сообщаем ей, что пора выгружаться и она
делает это, например, при помощи FreeLibraryAndExitThread.

P.S. Сама использовать эту ф-ю не пробовала ( в те поры не знала о ее существовании).
Выгружалась "вручную": сообщала библиотеке, что пора закругляться,
и создавала нить, в которой вызывала FreeLibrary.

Добавлено через 4 минуты и 17 секунд
Цитата(CodeMonkey @  26.6.2008,  10:07 Найти цитируемый пост)
Вы представляете, что будет, если приложение попробует воспользоваться DLL после того, как вы её выгрузили? 


Так перед выгрузкой надо пресечь данные, совершенно наглые попытки в корне  smile 
Иными словами вежливо попросить целевой процесс самостоятельно выгрузить нас smile

PM MAIL   Вверх
CodeMonkey
Дата 26.6.2008, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Цитата(Riply @  26.6.2008,  10:15 Найти цитируемый пост)
Так перед выгрузкой надо пресечь данные, совершенно наглые попытки в корне smile   Иными словами вежливо попросить целевой процесс самостоятельно выгрузить нас  smile 

Совершенно верно. Но я сказал это только для того, чтобы уточнить, понимает ли это автор вопроса. 
P.S. А то с некоторых станется и вызвать в бесконечном цикле FreeLibraryAndExitThread из главного потока.



--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Domoffou
Дата 26.6.2008, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Как я понимаю, DLL фактически работает со всеми процессами в системе?
Т.е. при Loadlibrary он присоединяется ко всем процессам (в DLL висит хук).
Пробовал ставить DLL_PROCESS_DETACH, но эта функция запускается каждый раз при закрытии какого-либо приложения (жаль, что ей нельзя воспользоваться глобально) :(
Riply, я попробовал функцию, которую Вы мне предложили.
Программа, вызывающая эту функцию, попросту закрывается, а DLL продолжает работать и записывать тестовый лог.
Возможно, я не очень понимаю, но мне нужно вызвать FreeLibraryAndExitThread столько раз, сколько процессов в системе?

Вся проблема в том, что программа, загружающая длл и программа, которая должна ее выгружать - это д.б. разные процессы,
причем работа второго должна производиться без деятельности первого (1 процесс закрыт, ДЛЛ висит в памяти).

Если я правильно понимаю - целевой процесс, это программа, загрузившая ДЛЛ? Ну дык она уже и не работает smile

Это сообщение отредактировал(а) Domoffou - 26.6.2008, 11:09
PM MAIL ICQ   Вверх
Domoffou
Дата 26.6.2008, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Сделал выводы из умной литературы smile
Первый раз, при загрузке DLL она помещается в память, выполняются действия при инициализации ДЛЛ, глобальный счетчик юзания этой длл становится 1.
Программа закрывается, длл висит в памяти. Счетчик по-прежнему 1.
Запускается другая программа, подсоединяется к моей ДЛЛ,
счетчик становится 2, хотя действия при инициализации не выполняются, т.к. длл уже в памяти.
Делаю из 2 программы FREELIBRARY, длл отсоединяется от 2 процесса, счетчик становится 1.
А выгрузка производится при длл равной 0.
Правильно ли я понимаю? smile
И что делать, как говорится, в такой ситуации.

P.S. FreeLibraryAndExitThread д.б. в библиотеке?

Это сообщение отредактировал(а) Domoffou - 26.6.2008, 11:45
PM MAIL ICQ   Вверх
Riply
Дата 26.6.2008, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Domoffou @  26.6.2008,  11:06 Найти цитируемый пост)
Если я правильно понимаю 


Цитата(Domoffou @  26.6.2008,  11:43 Найти цитируемый пост)
Правильно ли я понимаю?


Надо бы тебе еще почитать "умной литературы"  smile 

Я поступала так (это не руководство к действию, а просто рассказ smile )
1. Делаем невозможной продгрузку Dll-ки новыми процессами (зависит от способа, которым ты подгружал)
2. Сообщаем уже подгруженным, что пора закругляться.
    (Они должны подчистить за собой все, что напакостили в процессе)  smile 
3. Опять зависит от способа загрузки, но попробуй так:
    Каждая Dll-ка (подчистив за собой) создает нить, в которой вызывается FreeLibraryAndExitThread
    (эта нить не должна использовать ничего из DLL)

По поводу:
Цитата(Domoffou @  26.6.2008,  11:06 Найти цитируемый пост)
1 процесс закрыт, ДЛЛ висит в памяти

не уверена, что это возможно (ну, скажем так: лего реализуемо)   smile 

PM MAIL   Вверх
CodeMonkey
Дата 26.6.2008, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



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

Цитата(Domoffou @  26.6.2008,  11:06 Найти цитируемый пост)
Т.е. при Loadlibrary он присоединяется ко всем процессам (в DLL висит хук).

Вот с этого и надо было начинать. Вы, кстати, ловушку перед выходом снимаете?

Цитата(Domoffou @  26.6.2008,  11:43 Найти цитируемый пост)
И что делать, как говорится, в такой ситуации.

http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=62697
http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=58060

Цитата(Domoffou @  26.6.2008,  11:43 Найти цитируемый пост)
Правильно ли я понимаю?

Да, правильно.





--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Domoffou
Дата 26.6.2008, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Цитата(CodeMonkey @  26.6.2008,  12:08 Найти цитируемый пост)
Вы, кстати, ловушку перед выходом снимаете?

Перед выходом чего? ДЛЛ остается в памяти.
Я то как раз и пытаюсь сделать выход.

Несколько вопросов:
1. Хук в длл "присоединяется" к памяти всех процессов, с кем работает юзер? Т.е. чтобы выгрузить библиотеку, нужно заставить каждую прогу снять с нее хук или попросту закрыть?
2. При первой загрузке ДЛЛ происходит инициализация. При второй - происходит или нет?

Моя программа работает полностью в длл (мож, кто знает) smile
т.е. загружает ее другой проц (LoadLibrary) и выходит.

в ДЛЛ при инициализации стоит SetHook.
При закрытии каждой программы (например блокнота) вызывается DLL_PROCESS_DETACH
В идеале я бы сделал по этому событию UnHook, но в таком случае придется закрывать все окна, к которым присоединился хук фактически,
а это нереально.


Цитата(Riply @  26.6.2008,  12:03 Найти цитируемый пост)
Делаем невозможной продгрузку Dll-ки новыми процессами (зависит от способа, которым ты подгружал)

хук, как я понимаю, подгружается автоматически

Цитата(Riply @  26.6.2008,  12:03 Найти цитируемый пост)
Сообщаем уже подгруженным, что пора закругляться.

хмм... это как?
PM MAIL ICQ   Вверх
bartram
Дата 26.6.2008, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1606
Регистрация: 22.2.2004
Где: Russia, Samara

Репутация: 3
Всего: 29



Цитата(Domoffou @  26.6.2008,  15:19 Найти цитируемый пост)
В идеале я бы сделал по этому событию UnHook, но в таком случае придется закрывать все окна, к которым присоединился хук фактически,
а это нереально.

Делай Unhook при выгрузке какого-нибудь системного процесса например Explorer.exe. Если Explorer выгрузился, значит винда завершает работу, а значит снимаем хук smile


--------------------
В каждом из нас спит гений, но с каждым днем все крепче ;-)
bartram.ru
Twitter
user posted image 

PM MAIL ICQ   Вверх
Riply
Дата 26.6.2008, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Комодератор
Сообщений: 572
Регистрация: 27.3.2007
Где: St. Petersburg

Репутация: 21
Всего: 32



Цитата(Domoffou @  26.6.2008,  13:19 Найти цитируемый пост)
В идеале я бы сделал по этому событию UnHook, но в таком случае придется закрывать все окна, к которым присоединился хук фактически,
а это нереально.


А зачем закрывать все окна ? Ты что там (в процессах) дополнительно делаешь что-то необратимое ?
Если так, то меняй идеологию.

Цитата(Domoffou @  26.6.2008,  13:19 Найти цитируемый пост)
Цитата(Riply @  26.6.2008,  12:03 )
Сообщаем уже подгруженным, что пора закругляться.

хмм... это как? 


Ты же сам сказал:
Цитата(Domoffou @  26.6.2008,  00:07 Найти цитируемый пост)
возможно обмен данными между "чужим" процессом (апдейтером) и местной длл


а теперь спрашиваешь "как" ?

PM MAIL   Вверх
Domoffou
Дата 26.6.2008, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 60
Регистрация: 22.6.2008
Где: Северная Венеция

Репутация: нет
Всего: нет



Приведу код.
DLL:
Код

// При загрузке DLL (инициализации)
begin
SetHook;
end;


Программа, загружающая длл:
Код

procedure TForm1.Button1Click(Sender: TObject);
Begin
{Загрузка библиотеки}
 H:=LoadLibrary('bugaga.dll');
end;


Цитата(bartram @  26.6.2008,  14:34 Найти цитируемый пост)
Делай Unhook при выгрузке какого-нибудь системного процесса например Explorer.exe. Если Explorer выгрузился, значит винда завершает работу, а значит снимаем хук

Хорошая идея, будет полезна при сохранении данных при перезагрузке или выключении ПК. Каким образом следить? Пробегать по списку процессов?

Цитата(Riply @  26.6.2008,  14:55 Найти цитируемый пост)
А зачем закрывать все окна ? Ты что там (в процессах) дополнительно делаешь что-то необратимое ?

Нет, процедура хука простая - принимает клавишу и записываем его в файл (для теста).

Ну совсем не догоняю как это реализовать smile
пробовал так в программе (уже другой):
Код

procedure TForm1.Button2Click(Sender: TObject);
begin
FreeLibraryAndExitThread(H,exitCode);
//FreeLibrary(h);
end;

программа завершается а логи продолжаются делать.

P.S. Секцию DLLProc пока не подключал. Нужно ли?

Это сообщение отредактировал(а) Domoffou - 26.6.2008, 15:06
PM MAIL ICQ   Вверх
bartram
Дата 26.6.2008, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1606
Регистрация: 22.2.2004
Где: Russia, Samara

Репутация: 3
Всего: 29



Цитата(Domoffou @  26.6.2008,  17:05 Найти цитируемый пост)
Хорошая идея, будет полезна при сохранении данных при перезагрузке или выключении ПК. Каким образом следить? Пробегать по списку процессов?

Нет,  в событии DLL_PROCESS_DETACH смотрим к какому процессу прицеплены, если это Explorer то снимаем хук.


Это сообщение отредактировал(а) bartram - 26.6.2008, 16:09


--------------------
В каждом из нас спит гений, но с каждым днем все крепче ;-)
bartram.ru
Twitter
user posted image 

PM MAIL ICQ   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.1389 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.