Есть DLL, которая подгружена в АП некотрых процессов Задача DLL - самообновится когда ей будет это указно, не прерывая выполнения процесса. И вот собственно возникшие вопросы: - можно ли это как-то сделать, т.е по сути выполнить свзяку FreeLibrary, LoadLibrary ? - будут ли очищены куски памяти выделенные в этой DLL после FreeLibrary или об этом нужно заботится самому ? - если запустить поток из этой DLL выполняющий шел код будет ли он во время FreeLibrary остановлен ? Подскажите пожалуйста методики обновления на лету. Возможно Вам встречались подобные ситуации или попадался похожий исходник. Спасибо!
lamer2k Непонятно ничего, можно поподробней. И так связано. Да память будет освобождена. Нет код упадёт. Если используется шелкод то зачем нужен модуль ?
Смотря что за ДЛЛ, статически подгружается или динамически, экспортирует ли что-нибудь. Если экспортирует, то в момент выгрузки в экспортируемых функциях могут находится другие потоки, хз учитывает ли это FreeLibrary, да и потом даже если ты подрузишь новую ДЛЛ, то она подгрузится с другой базой и адреса экспорта будут другие, и при попытке их вызвать из других потоков будет AV. Если ДЛЛ ничего не экспортирует, то другое дело. Это почему? Если память выделена к примеру с помощью VirtualAlloc, c какой стате она освободится? Также с другими ресурсами и открытыми хендлами. Все нужно освобождать/закрывать. Почему он упадет? ИМХО, будет себе дальше работать, пока не завершится.
lamer2k в принципе возможно. Для этого тебе достаточно будет 1. в АП нужного процесса выделить регион памяти через VirtualAlloc 2. Скопировать туда нужный шеллкод, который выгрузит твою дллку, заменит ее и опять загрузит. 3. Создать поток через CreateThread на твой шелкод либо грубо передать управление джампом Разумеется, перед выгрузкой длл желательно тормознуть потоки, проверить их контексты. Если какой-то из потоков находится внутри длл - возобновоить его и подождать , пока он не завершится либо пока EIP не будет ВНЕ твоего модуля. В этом тебе помогут функции ResumeThread SuspendThread GetThreadContext Sleep Если завершение потока не предусмотрено, а EIP потока по логике не должен покидать функцию (к примеру в цикле выполняется какая-то оконная процедура или выполняется цикл ожидания) - тогда поток прийдется остановить и завершить принудительно. НЕ БУДУТ Все хэндлы будут закрыты, а выделенные регионы памяти освобождены только после завершения процесса. Выгрузка модуля на это никак не повлияет Если шел-код находится внутри твоего модуля и поток не остановлен - вероятнее всего весь процесс упадет. Если вне модуля - ничего страшного не случится.
DLL функции не экспортирует Т.е как я понял для обновления нужно: 1) выделить память под шел код с помощью VirtualAlloc 2) освободить все занимаемые ресурсы 3) убедится что все потоки вне моей длл 4) создать поток CreateThread с точкой входа указывающий на мой шел код шел на подобии: Код (Text): push _hmodule_ call [FreeLibrary] jnz @ret push _path_ call [LoadLibrary] @ret: push 0 call [ExitThread]
MoveFileEx его можно перенести в другое место, и записать на его место обновленный либо указать другое имя для DLL
lamer2k Нет. Человек задал верный вопрос. Если ваш модуль подгружен в несколько процессов, а оно так и есть то модуль не может быть удален, перемещен и открыт на запись, пока он открыт или загружен хоть в один из процессов. Проще говоря, чтобы заменить модуль, сперва нужно дать комманду (через мутекс или евент), чтобы ВСЕ процессы, где модуль загружен - этот модуль выгрузили. Иначе замены не получится.
Clerk оффтоп: привайтный трой это, неужели не йасно? )) будет сидеть в резиденте и втихаря обновляться
Так этож надо в WASM.VIROLOGY или нет ? [OFFTOP] Часто на форумах вижу ники нуб, ламер, лох, неуч и т.д. Что заставляет людей так себя обзывать? [OFFTOP]
DLL можно спокойно переименовать или переместить независимо от того занята она или нет. Попробуйте проверить. У меня на win xp sp0-sp3 win vista такой фокус проходит.
2SloT а что заставляет флудить в 2 часа ночи на форуме это загадка для меня. никто не говорил что это приложение - вирус. точно так же могут работать и защиты р3
lamer2k специально проверил не работает До тех пор пока загружен модуль и выполняется текущий процесс - модуль не перемещается Как только завершается процесс - идет перемещение XP SP 3 x32
lamer2k Защиты так работать не могут. Пойми, этот способ предумал ты, никто не говорит что это нормально, наоборот, выгружать - изменять файл - загружать это ппц вобще. Я же спросил нормально что будет делать модуль, не просто так, а чтобы подумать над лучшим вариантом, а такой гуан как это обновление обсуждать нормально никто не будет.
Ну даже если так, никто не помешает изменить имя длл либо заменить длл в р0 Хотя щас еще погуглю по этому поводу. Мб невозможность переименования связана с ограниченной учетной записью...
Это безнадёжно, пойду кодить код, удачи изменить модуль, тока не забудь что на такие изменения АВ ругаются, кису потом надо успакаивать. Есть обьект 'секция', в таких случаях мы это юзаем.
Вот тут (http://forum.antichat.ru/threadnav43482-2-10.html) многоуважаемый Great писал о таком чуде как переименование занятого файла. В принципе вопрос решен. 2Clerk Ок. Как по вашему как нужно обновить юзермодную часть антивируса, если не хочется по пустякам просить ребутать пользователя. Только не говорите что АВ полностью можно исполнить в р0. т.к видно на примере и аутпоста и киса, что без юзермодного хелпера - нормальной, полнофункциональной работы нету.
Загрузчик пытается открыть 'KnownDlls' секцию с именем модуля, если её нет то он открывает файл через NtOpenFile, в этом сервисе есть параметр - ShareAccess, он и решает можно писать или удалить файл если он занят, в XPSP2 он имеет значение FILE_SHARE_READ or FILE_SHARE_DELETE, тоесть открытый занятый файл(именно модуль, юзермодный загрузчик!) можно читать и удалять. А вот если связать его с секцией которую спроецировать на запись в АП, записать в неё чтолибо и сохранить на диск посредством NtFlushVirtualMemory, то походу придётся обломаться - прав нет, хотя я не проверял, чисто теоритически. Насчёт обновления - я тчно не помню, но вроде можно создать в модуле секцию с определённым именем, и эта секция будет являться разделяемой для всех процессов в которые загружен этот модуль. Туда и вписать можно что угодно, без связывания с диском. Киса - это не ламерская программа. Да, есть модуль который она подгружает ко всем процессам, но если она его и обновляет то делает это после ребута. Своё тело выгружать - дурной тон программирования.