Упаковщик PE-файлов (exe, dll)

На днях завершил крупный коммерческий проект, только собирался потратить вырученные средства на покупку очередного ноутбука Alienware и поездку на Гавайи, как ко мне в гости зашел Каями (с нехарактерно расширенными зрачками) и сказал, чтобы я что-нибудь написал в блог, дескать не солидно как-то ничего не запостить перед Новым Годом. Сам-то он якобы занят, но я подозреваю, чем он на самом деле занимается. В общем, его просьбу я выполнил. Каями, судя по всему, остался доволен и в ответ на ссылку на пост скинул мне в аську скриншот статы какой-то партнерки. Так что он тоже едет на Гавайи! Поэтому в ближайшие пару недель новых постов можно, пожалуй, не ждать.

Итак, выкладываю упаковщик PE-файлов собственного производства. Исходники самого упаковщика на C++ и стаба распаковщика на MASM32 в комплекте. Все с комментариями на английском языке. Привереды и не умеющие переводить технические тексты идут вон из комментариев к посту! Про PE-формат я цикл статей завершу когда-нибудь, а пока ловите хотя бы это, на остальное времени нет. Самое основное в упаковщике - это файл main.cpp размером 51 кб (лень было разбивать) и unpacker.asm. unpacker.cpp - это стаб распаковщика в скомпилированном виде (его исходник, соответственно, в unpacker.asm). Используется немного библиотек из boost.

Возможности упаковщика:
[+] Поддержка exe, dll-файлов. Драйвера (sys-файлы) не упаковываются.
[+] Дерьмовая степень сжатия, так как используются RtlCompressBuffer / RtlDecompressBuffer - чисто ради примера. Кроме того, упаковывается каждая секция отдельно, не слепляются вместе, как это делает UPX, это тоже влияет на степень сжатия.
[+] Поддержка экспортов (по ординалу, по имени, а также форвардов в другие dll).
[+] Само собой, поддержка импортов (по ординалу и по имени).
[+] Поддержка и умение упаковывать секцию ресурсов (из нее перемещаются иконки, информация о версии и манифест, так что упакованный файл внешне ничем не отличается от оригинала).
[+] Поддержка релокаций (фиксапов / перемещаемых элементов / назовите их как хотите).
[+] Изменение выравнивания файла.
[+] Возможность упаковки только конкретных секций
[+] Поддержка TLS (локальная память потока) (кроме TLS callbacks, которые ни один компилятор не умеет делать, насколько мне известно).
[+] Удаление rich overlay'а от Visual C++.
[+] Возможность упаковки PE-заголовка в DOS-заголовок.
[+] Поддержка бинарников Visual C++, Borland C++/Delphi, MinGW, MASM32 (другое не проверялось, но, скорее всего, тоже заработает).

Упаковщик поддерживает только PE32.

Пример использования:
pack.exe test_exe.exe

Дополнительные опции командной строки:

-o - позволяет задать имя запакованного файла. По умолчанию оно собирается из имени оригинального файла и слова "packed".
-i - если задана эта опция, в запакованный бинарник будет добавлена директория импорта, состоящая из одного импорта. Дело в том, что старым версиям Windows (например, XP) иногда может не нравиться отсутствие импортов у исполняемого файла. По умолчанию запакованный файл директории импорта не имеет.
-s - позволяет задать список имен секций, которые должны быть упакованы. По умолчанию пакуются все секции файла. Использование: -s .text .data
-r - позволяет включить/отключить упаковку секции ресурсов. Если у бинарника много места занимают иконки, то иногда выгоднее ее не паковать. Использование: -r 0 или -r 1.
-a - позволяет задать файловое выравнивание запакованного бинарника. Использование: -a 1024. По умолчанию это 512 (минимальное).
-d - позволяет включить опцию обрезки DOS-заголовков (поверх их будет записан PE-заголовок). По умолчанию выключена, так как на результирующий размер не влияет. Использование: -d 0 или -d 1.
-f - если задана данная опция, будет паковаться любое говно, которое вы подсунете упаковщику (дрова, .NET-бинарники, уже запакованные ранее файлы и т.д.), но результат, скорее всего, будет неработоспособным.
-m - опция включает/отключает перемещение иконок из директории ресурсов (если она пакуется) в секцию ресурсов упаковщика. По умолчанию включено, но можно отключать для файлов DLL, имеющих в ресурсах какие-то иконки - размер будет меньше. Использование: -m 0 или -m 1.

Любители няшных графических свистелок и перделок идут в лес за грибами.

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

А вот и сам пакер с исходниками: Скачать!

UPDATE от 27.12.2011: Добавлена опция командной строки -i, добавлен вывод предупреждения, если файл имеет оверлей.
UPDATE от 28.12.2011: Добавлена опция командной строки -m.

Упаковщик PE-файлов (exe, dll): 59 комментариев

        1. Можно на разных движках реализовать, есть со встроенным скриптовым языком для AI, вот TES: Oblivion - там и диалоги есть(говорят вроде новая вышла. Хотя, имхо, в 3D не так интересно будет

          1. Судя по всему, людям максимально интересна обычная консоль, выдающая сразу задания. В третий квест гораздо меньше людей играло.

          2. А в каком интересно? Просто консоль - конечно круто и имеет некий плюс, т.к. играется в целом через браузер, но как-то избито что ли...

  1. Несколько лет назад у меня была мечта - написать полиморфный упаковщик. Полиморфный движок написал, а вот до упаковщика руки так и не дошли (учеба, работа, ...). По-моему было бы просто охренительно прикрутить мой полиморфный движок к твоему упаковщику. Для этого потребуется лишь немного переписать код unpacker.asm. Мне кажется, у тебя это получится быстрее и лучше, чем у меня. Если заинтересован - пиши на afiskon гаф gmail.com.

    1. Полиморфный упаковщик? Я слышал о полиморфных крипторах и о простых упаковщиках, а такого термина, как "полиморфный упаковщик", не встречал :)
      Времени сейчас нет такое делать, если есть желание поковыряться - все исходники я выложил. Сложность еще в том, что код базонезависимым должен быть, так как он может оказаться по любому виртуальному адресу загружен. Хотя можно для обычного базозависимого написать релокации, но это, пожалуй, еще более занудно.

        1. Цитату про отсутствие коммерции и про точное определение. Т.к. лично я не считаю коммерцией ситуацию, когда, например, d_x просит меня что-то написать и предлагает за это деньги.

        2. Ну например твой же пост "почему я не люблю программировать". Как-то слабо вяжется с партнерками.
          Впрочем,это совсем не мое дело и ес-но, у меня никаких претензий нет. Просто удивило как-то. Не в обиду, если что.

          1. Так если ведем речь обо мне, то в чем скамерция то? Партнерки - окей, но весь мой доход на них обычно, либо за счет рефа, либо за счет поиска способа накрутки партнерки.

    1. Я уже сказал, что без переписывания самого инсталлятора (или как минимум его детального изучения) это невозможно.

  2. Это не инсталятор, а его подобие, setup.exe из лога - это только пример. Меня не особо интересует степень сжатия, интересует кое что другое ;)

    1. Если интересует криптование, то проще пройтись по бинарнику криптором, который сохраняет физические размеры секций и не режет в результате этого оверлей. Упаковщик точно для такого не подойдет.

  3. С чего бы это ХР не нравились РЕ без импорта?
    Почему выравнивание 512 минимальное?
    По оверлею: многие ехе читают оверлей не по смещению, а по размеру оверлея отнимая от EOF, такчто прикрутить оверлей через 16-ричный редактор и вероятно будет работать.

    1. Прошу прощения, XP нравится без импорта, не нравится, вроде бы, 2000 или NT... А XP не любит таблицы экспорта, содержащие форварды.
      Про выравнивание минимальное - читай доки.

      1. Если Section Alignment == File Alignment, то последнее может принимать любое значение, представляющее собой степень двойки (например, 20h).

        1. Предлагаю выложить пруф в виде файла с Section Alignment = File Alignment = 512< , причем, чтобы файл корректно отрабатывал как на XP, так и на 7

  4. а показать нам всем пример упаковки\шифровки sys файлов не вариант или хотябы лоадер для них?

      1. Ок, пробую собрать пакер, юзаю VC2008
        скачал boost, положил туда 3 файла, но компановщик как будто их не видит
        fatal error C1083: Не удается открыть файл include: boost/scoped_array.hpp: No such file or directory

        boost/scoped_array.hpp
        boost/foreach.hpp>
        boost/program_options.hpp
        также и у меня лежит

  5. Интересная и хорошая работа. Вот только вместе с исходниками принято прилагать файл проекта или хотя бы список библиотек, а то гадать приходиться что да как компилировать.

    1. А тут в блоге есть целый цикл статей по написанию собственного упаковщика, со всеми либами и проектами на каждый шаг.

  6. Антивирус касперского бедалага испугался упакованный файл оставлять: Trojan.Win32.Crypt.cuq обнаружил

      1. Или же сделать распаковщик из исходников, там уже почти готовый код, просто распаковывает в память, а не в файл.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *