Уменьшаем размер приложения (Delphi)

21.11.2010

Уменьшаем размер приложения (Delphi)

Уменьшить размер EXE файла можно двумя путями: либо использовать упаковщики (типа UPX), либо удалить из EXE таблицы релокаций. Обычно для этого используют сторонние утилиты (например StripReloc от Джордона Рассела). Однако начиная с Delphi 2006 релоки можно не удалять, а просто не создавать! Далее в статье я расскажу как это реализовать.

В Delphi 2006 появилась недокументированная директива компилятора {$SETPEFLAGS}. Она позволяет настроить несколько тонких моментов создания нашего бинарника.

В первую очередь она интересна тем, что позволяет отключить создание таблицы релокаций. Вот только тут будьте осторожны: не отключайте таблицы релокаций в dll, bpl и др. файлах, так как таблица релокации не нужна только exe файлу, который всегда грузится по одному и тому же адресу.

Теперь ближе к делу. Как отключить таблицу релокаций:
1. Откройте файл проекта (dpr)
2. В uses добавьте Windows
3. Ниже пропишите {$SETPEFLAGS IMAGE_FILE_RELOCS_STRIPPED}

Теперь попробуйте скомпилировать проект и сравните какой был размер до и после внедрения этой функции.

В дополнение хочу сказать, что использование SETPEFLAGS этим не ограничивается. У неё есть ещё масса интересных возможностей получить которые очень просто:
1. Откройте модуль Windows
2. Найдите в нём поиском IMAGE_FILE_RELOCS_STRIPPED

Нашли? Ниже идёт целый список констант, начинающихся с IMAGE_FILE_,
а справа идёт их комментарии. Для включения нескольких инструкций одновременно, используйте or. Например:
{$SETPEFlAGS IMAGE_FILE_RELOCS_STRIPPED or IMAGE_FILE_DEBUG_STRIPPED or
IMAGE_FILE_LINE_NUMS_STRIPPED or IMAGE_FILE_LOCAL_SYMS_STRIPPED or
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP or IMAGE_FILE_NET_RUN_FROM_SWAP}

Теперь подробнее о том, что мы написали:
IMAGE_FILE_RELOCS_STRIPPED - отключает таблицу релокаций.
IMAGE_FILE_DEBUG_STRIPPED - удаляет из ехе Debug информацию.
IMAGE_FILE_LINE_NUMS_STRIPPED - удаляет из exe информацию о номерах строк.
IMAGE_FILE_LOCAL_SYMS_STRIPPED - удаляет local symbols.
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP - при запуске exe с диска, флэшки или других извлекаемых устройств, позволяет считать exe в память компьютера и запускать оттуда. Полезно, если нужно запустить программу с диска, а потом попросить вставить другой.
IMAGE_FILE_NET_RUN_FROM_SWAP - аналогично предыдущей, только для сетевых дисков.

А не проще ли воспользоваться UPX-упаковщиком?
На этот вопрос Джордан Рассл даёт три ответа:

  • При запуске сжатого EXE / DLL, весь код распаковывается из образа в память за один проход, что может привести к зависанию и большой нагрузке на диск, особенно если системе не хватает памяти и она вынуждена пользоваться файлом подкачки.
  • Если у вас есть сжатый EXE который весит 1 МБ (до сжатия) и вы запустите его 5 раз, то около 4 Мб памяти пропадёт в пустую, а если у вас ещё есть и DLL (тоже по 1 Мб) и она используется на 5 запущенных приложениях, то это ещё минус 4 Мб свободной памяти. У несжатых EXE / DLL, код загружается в память один раз и является общим для всех пяти программ.
  • Некоторые старые антивирусные сканеры распознают сжатый EXE / DLL как инфицированные вирусом приложения.
  • Комментарии

    avatar

    Теги

    Опрос

    Ваши увлечения?
    Результаты Все опросы

    Статистика


    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0