Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 01.12.20 09:29
Оценка:
Привет,
Есть известные способы, которые позволяют загружать dll из памяти, а не с диска, например:
https://github.com/fancycode/MemoryModule
Вместо LoadLibrary используется:
HMEMORYMODULE MemoryLoadLibrary(const void *, size_t);

Вместо GetProcAddress:
FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);

Обычные функции работы с ресурсами естественно не работают, поэтому например, вместо FindResource:
HMEMORYRSRC MemoryFindResource(HMEMORYMODULE, LPCTSTR, LPCTSTR);

и тд.
Если мы напрямую работаем с ресурсами, то всё OK, но если dll например отображает диалоговое окна:
HWND CreateDialog(HINSTANCE hInstance,
    LPCTSTR lpTemplate,
    HWND hWndParent,
    DLGPROC lpDialogFunc
);

то всё это уже не работает.
Что тут можно сделать? Ставить хуки на API работы с ресурсами, насколько это будет стабилно.
Интересно ещё то, что например, некоторые протекторы позволяют упаковывать dll в исполняемый файл. У них такие же ограничения?
Re: Загрузка DLL из памяти и диалоговые окна
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 01.12.20 09:44
Оценка: +1
Здравствуйте, edton, Вы писали:

E>Есть известные способы, которые позволяют загружать dll из памяти, а не с диска


Все эти способы не нравятся антивирусам, и MS постепенно выпиливает способы выполнения кода, происхождение которого не поддается проверке. Заложившись на такие техники, рискуете поиметь большие проблемы в будущем, так что использовать их стоит лишь в случае реальной необходимости.
Re[2]: Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 01.12.20 10:09
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Все эти способы не нравятся антивирусам, и MS постепенно выпиливает способы выполнения кода, происхождение которого не поддается проверке. Заложившись на такие техники, рискуете поиметь большие проблемы в будущем, так что использовать их стоит лишь в случае реальной необходимости.


Антивирусам может не нравиться и создание dll на диске приложением. JIT компиляцию тогда тоже на свалку?
Re[3]: Загрузка DLL из памяти и диалоговые окна
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 01.12.20 10:34
Оценка:
Здравствуйте, edton, Вы писали:

E>Антивирусам может не нравиться и создание dll на диске приложением.


Ну да — любые способы динамического создания кода. Поскольку насущная необходимость в этом возникает редко, такая политика оправдана.

E>JIT компиляцию тогда тоже на свалку?


Для продуктов, использующих компиляцию в целях необходимости, делаются исключения. Но, чтоб эти исключения сделали для Ваших продуктов, нужны весомые аргументы об этой самой необходимости.
Re: Загрузка DLL из памяти и диалоговые окна
От: morgot  
Дата: 01.12.20 22:02
Оценка:
Здравствуйте, edton, Вы писали:

E>Привет,

E>Есть известные способы, которые позволяют загружать dll из памяти, а не с диска, например:
..
E>Что тут можно сделать? Ставить хуки на API работы с ресурсами, насколько это будет стабилно.
E>Интересно ещё то, что например, некоторые протекторы позволяют упаковывать dll в исполняемый файл. У них такие же ограничения?

LoadPE и упаковщики — как бы разные вещи, упаковщики не бьют ресурсы.
Re[2]: Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 02.12.20 05:54
Оценка:
Здравствуйте, morgot, Вы писали:

M>LoadPE и упаковщики — как бы разные вещи, упаковщики не бьют ресурсы.

Упаковщики это не банальный UPX или что-то вроде, а когда dll помещаются внутрь exe и используются без выгрузки на диск.
Если это сторонняя dll в которой например вызывается FindResource или своя, но вызывающая например CreateDialog, или даже
банально GetModuleFileName не будут работать. Я так понимаю, что простого быстрого решения нет.
Re: Загрузка DLL из памяти и диалоговые окна
От: enigmas Ниоткуда  
Дата: 02.12.20 13:43
Оценка:
Здравствуйте, edton, Вы писали:

E>Что тут можно сделать? Ставить хуки на API работы с ресурсами, насколько это будет стабилно.

E>Интересно ещё то, что например, некоторые протекторы позволяют упаковывать dll в исполняемый файл. У них такие же ограничения?

Нет, у нас в протекторе таких ограничений нет.

Что может быть:
1. Попробуйте на другой версии Windows, под vmware, скорее всего все заработает (попробуйте на WinXP, там меньше всего сюрпризов от системы).
2. Загрузчик может проверять принадлежность HInstance переданного функции к какому-нибудь загруженному модулю. Если такового не найдено в PEB, то и окно не показывается
3. Загрузчик может проверять память, где находятся ресурсы, или код вызвавший функцию, на SEC_IMAGE, и если этот флаг для памяти не установлен, то выполнение заворачивается
4. На некоторых системах, при показе такого диалогового окна, загрузчик что-то прописывает в память, где находится заголовок директории ресурсов. Что именно я не разбирался. Возможно, что-то не может записать в вашу выделеную память.

Не исключено, какие то другие ошибки у вас в коде. Я не припомню каких либо проблем с CreateDialog при виртуализации в наших продуктах.
The Enigma Protector — software protection system
http://enigmaprotector.com/
Re[3]: Загрузка DLL из памяти и диалоговые окна
От: morgot  
Дата: 02.12.20 14:43
Оценка:
Здравствуйте, edton, Вы писали:

E>Здравствуйте, morgot, Вы писали:


M>>LoadPE и упаковщики — как бы разные вещи, упаковщики не бьют ресурсы.

E>Упаковщики это не банальный UPX или что-то вроде, а когда dll помещаются внутрь exe и используются без выгрузки на диск.

Потому и говорю, вам нужно то, что называется LoadPE. Ручная загрузка модуля в память. Я писал такое, правда про диалоги не скажу — там больше проблем с SEH, студийным рантаймом и так далее.
Если есть простой пример дллки (что нужно потестить), скиньте.
Re[4]: Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 02.12.20 16:01
Оценка:
Здравствуйте, morgot, Вы писали:

M>Потому и говорю, вам нужно то, что называется LoadPE. Ручная загрузка модуля в память.


OK, ну вот например первой строкой в гугле:
https://github.com/LakshmiDesai/LoadPE
Из README:

MemoryModule is a library that can be used to load a DLL completely from memory ¨C without storing on the disk first.

Чем это отличается от того что я взял:
https://github.com/fancycode/MemoryModule

Часть сторонних и своих библиотек работает, всё нормально, при беглом просмотре импорта там нет потенциально проблемных функций. Но при первой загрузке dll вызывающей CreateDialog всё упало. Дальше пока не разбирался.
Вернемся опять к простому и явному примеру с GetModuleFileName. Пусть у нас есть чужая dll, которая вызывает эту функцию для получения пути к своему файлу на диске. Так как такой сущности как файл dll на диске вообще нет, что она вернёт?
Re[5]: Загрузка DLL из памяти и диалоговые окна
От: morgot  
Дата: 02.12.20 16:11
Оценка:
Здравствуйте, edton, Вы писали:

E>Вернемся опять к простому и явному примеру с GetModuleFileName. Пусть у нас есть чужая dll, которая вызывает эту функцию для получения пути к своему файлу на диске. Так как такой сущности как файл dll на диске вообще нет, что она вернёт?


А что вернётся при обычной загрузке длл? Вот загрузил ее кто-то через LoadLibrary, и что тогда будет — вероятно, путь к ехе?

Вообще, наверное, нужно перехватывать часть функций и подменять значение; я кодил лоадер для ЕХЕ, там подменял GetModuleHandle.
Re[2]: Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 02.12.20 16:14
Оценка:
Здравствуйте, enigmas, Вы писали:

E>Нет, у нас в протекторе таких ограничений нет.


Я правильно понимаю, что у вас нечто большее чем просто загрузка dll из памяти? вроде такой:
https://github.com/fancycode/MemoryModule
Обычно это называется что то вроде "virtual files".
Возьмём для примера GetModuleFileName. Пусть у нас есть чужая dll, которая вызывает эту функцию для получения пути к своему файлу на диске. Так как такой сущности как файл dll на диске вообще нет, что она вернёт?
Re[6]: Загрузка DLL из памяти и диалоговые окна
От: edton  
Дата: 02.12.20 16:21
Оценка:
Здравствуйте, morgot, Вы писали:

M>А что вернётся при обычной загрузке длл? Вот загрузил ее кто-то через LoadLibrary, и что тогда будет — вероятно, путь к ехе?


Вот так например:
TCHAR szPath[MAX_PATH];
GetModuleFileName(GetModuleHandle(L"mylib.dll"),szPath,MAX_PATH);


M>Вообще, наверное, нужно перехватывать часть функций и подменять значение; я кодил лоадер для ЕХЕ, там подменял GetModuleHandle.


Ну вот к этому и пришли
Re: Загрузка DLL из памяти и диалоговые окна
От: Denwer Россия  
Дата: 10.12.20 11:41
Оценка:
Здравствуйте, edton, Вы писали:

E>Что тут можно сделать? Ставить хуки на API работы с ресурсами, насколько это будет стабилно.

E>Интересно ещё то, что например, некоторые протекторы позволяют упаковывать dll в исполняемый файл. У них такие же ограничения?

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