Есть программа, она юзает длл "engine.dll". Эта длл юзает другие длл. Я написал программу, которая грузит "engine.dll" через LoadLibraryA, кое-то в ней ищет, затем выгружает "engine.dll" через FreeLibrary, ждет ввода пользователя и патчит эту длл. Через несколько секунд ожидания прога вылетает с ошибкой. Предположительно ошибка происходит потому что те, другие длл поставили какие-то перехваты в "engine.dll", и не выгрузились сами. Что делать?) "engine.dll" должна быть выгружена т.к. мне надо ее патчить. Пока я вижу только два решения: - первое, простое и плохое - выгрузить "engine.dll", и пропатчить ее пока прога не вылетела, и завершиться. Но это неуважение пользователю, и не факт что будет стабильно работать. - второе решение: загрузить "engine.dll" запустить копию себя, передав необходимую информацию через командную строку, и завершиться. во втором процессе уже не загружать длл. Хотелось бы более правильных решений.
GoldFinch Не совсем понял. Но возникло подозрение, что это Вы типа думаете, что LoadLibrary Вам ещё одну копию dll в АП процесса подгрузит. ЩАЗ.
GoldFinch "Есть программа, она юзает длл "engine.dll"" и "Я написал программу, которая грузит "engine.dll"" - это одна и та же программа? Если нет, то в чьё АП подгружает Ваша программа? "Через несколько секунд ожидания прога вылетает с ошибкой." Какая из? И через несколько секунд ожидания после чего? После поиска "кое-чего"? После ввода пользователя? После патчинга dll?
ок. попробую пропроще. есть программа с таким кодом (фасм+макросы): Код (Text): ... entry $ LoadLibraryA("engine.dll") FreeLibrary(eax) jmp $ ... (все проверки на ошибки удалил чтоб лучше читалось, апишки вызываются успешно) Если ее запустить и ничего не трогать она вылетает с ошибкой.
GoldFinch Вообще без самой engine.dll и её зависимостей трудно сказать. Попробую погадать на картах... Есть вероятность, что engine.dll создаёт поток и не заботится о нём в случае DLL_PROCESS_DETACH. Поэтому ИМХО лучшее решение - это подгружать dll через FileMapping, а не через LoadLibrary. P.S. Чуть не забыл: а отладчики на что?
Так.... engine.dll запакована фемидой. Я ее гружу - она распаковавается. Пока она распакована я ищу в ней нужные байты. Затем мне надо ее выгрузить и пропатчить на диске - прицепить к ней лодер который будет потом патчить эти байты. Все делается не под конкретную engine.dll а под любую ее версию, поэтому нужен поиск и генерация лодера.
GoldFinch Вам всё таки стоит разобраться с тем, от чего падает процесс (совет об отладчике из P.S. пятого поста). Если вариант с лишним потоком верен, то нужно проверить, достаточно ли распакована engine.dll к моменту создания потока. Если достаточно, то перехватывать создание потока, не давать создаться и в перехватчике искать данные, которые будут патчиться лоадером. Либо на крайний случай встроить поиск байтов в сам лоадер. Либо на самый крайний случай выложить сюда engine.dll со всеми зависимостями.
Со всем зависимостями там ~50Мб будет, кроме того как я уже говорил, работать надо не с конкретным файлом, а с одним из, т.е. известно только что в нем есть искомая последовательность байт. Я придумал более-менее нормальное решение - копировать ее в engine.bak, загружать engine.bak, а патчить engine.dll .
Или просто поиск делай в отдельном процессе, в котором дллка и будет загружаться, а в основном процессе тока патчи. Тогда особо много настроек не придётся передавать из процесса в процесс (хотя конечно зависит от механизма поиска).
Ну смотри у тебя есть основной процесс, П1. Из него ты стартуешь процесс П2. Процесс П2 загружает твою библиотеку, ищет в ней чего надо, и умирает, тем самым библиотеку по любому выгружая. Тогда уже процесс П1, получив из П2 информацию о том что было найдено, патчит библиотеку.\ (П1 никогда библиотеку не загружает).
mcbain Это в первом посте предложено. Вариант из восьмого поста ничего, но любопытства у GoldFinch видимо не хватило, чтобы разобраться, почему же падает после FreeLibrary.
Ну, это не совсем тоже самое. Он собирался запускать второй процесс и продолжать уже в нём, а первый убивать. У меня наоборот. Разница в том что скорее всего меньше информации придётся посылать между процессами, типа текущих настроек (но зависит от дизайна).
Еще как вариант перед загрузкой длл создать список из загруженых длл на текущий момент, после прогрузки engine.dll и шаманских действий над ней снова пройтись по всем загруженным длл и если их нет в сохраненном списке, то выгрузить и последним шагом выгрузить саму engine.dll Кстати вариант со вторым процессом можно сделать совсем простым, если использовать второй процесс как гейт. Например второй процесс грузит длл, сохраняет ее из памяти в engine.dmp и териматица, первый ждет появления файла и начинает с ним работать (файл это уже распакованая длл). Всё. Нет даже никакого общения между двумя процессами, реализовывается в течение 10 минут.