Раньше я использовал UPX, чтобы уменьшить размер исполняемых файлов Windows, но должен признать, что я наивен в отношении каких-либо негативных побочных эффектов, которые это могло иметь. В чем недостаток всей этой упаковки / распаковки?
Существуют ли сценарии, в которых кто-то порекомендовал бы НЕ UPX-загружать исполняемый файл (например, при написании DLL, службы Windows или при ориентации на Vista или Win7)? Я пишу большую часть своего кода на Delphi, но я также использовал UPX для сжатия исполняемых файлов C / C++.
Кстати, я нет запускаю UPX, пытаясь защитить свой exe от дизассемблеров, только чтобы уменьшить размер исполняемого файла и предотвратить поверхностное вмешательство.





В последний раз, когда я пытался использовать его в управляемой сборке, он настолько сильно изменил его, что среда выполнения отказалась загружать его. Это единственный раз, когда я могу подумать, что вы не захотите его использовать (и, действительно, я так давно не пробовал, что теперь ситуация может быть даже лучше). В прошлом я широко использовал его для всех типов неуправляемых двоичных файлов, и у меня никогда не было проблем.
Окончательный размер исполняемого файла на диске в наши дни практически не имеет значения. Ваша программа может загружаться на несколько миллисекунд быстрее, но как только она начнет работать, разница будет неразличима.
Некоторые люди могут с большим подозрением относиться к вашему исполняемому файлу только потому, что он сжат с помощью UPX. В зависимости от ваших конечных пользователей это может быть или не быть важным соображением.
+1 Я всегда с подозрением отношусь к упакованным исполняемым файлам / DLL, особенно если я не могу их распаковать.
Размер имеет значение в контейнерах Docker.
Размер имеет значение, если вы читаете из медленной флэш-памяти, что может иметь место во встроенной системе.
The reason is there are downsides to using EXE compressors. Most notably:
Upon startup of a compressed EXE/DLL, all of the code is decompressed from the disk image into memory in one pass, which can cause disk thrashing if the system is low on memory and is forced to access the swap file. In contrast, with uncompressed EXE/DLLs, the OS allocates memory for code pages on demand (i.e. when they are executed).
Multiple instances of a compressed EXE/DLL create multiple instances of the code in memory. If you have a compressed EXE that contains 1 MB of code (before compression) and the user starts 5 instances of it, approximately 4 MB of memory is wasted. Likewise, if you have a DLL that is 1 MB and it is used by 5 running applications, approximately 4 MB of memory is wasted. With uncompressed EXE/DLLs, code is only stored in memory once and is shared between instances.
http://www.jrsoftware.org/striprlc.php#execomp
Не все программное обеспечение находится в ситуации, когда совместное использование страниц виртуальной машины между несколькими экземплярами является проблемой, а некоторые компрессоры позволяют пропускать общие разделы. Например, PECompact пропускает их по умолчанию. Кроме того, что касается «загружается вся память», это правда, но эта память будет выгружена обратно, если она не используется и понадобится где-то еще. В некоторых ситуациях это создает более быструю загрузку, потому что накладные расходы носителя (обычно жесткого диска) ниже, и все загружается «сразу» и «уже есть». Так что исключения бывают, и каждому свое. ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я являюсь автором PECompact.
Джереми: Общие разделы - это не столько проблема, сколько сами разделы кода. Код обычно представляет собой чтение-выполнение с отображением памяти, что означает, что если вы запустите 10 программ, все они будут использовать одни и те же, идентичные физические страницы памяти, а физические данные загружаются с диска только один раз. ОС также может отбрасывать страницы, содержащие код, который никогда не вызывался, если у него мало памяти, зная, что она всегда может легко перезагрузить их из образа. Ничего из этого не происходит с кодом, полученным от упаковщика exe, соответствующие страницы должны поддерживаться файлом подкачки.
Я согласен с вами, Деймон, поэтому возникает вопрос - имеет ли ваше приложение тенденцию к запуску нескольких экземпляров? Это одно из предостережений, о которых я давно предупреждал. Конечно, участки кода в любом случае обычно довольно маленькие - посмотрите на размеры, о которых мы говорим, по сравнению с сегодняшними системами. Я бы сказал, что НАМНОГО больше памяти обычно выделяется динамически в БОЛЬШИНСТВЕ приложений.
Я также ожидаю, что это немного замедлит время запуска - что может быть незаметно для одного запуска, но если у вас есть исполняемый файл, который запускается повторно (например, grep), это может иметь довольно заметную разницу, верно?
Означает ли это, что сжатый, а затем распакованный исполняемый файл upx original.exe -o compressed.exe будет вести себя нормально, как исполняемый файл, в котором ОС разделяет код между экземплярами и не перегружает диск?
Единственное, что имеет значение размер - это время загрузки из Интернета. Если вы используете UPX, производительность будет ниже, чем при использовании 7-молния (на основе моих тестов 7-Zip вдвое лучше UPX). Затем, когда он фактически остается сжатым на целевом компьютере, ваша производительность снижается (см. Ответ Ларса). Так что UPX - не лучшее решение для размера файла. Просто заархивируйте все это с помощью 7zip.
Что касается предотвращения взлома, это тоже ПРОВАЛ. UPX также поддерживает распаковку. Если кто-то захочет изменить EXE, он увидит, что он сжат с помощью UPX, а затем распакует его. Процент возможных взломщиков, которые вы можете замедлить, не оправдывает потери усилий и производительности.
Лучшим решением было бы использовать двоичную подпись или хотя бы просто хэш. Простая система проверки хэша состоит в том, чтобы взять хэш вашего двоичного файла и секретное значение (обычно это guid). Только ваш EXE знает секретное значение, поэтому, когда он пересчитывает хэш для проверки, он может использовать его снова. Это не идеально (секретное значение можно получить). Идеальной ситуацией было бы использование сертификата и подписи.
Размер имеет значение на USB-накопителе. Портативные приложения - это тот случай, когда это имело бы смысл.
Учитывая текущие цены на многогигабайтные флешки, я не уверен, что и здесь размер имеет значение. Если, конечно, вы не храните HD-видео.
Алгоритм сжатия UPX как минимум равен LZMA для сжатия отдельного исполняемого файла. Только 7-zip лучше, если у вас есть несколько exe / dll, которые нужно сжать одновременно: в этом случае 7-zip сжимает все эти файлы за один раз, поэтому имеет некоторое соотношение.
Размер также имеет значение при использовании файлов НЕ на локальном жестком диске. Как на сетевом ресурсе, так и на внешнем жестком диске.
Размер имеет значение и в контейнерах Docker.
Я считаю, что есть вероятность, что это может не работать на компьютерах, на которых включен DEP (предотвращение выполнения данных).
Как автор коммерческого компрессора PE (PECompact), я могу сказать, что каждый пакер должен полностью поддерживать DEP, включая UPX. Я не могу сказать наверняка, что это так, но, безусловно, это так - это проблема, которая возникла много лет назад.
Не могли бы вы подробно рассказать, как это достигается? (источник / литература)
@ kn0x DEP предотвращает выполнение только памяти, которая не помечена как исполняемая, для которой VirtualProtect(Ex) используется для переключения страниц памяти между записываемыми и исполняемыми.
Это возврат :) Thx @Suchiman, мой вопрос изначально касался внутреннего устройства upx, а не DEP.
Если вас интересует только уменьшение размера исполняемых файлов, то пробовали ли вы сравнить размер исполняемого файла с пакетами времени выполнения и без них? Конечно, вам нужно будет также указать размеры пакетов в целом вместе с вашим исполняемым файлом, но если у вас есть несколько исполняемых файлов, которые используют одни и те же базовые пакеты, тогда ваша экономия будет довольно высокой.
Еще одна вещь, на которую стоит обратить внимание, - это графика / глифы, которые вы используете в своей программе. Вы можете сэкономить довольно много места, объединив их в один Timagelist, включенный в модуль глобальных данных, вместо того, чтобы повторять их в каждой форме. Я считаю, что каждое изображение хранится в ресурсе формы как шестнадцатеричное, так что это будет означать, что каждый байт занимает два байта ... вы можете немного уменьшить его, загрузив изображение из ресурса RCData с помощью TResourceStream.
Я удивлен, что об этом еще не упоминалось, но использование исполняемых файлов, упакованных UPX, также увеличивает риск получения ложных срабатываний от эвристического антивирусного программного обеспечения, потому что статистически многие вредоносные программы также используют UPX.
UPX не для защиты. Просто собираю вещи.
Извините, я немного невнятно это сказал. Изменил формулировку сейчас.
Полностью согласен. В Free Pascal мы получаем несколько таких отчетов (о том, что тот или иной двоичный файл в дистрибутиве запускает какой-то вирус) в год. Затем мы перестали регулярно обновлять апкс.
@JohnSmith Вы правы ... но, к вашему сведению, вы можете (довольно легко) сместить точку входа файла, сжатого UPX, так что стандартный метод распаковки UPX не сможет распаковать его, что, по сути, делает его защищенным (ищите UPX Scrambler который делает это автоматически)
Есть три недостатка:
Таким образом, указанные выше недостатки представляют собой большую проблему, если ваши EXE или библиотеки DLL содержат много ресурсов, но в противном случае они могут не иметь большого значения на практике, учитывая относительный размер исполняемых файлов и доступной памяти, если вы не говорите о библиотеках DLL. используется многими исполняемыми файлами (например, системными DLL).
Чтобы рассеять некорректную информацию в других ответах:
ИМХО в обычном режиме UPXing бессмысленен, но причины изложены выше, в основном память дороже диска.
Эрик: заглушка LZMA могла бы быть больше. Даже если алгоритм лучше, это не всегда будет чистым плюсом.
Кажется, что память и дисковое пространство в любом случае не сильно влияют на современное оборудование, что делает UPX просто дополнительным осложнением. По моему опыту, я экономлю всего около 500 КБ из приложения 3 МБ, особенно на Mac, где файлы dylib не поддерживаются.
Сканеры вирусов, которые ищут «неизвестные» вирусы, могут помечать сжатые исполняемые файлы UPX как содержащие вирус. Мне сказали, что это связано с тем, что некоторые вирусы используют UPX, чтобы скрыться. Я использовал UPX для программного обеспечения, и McAfee отметит файл как содержащий вирус.
Макафи? Это самая ужасная антивирусная программа, которую я когда-либо использовал. Держись подальше!
На самом деле, держитесь подальше от любого антивирусного сканера, который достаточно глуп, чтобы пометить каждый сжатый файл upx как вирус.
Причина, по которой UPX имеет так много ложных срабатываний, заключается в том, что его открытое лицензирование позволяет авторам вредоносных программ безнаказанно использовать и изменять его. Конечно, эта проблема присуща отрасли, но, к сожалению, великий проект UPX страдает от этой проблемы.
ОБНОВЛЕНИЕ: обратите внимание, что по мере завершения проекта Taggant возможность использования UPX (или чего-либо еще) без ложных срабатываний будет улучшена, если UPX поддерживает его.
Недостатков нет.
Но к вашему сведению, существует очень распространенное заблуждение относительно UPX как ...
По сути, вы создаете новый исполняемый файл, который выполняет функцию «загрузчика», а «настоящий» исполняемый файл, ну, разделяется и сжимается, помещается как ресурс двоичных данных исполняемого файла загрузчика (независимо от того, какие типы ресурсов были в исходный исполняемый файл).
Использование методов обратного проектирования и инструменты либо в образовательных целях, либо Другие покажет вам информацию о «исполняемом файле загрузчика», а не переменную информацию об исходном исполняемом файле.
@kobik несмотря на то что "без недостатков" * должен вероятно заменить на "без практических недостатков" *, что по сути (для практического разработчика в современной архитектуре) означает то же самое, я решил, что это не требует редактирования, в пользу более четкого, реалистичный ответ. Смирись с этим :)
Как автор одного из классических конкурентов UPX, PECompact, могу однозначно сказать о практических недостатках находятся. Два называют три: ложные срабатывания, потенциальные проблемы совместимости в будущем и неспособность ОС загружать определенные страницы с диска по запросу (применимо только к действительно большим модулям).
Ваше объяснение того, как работает сжатие, тоже немного неверно ... Собственное сжатие PE фактически выполняет декомпрессию «на месте». Итак, это не похоже на то, что вы описали, где он просто распаковывает весь исходный EXE из сжатого ресурса, а затем запускает его. Вместо этого ОС фактически запускает сжатый модуль. Загрузчик распаковывает виртуальные страницы на месте. Теперь есть плохие / хромые компрессоры, которые действуют так, как вы описали, и компрессоры сборки .NET будут такими, но обычно это не делается. Прошу прощения за критику, я просто хочу обеспечить точность.
Когда Windows загружает двоичный файл, первое, что она делает, это разрешение таблицы импорта / экспорта. То есть, какие бы API и DLL не были указаны в таблице импорта, они сначала загрузят DLL в случайно сгенерированный базовый адрес. И используя базовый адрес плюс смещение в функции DLL, эта информация будет обновлена в таблице импорта.
EXE не имеет таблицы экспорта.
Все это произошло еще до перехода к исходной точке входа для выполнения.
Затем после того, как он начнет выполнение с точки входа, EXE выполнит небольшой фрагмент кода перед запуском алгоритма распаковки. Этот небольшой фрагмент кода также означает, что необходимый Windows API будет очень маленьким, что приведет к небольшой таблице импорта.
Но после распаковки двоичного файла, если он начал использовать какой-либо Windows API, не разрешенный ранее, скорее всего, он выйдет из строя. Поэтому важно, чтобы процедура декомпрессии разрешала и обновляла таблицу импорта для всех упомянутых окон API внутри распакованных кодов перед выполнением распакованных кодов.
Использованная литература:
https://malwaretips.com/threads/malware-analysis-2-pe-imports-static-analysis.62135/
+1 причина не использовать UPX: некоторые антивирусы идентифицируют Delphi + UPX как потенциальный вирус. Предпочтительно использовать наш LVCL, который составляет 30 КБ exe с Delphi без сжатия (вместо 300/800 КБ exe с обычным VCL). Достаточно, например, для программы установки, которая распаковывает его содержимое. См. synopse.info/forum/viewtopic.php?id=30. Вы можете также взглянуть на KOL, которые сложнее использовать, но они также более мощные.