Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.01.23;
Скачать: [xml.tar.bz2];

Вниз

Dll в памяти.   Найти похожие ветки 

 
Evgeniy_K   (2003-12-28 11:29) [0]

Как найти в памяти dll и выгрузить ее. Известно только имя файла dll.


 
Opuhshii   (2003-12-28 12:41) [1]

см. toolhelp32, + ProcessTerminate или FreeLibrary и CreateRemoteThread,

да кстати, в чьей памяти?


 
Evgeniy_K   (2003-12-29 11:04) [2]

В памяти Windows. Задача такова: есть приложение, оно завесилось, нужно выгрузить из памяти dll, которую оно использует, чтобы можно было перезапустить приложение.


 
Digitman   (2003-12-29 11:42) [3]


> чтобы можно было перезапустить приложение


.. нужно просто его "перезапустить" и не выкрутасничать с тем, о чем ты имеешь слабое теоретическое представление

аварийное снятие "зависшего" процесса с выполнения - см. TerminateProcess()
при этом заботиться о "выгрузке" модулей , используемых ДАННЫМ процессом, не нужно - система сама это сделает не хуже (и корректней) тебя


 
Evgeniy_K   (2003-12-29 13:12) [4]

Если бы всегда срабатывало бы, то не спрашивал бы!


 
Digitman   (2003-12-29 13:23) [5]


> Если бы всегда срабатывало бы


а что, собственно, не "срабатывает" ? TerminateProcess() ?


 
Digitman   (2003-12-29 13:27) [6]

прямо-таки расчудесное объяснение проблемы : я ,мол, сел за руль автомобиля, а он не едет почему-то ! Не срабатывает ! А, мол, еслт ли у меня в баке бензин и ли еще чего-нть у меня в машине нет - догадайтесь, мол, сами ! Не царское эт дело - объяснять еще всяким , чего тут у меня "не срабатывает" и какого хрена при наличии машины я никуда не еду на ней)


 
Evgeniy_K   (2003-12-29 15:40) [7]

Конкретный вопрос поставлен в теме ветки.


 
Digitman   (2003-12-29 15:55) [8]


> Конкретный вопрос поставлен в теме ветки


в "конкретном" вопросе - не менее "конкретное" непонимание механизмов работы PE-загрузчика Win32, и на таком уровне ответ на вопрос один : никак.

решение будет подсказано ТОЛЬКО при ответе на [5]


 
YuRock   (2003-12-29 16:45) [9]

> В памяти Windows
???

Тяжело понять вопрос... Но может поможет это:


FreeLibrary(GetModuleHandle("<имя длл>"));


 
Digitman   (2003-12-29 17:25) [10]


> YuRock


Юрок, тебе тоже не жалко ящика шнапса ?)


 
YuRock   (2003-12-29 17:30) [11]

> Digitman

:)) МИНЗДРАВ предупреждает...


 
Digitman   (2003-12-29 18:13) [12]


> МИНЗДРАВ предупреждает...


эт точно) ... предупреждает : не несите чепухи) ... и не прыгайте с бубном, если не знаете для чего и когда нужен бубен)


 
YuRock   (2003-12-29 18:41) [13]

>не несите чепухи) ... и не прыгайте с бубном, если не знаете для чего и когда нужен бубен)

О... Щас нам великий Delphi-мастер прочитает познавательную мораль...
Есть одна истина: "Свое мнение не всегда правильно". Так что не следует навязывать его другим


 
Woodpecker   (2003-12-29 18:49) [14]

2 YuRock
Прежде чем пустозвонить Рихтера почитал бы или что-нить в ентом роде.


 
Digitman   (2003-12-29 18:50) [15]


> [13]


на редкость серьезная заява !)
приятно и чрезвычайно полезно-познавательно было бы послушать аргументы в пользу оной)


 
YuRock   (2003-12-29 18:51) [16]

(Стараясь никого не обидеть): мне кажется, форумы нужны для того, чтобы отвечать на поставленные вопросы, а не читать морали.

Вопрос: "Как найти в памяти dll и выгрузить ее. Известно только имя файла dll."
Ответ: "FreeLibrary(GetModuleHandle("<имя длл>"))"


 
Digitman   (2003-12-29 18:53) [17]

да Рихтер нам не указ ! Как известно)..
Мы его - хрясь ! - и by FreeLibrary() call "выгрузили", их хрен знает какой "памяти") .. коль завис он тут со своими "умными" мыслями на несколько сотен страниц текста, которые нам читать не к чему и недосуг)


 
YuRock   (2003-12-29 18:54) [18]

> [16] Другое дело, что это не поможет закрыть dll для ругих процессов, но каков вопрос, таков и ответ


 
Digitman   (2003-12-29 18:55) [19]


> YuRock © (29.12.03 18:51) [16]


ну так и где ж ты ее, сударь, ищешь ?) DLL-то ? в своем Freelibrary() ?
и в какой такой, пардон за назойливость, "памяти" ?


 
YuRock   (2003-12-29 19:02) [20]

Глубокоуважаемый господин Сергей Digitman, я не хочу с вами спорить (тем более, что мы оба знаем, что Вы правы), я просто хотел бы еще раз подчеркнуть, что нужно стараться помочь спрашивающему, а не стараться показать ему и отвечающим на его вопрос (в том числе и мне) их незнание предметной области.
Тем более это обидно, когда не обосновано.


 
Evgeniy_K   (2003-12-30 08:00) [21]

Полностью знает Виндоус только Майкрософт. Так что твой механизм может быть всего лишь иллюзия ;-)

Проблема такова:
Приложение вылетело, но dll в памяти осталась. Приложение в памяти нет. Перезапустить прилождение не удается, потому что dll уже загружена и завешена в памяти. Такое редко, но бывает!


 
Digitman   (2003-12-30 08:41) [22]


> Приложение вылетело


КУДА "вылетело" ? ЧТО значит "вылетело" ? Процесс снят с выполнения или не снят ?


> dll в памяти осталась


Если процесс уже не существует, тот никаких модулей в его ВАП нет, ибо нет самого ВАП


> Перезапустить прилождение не удается


Симптомы ? Сообщения какие ? ЧТО система говорит в ответ на попытку ?


> dll уже загружена и завешена в памяти


модуль НЕЛЬЗЯ завершить ! это - нонсенс
ЭКЗЕМПЛЯР библиотеки в виде программного модуля либо отображен на ВАП процесса либо не отображен. третьего не дано.


 
KosilkA   (2003-12-30 10:35) [23]

а если dll внедрена в ВАП сторонннего процесса ,например эксплорера , по принципу вируса? как такое прибить , кстати?


 
YuRock   (2003-12-30 10:41) [24]

Такое бывает, если библиотеку использует еще один процесс. Если нет - винда выгружает ее из памяти.

> Digitman © К стати говоря, если уж совсем по-научному, то библиотека грузится только раз (при первом LoadLibrary()), а при следующих только возвращается ее готовый хендл (даже если грузить из другого процесса).
И этому есть логичное объяснение: хендл библиотеки - это ни что иное, как указатель на структуру заголовка библиотеки, и нет никакой необходимости делать новый экземпляр этой структуры.

В данном случае может быть две причины - либо текущий процесс не завершен, либо dll используется другими программами


 
Digitman   (2003-12-30 11:10) [25]


> если уж совсем по-научному


ну давай "по-научному", коль настаиваешь)


> библиотека грузится только раз


"грузится" она столько раз, сколько процессов хотя бы однократно затребовали ее загрузку


> при следующих только возвращается ее готовый хендл (даже
> если грузить из другого процесса).


это как ?) загрузка осуществляется в контексте конкретного код.потока конретного процесса ! как ты себе это представляешь - "грузить из другого процесса" ? ерунда же полная !


> хендл библиотеки - это ни что иное, как указатель на структуру
> заголовка библиотеки


хэндл PE-модуля имеет смысл для конкретного процесса, ибо это, в первую очередь, loaded image base address, который в разных процессах вполне может быть разным.


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


в контексте ДАННОГО рассматриваемого процесса - да, необходимости нет

в контекстах БОЛЕЕ чем одного процессов системой будет создано столько экз-ров, сколько процессов затребовали загрузку модуля


> либо текущий процесс не завершен


автора утверждает якобы иное - "Приложение вылетело.. Приложение в памяти нет"


> либо dll используется другими программами


да ну и на здоровье ! пусть используется ! как это может помешать старту еще одного процесса, использующего этот модуль ? в дан.случае - повторному старту процесса авторского приложения ?

вот это мне совершенно непонятно) .. ибо автор никак не хочет (или не в состоянии) вразумительно объяснить, что мешает повторному старту процесса ...
да мало ли какие другие процессы используют в этот момент этот модуль ! как это влияет на ДАННЫЙ процесс ? чем это он так уж радикально отличается от других процессов ? совершенно неясно) ...


 
Digitman   (2003-12-30 11:14) [26]

резюме всего этого просто как лапоть : для того ПРИНУДИТЕЛЬНО "освободить" файл PE-модуля, необходимо тем или иным образом терминировать все процессы, использующие в данный момент этот PE-модуль


 
Digitman   (2003-12-30 11:36) [27]

поэтому оригинальный вопрос


> Как найти в памяти dll и выгрузить ее


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

если текущего, то - полный нонсенс : текущего либо уже нет (он "вылетел" куда-то) либо он "висит" (в первом приближении так скажем)

если иного, то собственно поиск модулей не составляет труда - на то есть хотя бы штатный psapi.. а вот выгрузка - это (FreeLibrary) должен сделать каждый код.поток локализованного процесса, который ранее сделал LoadLibrary()


 
YuRock   (2003-12-30 11:37) [28]

> Digitman ©
> "грузится" она столько раз, сколько процессов хотя бы однократно затребовали ее загрузку

Не совсем правда. Когда первый процесс первый раз загружает dll, система грузит ее "с нуля", полностью считывая ее заголовок в созданный для этого экземпляр структуры (не помню, как называется). При последующем же вызове LoadLibrary(), система лишь возвращает указатель на этот экземпляр этой структуры. Это легко посмотреть на примере:

program Test;
uses Windows, Dialogs, SysUtils;
begin
ShowMessage(IntToStr(LoadLibrary("kernel32.dll")));
end.

Запуская несколько раз такую программу, можно заметить: хендл библиотеки будет одним и тем же - что это, совпадение? Нет! Просто он лежит вне адресного пространства приложения.

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


> грузить из другого процесса

Я имел в виду повторно (наприме, в другом процессе вызвать LoadLibrary)


 
Digitman   (2003-12-30 11:42) [29]

к тому же если UsageCount модуля некоего процесса = -1 (это значение соответствует факту стат.загрузки модуля на этапе старта и иниц-ции процесса, осн.модуль которого статически импортирует ф-ции интересующего модуля), то никакие FreeLibrary в контекстах его код.потоков не смогут "выгрузить" модуль из ВАП данного процесса - модуль будет "выгружен" ТОЛЬКО по факту штатного (ExitProcess) либо аварийного (внутренняяя GPF или внешний вызов Terminateprocess) снятия процесса с выполнения


 
Digitman   (2003-12-30 11:44) [30]


> Просто он лежит вне адресного пространства приложения.


чушь несусветная
читай хотя бы Рихтера)


 
YuRock   (2003-12-30 11:47) [31]

Я не знаю, кто такой Рихтер и что он писал, но хотябы читай то, на что отвечаешь. Ты хоть понял, что я написал?


 
Digitman   (2003-12-30 12:00) [32]


> YuRock


экз-ров секций данных модуля столько, сколько процессов хотя бы однократно вызвали LoadLibrary()

экз-р секции кода модуля по началу единственный (по кр.мере - в физ.памяти), но до момента первого обращения к страницам секции по записи (если таковую разрешить, по умолчанию - запрещена) ... далее же поведение разных систем разное : NT-based системы устанавливают атрибут страниц кода как COPY_ON_WRITE, и попытка записи в некую кодовую страницу модуля приводит к немедленной создании копии страницы; Win9x-based системы отражают изменения кодовой страницы модуля для всех процессов, в ВАП которых секция кода модуля отображена (т.е. единственный , разделяемый между всеми процессами, экз-р кода модуля)

НО ! секции данных PE-модуля всегда по умолчанию мультиэкземплярны в рамках системы и заинтересованных в использовании модуля процессов ... стандартный линкер от Borland Delphi не позволяет управлять изменением соотв.флагов секции данных создаваемого им PE-модуля


 
YuRock   (2003-12-30 12:03) [33]

> то никакие FreeLibrary в контекстах его код.потоков не смогут "выгрузить"...
Естественно, винда за этим следит. Так же она следит за тем, чтобы FreeLibrary не закрыла библиотеку, если она еще используется другими процессами (в этом случае она просто освобождает информацию о библиотеке в данном процессе об этой dll, и то не всегда - как в предложенном примере).

На счет Рихтера и прочих: на чтение подобных книг у меня нет времени. Изучаю Windows я в процессе работы, и все мои знания накописись на основе опыта (с помощью разных help"ов, предоставленных компанией Microsoft)


 
Digitman   (2003-12-30 12:06) [34]


> YuRock © (30.12.03 11:47) [31]


еще раз повторю, что утверждение


> Просто он лежит вне адресного пространства приложения


неверно ни терминологически ни концептуально, когда речь идет о вирьтуальном адресном пространстве конкретного процесса


 
Digitman   (2003-12-30 12:08) [35]


> на чтение подобных книг у меня нет времени


это заметно


 
YuRock   (2003-12-30 12:17) [36]

> Digitman ©:
"Программингом занимаюсь более 16 лет, из которых последние 7 - профессионально"

а я работаю, а не занимаюсь


 
Digitman   (2003-12-30 12:18) [37]


> Так же она следит за тем, чтобы FreeLibrary не закрыла библиотеку


да следит-следит)... вот только ты не следишь за тем, что я веду решь о стат. и дин. использовании модуля

в рамках тек.процесса, если его модули статически импортируют некий модуль A, то никакие Freelibrary() ни в каких код.потоках тек.процесса не заставят систему "выгрузить" модуль A из ВАП тек.процесса ... а прочие процессы здесь ни при чем - у них своя отдельная "песня" на ту же тему ...
иными словами, если некий PE-модуль, будучи импортированным статически, используется в дан.момент времени ТОЛЬКО ОДНИМ процессом, то освободить файл PE-модуля невозможно НИКАКИМИ документ.способами (ни FreeLibrary ни что-то иное) вплоть до завершения процесса (штатного или аварийного - без разницы)


 
YuRock   (2003-12-30 12:19) [38]

> вирьтуальном адресном пространстве конкретного процесса

При чем здесь конкретный процесс??? А, ладно, надоело...


 
Digitman   (2003-12-30 12:21) [39]


> YuRock


ладно, все ясно с тобой, сударь
засим ненамерен более продолжать с тобой бесплодную "научную" дискуссию - все твои аргументы сводятся к "что вижу, то пою"


 
YuRock   (2003-12-30 12:34) [40]

>Digitman ©

В таком случае твой "научный" стиль тоже хорош: "что читаю, то и пишу". Ну ладно, с наступающим тебя. И всех остальных.


 
Digitman   (2003-12-30 12:51) [41]


> Перезапустить прилождение не удается, потому что dll уже
> загружена и завешена в памяти


ты головой-то подумай своей)

надеюсь, для тебя не новость, что та же системная библ-ка kerne32.dll используется всеми прикладными Win32-процессами ?

так вот по твоей логике получается, что если самый первый процесс A стартовал и загрузил/использует kerne32, то никакой другой процесс стартовать не может, пока процесс A либо не завершится сам либо каким-то невероятным образом kernel32 не будет "освобождена")


 
Digitman   (2003-12-30 12:57) [42]


> YuRock © (30.12.03 12:34) [40]


угу ... с наступающим и тебя !

желаю тебе в НГ таки хоть что-нибудь почитать о механизмах организации страничной и виртуальной памяти процессов и о работе системного PE-загрузчика, дабы не нести чепухи и не давать заведомо несуразные/невыполнимые никоим образом советы


 
KosilkA   (2003-12-30 13:02) [43]

желаю всем на новый год хорошо погулять и отдохнуть, ни на секунду не задумываясь о проблемах динамических библиотек :-)


 
YuRock   (2003-12-30 13:26) [44]

>Digitman © [42]
Спасибо за пожелание - надеюсь, появится время.

А тебе я желаю вот чего: старайся понимать то, что тебе говорят, и если спорить, то по теме. Я например вообще речь не вел ни о сегменте кода, ни о сегменте данных модуля. Почти все, что ты говорил по этому поводу, не подлежит сомнению. Но ты так и не понял, что я говорю о заголовке модуля, который к тому, что ты говорил, не имеет никакого отношения, и указатель на него (хендл библиотеки) как раз всегда один.
Именно он и используется в начале загрузки кода, данных и всего прочего в какой-либо процесс, а про эти механизмы я и не собирался говорить (в этом я не специалист).

Ну я не хочу продолжать эту дискуссию.

Всего наилучшего.


 
alehan   (2003-12-30 14:00) [45]


> YuRock © (30.12.03 12:03) [33]

На счет Рихтера и прочих: на чтение подобных книг у меня нет времени. Изучаю Windows я в процессе работы, и все мои знания накописись на основе опыта (с помощью разных help"ов, предоставленных компанией Microsoft)

Чтение Рихтера как раз и нужно чтобы вместо накопившейся груды знаний в голове возникла чёткая стройная теория.

Без этого обсуждения типа

Вопрос: "Как найти в памяти dll и выгрузить ее. Известно только имя файла dll."
Ответ: "FreeLibrary(GetModuleHandle("<имя длл>"))"

оказываются лишены не только теоретического, но и практического смысла.


 
YuRock   (2003-12-30 14:18) [46]

> alehan ©
> в голове возникла чёткая стройная теория

Я практик (предпочитаю утверждать лишь проверенные мною факты). А на счет чтения книг (если ты недопонял) - то я ничего не имею против, просто нет времени.

> лишены не только теоретического, но и практического смысла
"FreeLibrary(GetModuleHandle("<имя длл>"))" закроет библиотеку в текущем процессе (если она в нем открывалась ч-з LoadLibrary()).

Так что практический смысл эта запись в принципе может иметь (если не знаешь хендла, а закрыть нужно).


 
alehan   (2003-12-30 14:46) [47]


> YuRock

Понятно :)

При случае непременно воспользуюсь твоим ценным советом )

Вообще бывают случаи, когда упавшее приложение не удаётся сразу опять запустить. Например, если оно юзает BDE, то упав при запущенных дельфях, оно не желает запускать повторно, жалуясь на недоступность каталога, содержащего файл PDOXUSRS.NET. Приходилось закрывать Дельфи. Сей феномен подробно исследовать мне было недосуг, повинны ли в том какие-либо dll или нет - не знаю.

Evgeniy_K к сожалению не уточнил своей ситуации, видимо разгоревшаяся между тобой и Сергеем Digitman дискуссия с применением высоконаучных терминов привела его (судя по всему тоже трудолюбивого практика) к мысле о том, что Рихтера почитать всё же было бы неплохо :)))


 
VMcL   (2003-12-30 15:41) [48]

>>YuRock © (30.12.03 14:18) [46]

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


 
YuRock   (2003-12-30 15:49) [49]

Если человек не может отличить документацию от книги (см. [33]) или он слепой (что для профессии "програмист" в принципе, одно и то же), а так же если человеку не хватает воспитания для того, чтобы уважительно относиться к людям (тем более, которых он не знает), то с таким "профессионалом" и разговаривать как-то не о чем...


 
Digitman   (2003-12-30 17:07) [50]

значение поля ImageBase некоего PE-модуля, отображенного на ВАП процесса А и значение поля ImageBase ТОГО ЖЕ (т.е. - одноименного, загружаемого из того же PE-файла) PE-модуля, отображенного на ВАП процесса В, не обязаны совпадать .. и этот факт ставит в тупик любого воинствующего дилетанта)


 
VMcL   (2003-12-30 17:23) [51]

YuRock © (30.12.03 15:49) [49]

Это тупой наезд.


 
YuRock   (2003-12-30 17:54) [52]

Хэндл библиотеки - это указатель на структуру типа IMAGE_DOS_HEADER, а не IMAGE_OPTIONAL_HEADER, о которой говоришь ты, который получается через

hModule + pDosHeader.e_lfanew + 2

(только в случае, если это PE, что тоже надо проверять).

И никакого отношения ImageBase не имеет к хендлу библиотеки. Не люблю никого оскорблять, но, вижу, наши мастера Delphi тоже не отличаются воспитанностью...


 
Digitman   (2003-12-30 18:33) [53]


> И никакого отношения


самое прямое)

значение ImageBase, прописанное в файле, есть значение базового адреса, ПРЕДПОЧТИТЕЛЬНОГО при загрузке образа модуля в ВАП процесса ... если система не имеет возможности загрузки модуля начиная с адреса, прописанного линкером в поле Imagebase PE-файла, система вправе загрузить образ PE-модуля по иному адресу. который с момента загрузки и становится реальным базовым адресом модуля в ВАП данного процесса... мы здесь не говорим о спец.опциях линкера, предписывающих ситс.загрузчику пытаться загружать образ по возмодности в верхние адреса ВАП

разумеется, поле Imagebase структуры IMAGE_OPTIONAL_HEADER после загрузки образа модуля остается неизменным ! Кто ж спорит !

но однотипное по смыслу поле run-time-структуры MODULE_INFO (неважно, как его обозвали - ImageBase или DLLBase) вовсе не обязательно содержит то же самое значение, что и IMAGE_OPTIONAL_HEADER.ImageBase ... собственно, cardinal-значение хэндла загруженного модуля и есть точная копия значения поля MODULE_INFO.DLLBase, но никак не копия значения IMAGE_OPTIONAL_HEADER.ImageBase

почему я обзываю поле MODULE_INFO.DLLBase именем "ImageBase" ? Да потому что оно некорректно по смыслу ! Образ любого модуля есть Image, но модуль совершенно необязательно есть DLL-модуль ! Осн.модуль (т.е. загруженный образ exe-файла) - это ТОЖЕ модуль ! такой же равноправный как и все прочие модули в ВАП процесса... поэтому поле DLLBase корректней было бы называть все же ModuleImageBase (или просто - ImageBase)... не путая при этом с полем IMAGE_OPTIONAL_HEADER.ImageBase


 
Digitman   (2003-12-30 18:37) [54]

отсюда - прямой ответ на вопрос : ЧТО реально возвращает в кач-ве рез-та ф-ция LoadLibrary() или GetModuleHandle() ..

а возвращают эти ф-ции значения полей MODULE_INFO.ImageBase , а не IMAGE_OPTIONAL_HEADER.ImageBase !!


 
Digitman   (2003-12-30 18:45) [55]

после загрузки (т.е. после того как PE-файл из просто некоего файла стал PE-модулем !! отсюда все недоразумения !) и последующей инициализации система вообще не обращается к структуре IMAGE_OPTIONAL_HEADER ... эта структура, пока процесс активен, более не нужна никому - ни системе ни программеру) ... разве что - из непонятного любопытства. которое вполне может быть удовлетворено и обычным чтением заголовка PE-файла и его анализом (т.е. ДО момента, когда он превратился в модуль некоего процесса)


 
YuRock   (2003-12-30 18:53) [56]

> значение хэндла загруженного модуля и есть точная копия значения поля MODULE_INFO.DLLBase, но никак не копия значения IMAGE_OPTIONAL_HEADER.ImageBase

Я что, спорю с этим? Мне не понятно, зачем сразу начинать ругаться.

Правда, я никогда не реботал (и не встречал) с MODULE_INFO.DLLBase (наверно это то же, что IMAGE_DOS_HEADER._lfanew - File address of new exe header), так как всегда начинал разбирать dll или exe со структуры IMAGE_DOS_HEADER, а из нее уже получал IMAGE_OPTIONAL_HEADER...

Неужели не понятно: всегда, когда я говорил о "заголовке модуля", я имел в виду именно эту структуру (IMAGE_DOS_HEADER или MODULE_INFO). Зачем ругаться не разобравшись? Ведь именно это и есть первоначальный заголовок модуля (или exe, или com)!


 
YuRock   (2003-12-30 19:01) [57]

> разве что - из непонятного любопытства
Почему из непонятного? Мне, например, неоднократно приходилось подменять функции (их адреса) в таблице адресов ф-ций модуля (в моем случае - экзешника) подключенной библиотеки на другие функции (очень удобное и красивое решение на низком уровне).
А это легко можно сделать, используя IMAGE_OPTIONAL_HEADER.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress


 
Evgeniy_K   (2003-12-30 20:12) [58]

Тогда как объяснить то, что после выгрузки из памяти моей программы ее dll иногда остается и, пока я ее не убью программой KillProcess, моя программа не запускается? Я надеялся что мне попомуг, а получаю пока какие-то упреки со стороны каких-то кодеров. Если ты конкретно не можешь ответить на поставленный вопрос, то зачем тогда выкручиваться? Спасибо за попытку мне помочь, но видно не судьба. Иди лучше Кнута почитай :-)


 
Evgeniy_K   (2003-12-30 20:23) [59]

Ладно, уточняю вопрос. Все-таки надеюсь, что кто-нибудь поможет.
Dll ставит хук на клавиатуру. Моя программа как раз вызывает функцию установки хука. Хук выставляется. Если происходит какой-либо левый сбой в моей программе и она вылетает, то хук не снимается и длл остается висеть в памяти. В связи с тем, что хэндл куда передаются коды клавиш не существует длл тоже завешивается, но это происходит уже после закрытия программы. Виндоус не убивает зависшую длл и она там остается. При новом запуске моей программы она пытается взаимодействовать с зависшей длл и из-за этого она просто зависает. Если я сворачиваю свою программу, то длл как замечено может выгрузиться, но не всегда. Почему это происходитя я не знаю Я не рихтовед. А даже если бы и был, то не хвастался бы на каждом шагу.

Так понятней?

PS Где взять хороший PEScaner?


 
YuRock   (2003-12-30 20:23) [60]

> Evgeniy_K (30.12.03 20:12) [58]
Извини, конечно, если это ко мне, но не мог бы ты поконкретнее рассказать, как ты "убиваешь ее программой KillProcess"? Ведь dll - это не процесс. А что за программа - KillProcess?
Я просто хочу тебе помочь, но не совсем понимаю, что ты делаешь...


 
YuRock   (2003-12-30 20:28) [61]

Evgeniy_K (30.12.03 20:23) [59]
Попробуй прибивать хук (UnhookWindowsHookEx) при выгрузке библиотеки (желательно - перед тем, как "хэндл куда передаются коды клавиш" перестает существовать)


 
jack128   (2003-12-30 21:18) [62]


> При новом запуске моей программы она пытается взаимодействовать
> с зависшей длл и из-за этого она просто зависает.

Применительно к EXE это выглядит, как если бы зависла моя программа, и из-за этого не могу запустить её новый экземпляр, что то здесь не состыкововается..

Учитывая

> В связи с тем, что хэндл куда передаются коды клавиш не
> существует длл тоже завешивается,

попробуй перед загрузкой DLL вызвать keybd_event..


 
Pat   (2003-12-30 21:32) [63]

>Если происходит какой-либо левый сбой в моей программе и она
>вылетает, то хук не снимается и длл остается висеть в памяти
Не волнуйся, система ее сама снимет.

Утилита Process Explorer от Sysinternals (www.sysinternals.com)


 
alexEagle   (2003-12-30 22:05) [64]

Digitman © (30.12.03 08:41) [22]
Если процесс уже не существует, тот никаких модулей в его ВАП нет, ибо нет самого ВАП

Уважаемый профи. Если вы действительно хорошо разбираетесь в программировании, а не только (по мнению модераторов) в делфи, то вы должны знать что Com может быть реализован в виде dll, которая не выгрузится из памяти до тех пор пока счетчик ссылок не обнулится (да и то при определенных обстоятельствах), а уж тем более при выгрузке одного из использующих его приложений из памяти.

И если это так, то тут поможет лишь знание COM (я сейчас не очень помню где можно управлять загрузкой ком-серверов)

И хотелось бы еще раз акцентировать ваше внимание на то, что в форуме надо давать конкретные ответы, а не разводить балаган.

Мне кажется что в этом случает, нужно было вначале ответить на поставленный вопрос, а затем объяснить когда описанная ситуация может иметь место


 
Digitman   (2003-12-31 08:37) [65]


> Evgeniy_K


вот теперь, когда ты упомянул про хук, все стало понятно и все встало на свои места.

стоило ли так долго "секретничать", что dll твоя реализует хук-модуль ?).. впрочем , я изначально подозревал, что следы ведуд к хукам)..

программа твоя запускается - это однозначно.
другой вопрос, что если запускается она из-под Делфи, то вполне возможно, что перед стартом хук-dll заново компилируется/строится, и если файл занят, то, разумеется, перезаписан он быть не может, и автостарт по F9 не выполняется

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

а дальше начинается самое интересное

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

есть еще один вариант со своей "тонкостью"

предположим, при первом старте ты успешно установил хук, поработал с ним и снял, уверовав в том, что снятие тобой хука привело к полной автовыгрузке экз-ров хук-модуля изо всех ВАП

но это может быть и не так !

некоторые GUI-процессы, "свернутые в трей", по причинам, о которых я сейчас не буду распространяться, не были включены системой в список процессов на выгрузку хук-модуля из их ВАП

вот они, эти процессы, и "мешают" тебе по всей видимости !

решение же простое как лапоть : сразу же после успешного UnhookWindowsHookEx следует выполнить SendMessage(HWND_BROADCAST, WM_NULL, 0, 0), и это даст ожидаемый результат - хук-модуль будет выгружен и из оставшихся процессов


 
Digitman   (2003-12-31 09:58) [66]

и последний важный момент, который вполне может решить задачу по "выгрузке" : если хэндл хука, полученного при предыдущей его установке известен (т.е. если были прияняты меры по его сохранению на момент установки хука в глоб.доступной памяти), то снятие хука с полсдедующей автовыгрузкой хук-модулей из ВАП всех GUI-процессов м.б. легко выполнен обычным UnhookWindowsHookEx, несмотря на то что это делается при повторном старте "вылетевшего" ранее хост-процесса


 
Digitman   (2003-12-31 10:26) [67]


> alexEagle


позволь мне, сударь, уж как-нибудь обойтись без твоих никчемных комментариев)

как только автор в [59] таки сподобился конкретизировать проблему, он тут же получил в [65], [66] наиболее вероятные способы ее обхода, ДАЖЕ без предоставления исх.текстов, что, впрочем, еще быстрей бы позволило проанализировать источник проблемы и найти ошибки и их устранение

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


 
Digitman   (2003-12-31 10:40) [68]


> PS Где взять хороший PEScaner?


для таких целей (т.е. целей отладочного исследования) вполне подойдет пример, приведенный в

http://delphimaster.net/view/7-1072779417/

этот код реализует доп.пункт контекстного меню оболочки, при выборе которого на выделенных, например, в Эксплорере файлах с расширениями exe, dll и bpl можно тут же быстро определить, какими процессами в системе в дан.момент используется указанный PE-файл


 
panov   (2003-12-31 13:43) [69]

Какая экспрессия, однако...
Извините за оффтопик, но знание не означает мудрости, а мудрость подразумевает оное.
Мудрость так же подразумевает понимание других.

Ошибки свойственны всем, надо уметь принимать свои ошибки без обид.

А унижать других ради собственного самомнения - как минимум непорядочно.


 
Digitman   (2003-12-31 14:20) [70]

Александр, удали-ка ты, коль можно, эту ветку на всяк случай) ... ну или в "Потрепаться" - тож вариант хороший) .. авось всем нам неповадно будет "мудрость" свою казать) .. оно так спокойней будет


 
Dolot   (2003-12-31 15:16) [71]

Digitman, действительно, умерь свой пыл. Ты, конечно, всем доказал, что ты супер крут. Только что из этого? Нашел себе забаву - с новичками силами тягаться... найди себе более мирное применение.

А то сквозь эту ветку так и проходит твое стремление доказать, что ты супер-пупер, хоть ты сейчас и будешь говорить обратное. Вообще, за тобой замечается в последнее время такое - вместо ответа ты пытаешься унизить человека, доказать ему, что он не достиг того уровня, чтобы задавать такие вопромы... неправильный подход какой-то


 
Германн   (2004-01-01 07:12) [72]

2 Dolot (31.12.03 15:16) [71]
Ну, во-первых, чтобы иметь право постить любые критические замечания в адрес Мастеров, правила простой этики И-нет форумов требуют некоей, авторизации. А вы даже не удосужились "зарегистрироваться" на форуме, где регистрация - чисто номинальная. Так о чем тут говорить? Любой модератор имеет полное право удалить ваш пост, даже без объяснений.

Во-вторых, действительно, почему-то, количество постов уважаемого Digitman в эти дни сильно превышает обычный уровень. Почему - знает только он.

Но, лично для меня, это - удача. Я получил и естесс-но сохранил для себя кучу примеров и советов дополняющих книги, в том числе и книгу Рихтера.

А вот людей, которые говорят, что не знают, кто такой Рихтер, и говорят, что у них нет времени читать книги, мне искренне жаль! Может им лучше последовать Остапу Бендеру и уйти в управдомы?


 
Evgeniy_K   (2004-01-01 10:10) [73]

KillProcess - программа, убивающая или размораживающая зависшие процессы в памяти и длл. Можно даже кернел убить.


 
Snap   (2004-01-02 18:37) [74]

>>длл. Можно даже кернел убить.

Какой кернел? kernel32.dll?

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

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


 
AllDer   (2004-01-04 02:08) [75]

может и может kernel32.dll убить
но только не в XP(если он есть)
а в 98 там и Explorer спокойно из Киллеров вырубается


 
X-MAN   (2004-01-04 02:09) [76]

FreeLibrary(GetModuleHandle("some.dll"));



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

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

Наверх





Память: 0.79 MB
Время: 0.008 c
1-72816
alexnmsk
2004-01-14 09:17
2004.01.23
Рисование на канве формы


3-72662
Skif
2003-12-25 19:02
2004.01.23
BDE+ODBC+MySQL - ошибка при выполнении запроса


1-72700
John S.
2004-01-14 12:55
2004.01.23
Sheduler


14-72930
Rouse_
2003-12-31 12:30
2004.01.23
Войнушка...


1-72795
www85
2004-01-13 09:10
2004.01.23
Как отпечатать?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский