Всем доброго времени суток. Собственно в чем вопрос. После инжекта dll (1.dll) в процесс, от DLL_ATTACH создается тред и крутится в процесе до потери пульса. На DLL_PROCESSDETACH ничего не стоит. Задача - грамотно завершить созданный им тред и выгрузить этот dll(1.dll) из процесса. Я пока вижу 2 варианта: 1) Может как-нибудь попытаться сделать CreateRemoteThread со стартом в FreeLibrary для нужного процесса? 2) На мой взгляд - проще всего инжектировать в этото процесс еще один dll (2.dll), и в нем вызвать FreeLibrary (1.dll). Вобоих случаях стоит проблема: выгрузится ли этот dll (1.dll) пока работает один из созданных в нем тредов??? Если нет - то как его убить? Можно ли узнать АйДи треда, зная только имя модуля, в коде которого он создался? Я пока нуб в этом деле, так что буду рад любой информации.
Ну да. Просто добавь в нее код для создания треада который через допустив определенное время выгрузит длл, и завершиться сам.
если ты выгрузишь длл в которой работает тред - получишь AV сделай евент и проверяй его иногда когда евент встанет - freelibraryandexitthread (как-то так называется)
сам инжект это размещение в АП чужого процесса кода и запуск его, инжектировать dll понимается как инжект кода торый подгрузит нужную либу зачем тебе подгружать ещё одну либу? просто инжекти код который выгрузит твою
Спасибо всем за помощь. Про инжект - понял. Проблема в том, что я не могу изменять код загруженной в АП dll (1.dll). Она просто есть, и она запустила тред, который не останавливается сам ни при каких обстоятельствах. Нужно прибить тред и выгрузить dll из АП процесса. Основная проблема для меня - найти этот тред. Через ToolHelp32 я могу перечислить все треды. Кроме того, я могу найти базу этой dll (1.dll). А как по этим данным, определить, какой тред сейчас вертится в коде этой DLL?
GetThreadContext. Народ из какой-то структуры ведь можно вытащить адрес, откуда поток стартовал. Или это у меня глюки?
Точно можно, в Olly, например, когда треды смотришь - он показывает параметр Entry. Но как - хз. Смешно: открыл один отладчик из другого, ставлю бряки))
invoke ZwQueryInformationThread,hThread,9,offset ThreadStart,4,0 mov eax,ThreadStart 9 - ThreadQuerysetWin32StartAddress правда у Неббета есть приписка, что работает не всегда.
Span на худой конец сохраняй все ид трэдов до того как подгрузил длл а потом убивай всех кто не в этом списке, но это конечно гимморно, потому что если трэд стартовал не из этой дллки, но после того как ты сохранил трэды, он будет убит можешь ещё извратиться перехватывая CreateThread и проверяя входящий адрес, принадлежит ли он нужной дллке, и если принадлежит то заносить его в кандидаты на убийство перед выгрузкой длл но как-то это гимморно... а почему не написано?
Да, сохранять все АйДи тредов - хорошая мысль, по крайней мере так точно будет стабильно работать. Но, как я уже говорил, я не могу менять код уже загруженной в АП процесса dll. Решил поступить следующим образом: Знаю, что эта dll постоянно использует одну ф-ю (func) стандартной библиотеки. Вызывает она ее неявно. Посему решил в таблице импорта перезаписать адрес точки входа в эту ф-ю (func) на ExitThread() из Kernel32. По идее, отлавливаемый мною тред должен туда обязательно попасть, т.к. func вызывается каждую секунду. Тут, правда еще пара проблем) 1) В стеке будут параметры для вызова ф-и func (там их довольно много). А для ExitThread нужен только один параметр. Но, думаю, здесь ничего страшного нет, т.к. завершаем мы последений тред модуля, а потом вообще выгружаем его из АП. 2) WriteProcessMemory ругается при перезаписи таблицы импорта. Не пойму почему. GetLastError содержит // MessageId: ERROR_NOACCESS // MessageText: // Invalid access to memory location. О каких правах тут вообще идет речь, если я из одного модуля пытаюсь перезаписать память другого?? Не пойму никак. И как дать этот доступ? В отладчике проверял WriteProcessMemory вызывается как надо, все параметры верные. Подскажите плз.
В принципе ничего страшного произойти не должно. В крайнем случае ставь свою заглушку. Не должна, там права на запись должны быть. Если нет- то VirtualProtectEx тебе поможет. Только вот подумай, что будет, если другой поток решит вызвать эту функцию. Дык 2.dll инжектится после 1.dll и как я понимаю к этому моменту поток уже запущен.
А что может произойти?? Я меняю раздел импорта конкретному модулю, больше ведь этот раздел импорта никто не использует. Если какой-нибудь поток станет вызывать эту ф-ю, он будет пользоваться разделом импорта модуля, из которого был стартован. А его и не трогаю. Ну, или вызовет GetProcAddress (либо ниже). За VirtualProtectEx - спасибо, буду пробовать.
А если какой-нибудь поток вызывает другую функцию из этого модуля, которая в свою очередь вызывает эту функцию? Используй GetThreadContext или ZwQueryInformationThread и не парься.