Проект PurePortable был создан для разработки средств для портабелизации программ с использованием прокси-dll.
Портирование программ осуществляется в основном через перехват вызовов WinApi - перехват обращений к реестру позволяет сохранять настройки не в реестре, а в файле рядом с программой, перехват вызовов для определения системных папок позволяет переместить AppData в папку программы и т.п.
Прокси dll, это dll перехватывающая вызовы WinApi от программы и либо изменяющая их поведение либо перенаправляющая вызовы в оригинальную dll без изменения.
Dll различаются способом внедрения:
1. Подмена системной dll в папке с программой. Для использования данного метода необходимо, чтобы программа имела в таблице импорта (прямого, не отложенного!) вызовы данной dll, либо такие вызовы имели другие dll, вызовы которых импортирует программа и находящиеся в одной папке с программой.
Типичный пример это version.dll. Сама version.dll не имеет экспортируемых функций интересных с точки зрения портабелизации, но из неё отлично устанавливаются хуки. Простой пример такой портабелизации - InnoSetup (выкладывал на ru-board).
Другой пример это winmm.dll, а пример портабелизации сам PureBasic. Да, Пурик имеет ключ /portable, но этот ключ надо ещё и не забыть указать, а случайно забыв Пурик тут же ассоциирует себя с файлами pb ломая нужные ассоциации. Кроме того, Пурик в своих prefs хранит абсолютные пути, что мало вяжется с "портабельностью". Dll решает эти проблемы корректирую пути к Tools в tools.prefs, к компиляторам в PureBasic.prefs, по возможности к файлам RecentFiles и некоторые другие пути. Dll я выкладывал на ru-board и в телеграмме.
А ещё winmm используется фреймворком QT. Даже если сама программа не имеет ничего полезного из импорта, если она использует QT то обычно легко портируется.
Таки способом нельзя подменить dll из списка KnownDLLs и в некоторых других случаях.
2. Подмена системной dll путём замены имени dll непосредственно в коде программы (речь о замене не в исходном коде, а непосредственно в exe, например, каким-нибудь hex-редактором).
Пример - портабелизация утилит SysInternals. Там подменяется comdlg32.dll. Выкладывал на ru-board.
Метод не обязательно применять только для dll из списка KnownDLLs, подходит для любых dll. Например, через прокси winmm, переименовании dll и соответствующем изменении имён в exe-файлах, в одной папке на флешке уживаются HWiNFO32 и HWiNFO64 (разной разрядности).
Метод не работает на сжатых файлах (потребуется разжатие), накрытых протектором, проверяющих свою целостность и т.п.
Кроме того, здесь мы становимся на скользкий путь возможного нарушения "авторских прав" и прочей копирайтной хреномудрии. Так что может не всем подойти по "религиозным" мотивам.
3. Добавление своей dll в импорт. Правкой таблицы импорта непосредственно в exe-файле или в одной из используемых им dll можно добавить dll в список. Программа такую dll загрузит, хотя ничего в ней на прямую не использует.
Метод так же, как и предыдущий, не работает на сжатых файлах, накрытых протектором, проверяющих свою целостность и т.п.
Здесь мы так же вмешиваемся непосредственно в код и возможны "копирайтные" ограничения.
Свой алгоритм правки пока не реализован, для внедрения используется утилита setdll из Microsoft (sic!) Detours.
4. Использование внешнего запускателя - создаётся "замороженный" процесс, внедряется dll и процесс размораживается. К сожалению, у меня пока нет рабочих примеров данного метода.
Как пример есть утилита withdll из того же Detours.
В dll используются следующие способы перехвата:
1. Сплайсинг на базе библиотеки MinHook.
2. Перехват IAT.
3. Прямая подмена вызовов. Это вроде даже и не метод, но для полноты должен быть упомянут - при подмене, например, advapi32.dll (метод 2 - правка кода) хуки могут быть вообще не нужны, так как программа напрямую вызывает функции из "подменной" dll.
Ссылки:
Смежная тема тема на ru-board
Википедия - перехват
Правовые моменты.
Сам по себе перехват не является чем-то незаконным и даже используется в самой ОС Windows, например, для обеспечения совместимости приложений с ОС, а слайсинг предусмотрен практически "из коробки".
Тем не менее, в некоторых случаях, например при правке кода для внедрения dll может быт что-нибудь нарушено. Обсуждение в таких "тонких" случаях лучше перенести на ru-board.
Отредактировано Smitis (26.08.2023 20:11:02)