Форум: "WinAPI";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];
ВнизПобочный эффект от перехвата API-вызова Найти похожие ветки
← →
evvcom (2004-03-04 11:43) [0]Здравствуйте, уважаемые Мастера!
Столкнулся со следующей проблемой. Есть приложение-клиент, которое умеет подгружать пользовательские dll, написанные в особом формате, грубо говоря плагины. Это приложение также запускает еще пару серверов, которые умеют нужные клиенту данные получать извне и сохранять в файлах. Клиент обменивается данными со своими серверами через FileMapping, доступ к которым защищается через Mutex, и извещают друг друга клиент и сервер через пару Event"s. Мне надо внутри своей dll вклиниться в их протокол, чтобы определить хэндлы объектов, потом обработать нужным образом данные и передавать клиенту свои данные. Я перехватил нужные API вызовы в самом exe, а также в mfc42.dll подменой адресов в таблицах импорта (этого мне достаточно), читаю их протокол и т.д. После закрытия приложения, чтобы exe и mfc42 не обращались по адресам моей dll, которая выгружается раньше, я возвращаю первоначальные значения вызовов в таблицах импорта, но этого оказывается недостаточно! Дело в том, что приложение использует вызовы в таком виде:
// этот код выполняется в дополнительном потоке
mov ebx, ds:ResetEvent
...
// где-то здесь основной поток выгружает мою dll
...
call ebx ; ResetEvent // естественно Access violation
Первая мысль приходит, что надо бы дождаться окончания работы всех дополнительных потоков, ну скажем, которые были созданы после загрузки моей dll, отслеживая dll_Thread_Attach и dll_Thread_Detach. Каким образом? Опять же приходит в голову пока только WaitForMultipleObjects. Но что-то меня здесь смущает. Загрузка и выгрузка моей dll происходит, как я понимаю, скорее всего в главном потоке, хотя вроде это и не столь важно. Если я его сейчас тормозну, то он перестанет естественно предпринимать какие-либо попытки по завершению дополнительных потоков. Сделал самую простую проверку: сразу после обратной замены адресов в таблицах импорта поставил Sleep(5000) - ну должно же хватить 5 секунд - но не помогло. Вот и ломаю голову, что же здесь могло бы помочь.
Может кто уже сталкивался с подобной проблемой? Есть у кого какие соображения по этому поводу?
← →
Digitman © (2004-03-04 12:52) [1]
> После закрытия приложения, чтобы exe и mfc42 не обращались
> по адресам моей dll, которая выгружается раньше
о каком обращении к ДАННОМУ экз-ру DLL может идти речь ПОСЛЕ завершения процесса приложения ? Процесс ведь уже завершился ?
Касаемо же перехвата, наиболее корректные точки для установки/снятия перехвата - это обработчики DLL_PROCESS_ATTACH/DETACH
← →
evvcom (2004-03-04 14:38) [2]Прошу прощения. Не "После закрытия приложения", а после нажатия на кнопку "закрыть приложение" или выбора пункта меню "Exit" и т.д. и т.п. Поэтому процесс еще не завершился, а находится на стадии завершения работы и выгрузки библиотек dll.
Касаемо точек перехвата. Где я устанавливаю перехват меня устраивает, а снимаю в finalization того unit, в котором все это происходит, чтобы не писать код снятия перехвата в каждой dll, в которой я буду это использовать. Причем в finalization мы попадаем позже, чем в DLL_PROCESS_DETACH, и даже в этом случае дополнительные потоки еще не завершились и продолжают вызывать перехваченные мною API-функции указанным выше способом.
← →
Digitman © (2004-03-04 15:00) [3]
> // где-то здесь основной поток выгружает мою dll
а зачем вообще осн.потоку выгружать твою DLL динамически ?
по завершению процесса в целом (т.е. когда все доп.потоки уже териминированы) в ходе ExitProcess() система сама выгрузит твою DLL, при этом код ее финализации получит управление именно в осн.код.потоке
← →
evvcom (2004-03-04 20:43) [4]
> а зачем вообще осн.потоку выгружать твою DLL динамически?
А я почём знаю?
Если приложение динамически загружает мою dll, то почему бы ему точно также динамически его не выгрузить? Да и какая разница кто выгружает мою dll, код приложения или автоматом система? Я предельно ясно задал вопрос, в одном месте допустил ошибку, хотя даже по смыслу можно было догадаться, что я имел ввиду, а Вы, уважаемый Digitman, имеющий голубенький копирайт, начали глумиться над описками и прочей мелочью. Раньше я был о Вас более высокого мнения. Если Вам нечего сказать, то лучше помолчите.
← →
evvcom (2004-03-04 22:28) [5]Хотя разница в том, кто выгружает мою dll, есть. Подозреваю, что это приложение и выгружает. Попробую перехватить FreeLibrary и проигнорировать попытку выгрузки моей dll. А там посмотрим.
← →
evvcom (2004-03-05 00:41) [6]Действительно, все получилось. Это, если кому будет вдруг интересно. Приложение динамически мою dll загружает и потом выгружает. Я перехватил выгрузку, проверил, а не меня ли выгружать собрались? Не дал выгрузить себя приложению, даже снятие перехватов убрал, как не нужный никому код. И это не навлекло никаких ошибок. Остался доволен.
Спасибо за внимание.
← →
Digitman © (2004-03-05 08:35) [7]
> Остался доволен
А я таковым не остался.
Вместо этого остались неприятные впечатления от общения с человеком. которому я искренне желал помочь в решении вовсе не тривиальной задачи. В ответ же получил незаслуженный упрек в якобы "глумлении".
> Я предельно ясно задал вопрос, в одном месте допустил ошибку,
> хотя даже по смыслу можно было догадаться, что я имел ввиду
Замечу - ошибку, не позволяющую сразу точно определить характер проблемы. Я не телепат и не намерен заниматься здесь "догадками".
← →
BiN © (2004-03-05 10:50) [8]evvcom (05.03.04 00:41) [6]
Я перехватил выгрузку, проверил, а не меня ли выгружать собрались? Не дал выгрузить себя приложению...
Что за выкрутасы! Единственно правлильный ответ Digitman тебе уже дал еще в самом начале (Digitman © (04.03.04 12:52) [1])
оффтоп:
имхо часто резкий в высказываниях Digitman в этот раз был предельно тактичен. "Глумление" - необоснованное обвинение.
← →
evvcom (2004-03-05 12:45) [9]
> А я таковым не остался.
> Вместо этого остались неприятные впечатления от общения
> с человеком. которому я искренне желал помочь в решении
> вовсе не тривиальной задачи. В ответ же получил незаслуженный
> упрек в якобы "глумлении".
Прошу прощения, если я не разглядел искренности. Но в общем что-то из нашего диалога натолкнуло меня на решение. Спасибо, и еще раз мои извинения.
> Что за выкрутасы! Единственно правлильный ответ Digitman
> тебе уже дал еще в самом начале (Digitman © (04.03.04
> 12:52) [1])
Ну почему же выкрутасы? Я могу поянить, что происходит на самом деле в моем случае, а что хотите Вы сказать своим заявлением? А в [1] еще не было и намека на правильное решение, я почти так и делал. Намек появился только в [3]. Будете спорить?
← →
BiN © (2004-03-05 13:07) [10]evvcom (05.03.04 12:45) [9]
Прошу прощения за "выкрутасы", не вник до конца в суть вопроса.
Если я правильно понял, ты хочешь сказать, что приложение определяет твою внедренную Dll, как чужеродную и избавляется от нее?
← →
evvcom (2004-03-05 14:03) [11]
> приложение определяет твою внедренную Dll, как чужеродную
> и избавляется от нее?
Оно не определяет, оно это знает. Само же это приложение мою dll грузит из специальной папки, предназначенной именно для этого, а потом естественно и выгружает.
← →
BiN © (2004-03-05 14:14) [12]evvcom (05.03.04 14:03) [11]
Просто обычно плагины не перехватывают API-вызовы в приложении, а выполняют формализованные задачи. Не лучше ли внедрять длл? - в этом случае больше вероятности, что приложение не выгрузит твою библиотеку динамически.
← →
evvcom (2004-03-05 19:50) [13]
> Не лучше ли внедрять длл? - в этом случае больше вероятности,
> что приложение не выгрузит твою библиотеку динамически.
А зачем ее внедрять, если она предназначена для нее(его, приложения, сорри, уже пьяный, 8-е марта, девчонок поздравляем)? А мне всё равно приходится что-то внедрять? Зачем выполнять непредвиденные действия, если оно... всё... что-то хотел сказать, ... уже пьяный... Надеюсь все поняли...
Страницы: 1 вся ветка
Форум: "WinAPI";
Текущий архив: 2004.05.02;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.037 c