Как сшить exe с exe
Однако существуют программы, использующие сторонние библиотеки, но при этом состоящие из одного единственного файла. Все утилиты от SysInternals, а также любимый мной LINQPad представляют из себя один файл в котором содержится все, что требуется для работы. Пользоваться такими утилитами одно удовольствие — они сразу готовы к использованию, их удобно передавать и хранить.
В статье рассказывается, как создавать такие автономные программы из одного файла. Разобран пример как со сжатием зашить библиотеку AutoMapper в программу и как ее потом достать и использовать.
Исходный код к статье — скачать
Код программы использует стороннюю библиотеку AutoMapper. Чтобы убедиться в работоспособности библиотеки после ее зашития в ресурсы, в программе вызывается код из семплов к библиотеке. Этот код здесь не приведен, ибо это статья не об AutoMapper. Но сама библиотека интересная и полезная — рекомендую посмотреть, что же она делает в коде.
Если CLR не удалось найти сборку, вызывается событие AppDomain.AssemblyResolve. Событие дает возможность загрузить требуемую сборку вручную. Поэтому для реализации автономной программы, состоящей из одного exe файла, достаточно зашить все зависимые сборки в ресурсы и в обработчике AssemblyResolve подгружать их.
Удобно класть в ресурсы сборки в архивированном виде. Архивация уменьшает размер итоговой программы приблизительно в 2 раза. Скорость запуска увеличивается, но эти доли секунды мало кто заметит. А вот уменьшение размера файла позволит его быстрее качать по сети.
Итак, у нас есть работающий проект, использующий сторонние библиотеки. Хочется, чтобы exe файл проекта был автономен и не требовал наличия зависимых dll в своем каталоге.
Полученную ранее архивированную сборку добавляем в ресурсы проекта через Project Properties-Resources-Files. Студия при добавлении ресурса генерирует код, который позволяет использовать добавленный ресурс через Resources класс.
Регистрируем обработчик AssemblyResolve (до использования классов зависимой библиотеки):
AppDomain .CurrentDomain.AssemblyResolve += AppDomain_AssemblyResolve; |
private static Assembly AppDomain_AssemblyResolve( object sender, ResolveEventArgs args ) if ( args.Name.Contains( "AutoMapper" ) ) Console .WriteLine( "Resolving assembly: " , args.Name ); // Загрузка запакованной сборки из ресурсов, ее распаковка и подстановка Для нескольких зависимых библиотек стоит ввести соглашение, согласно которому имя ресурса и искомой сборки совпадают. Тогда можно с помощью отражения автоматически искать требуемую библиотеку в ресурсах. По умолчанию зависимые библиотеки, добавляемые через References, копируются в выходную директорию проекта. Чтобы AssemblyResolve сработал, нужно либо скопировать выходной exe файл в другую директорию, либо запретить копировать зависимые библиотеки в конечную директорию через References-AutoMapper-Properties-Copy Local=false. Включение зависимых сборок в ресурсы самой программы позволяет ей работать автономно. Для запуска требуется один лишь exe файл. Это важно для служебных утилит, сразу готовых к использованию. Фактически такие автономные программы не требуют установки и их удобно передавать по сети или хранить на флешке. Архивирование сборок позволяет уменьшить размер программы и больше таких программ разместить на флешке / быстрее выкачивать из сети. Когда наш журнал был бумажным, мы считали не очень хорошей идеей делать серии зависимых друг от друга статей, ведь, чтобы освежить воспоминания месячной и двухмесячной давности, читателю пришлось бы поднимать подшивку. А теперь все просто :). Мы делаем цикл по реверсу малвари, две статьи уже вышло — вот нулевая (если кто не заметил, там офигенные ссылки, почитай, не пожалеешь. — Прим. ред.), вот первая. Если ты что-то забыл — вспоминай, а если нет — готовься узнать о том, как работают упаковщики и протекторы, для чего их используют и как с ними можно бороться. WARNINGВся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи. Сага о протекторах и упаковщикахОдин из излюбленных приемов зловредописателей — использование упаковщиков (packers) и протекторов (protectors) исполняемых файлов (хотя это также относится и к DLL). Изначально эти инструменты считались весьма банальными и были призваны, по сути, уменьшать размер скомпилированного файла, а в случае протекторов — позволять модифицировать авторам свои программы, превращая их, к примеру, в demo- или trial-версию, и не заморачиваться с защитой в основном коде. Но позднее вирусописатели приспособили эти инструменты в корыстных целях. Создатели вредоносов успешно стали применять их, чтобы усложнить антивирусный и эвристический анализ, защитить свои детища от запуска в виртуальной среде, отладки, дизассемблирования и последующего анализа. Поэтому с тех пор навыки и умения распаковывать исполняемые файлы вошли в обязательные требования как для начинающего, так и для опытного реверс-инженера. Наиболее популярные сегодня упаковщики — UPX, ASPack, FSG, PeShield, VMProtect. Это, так сказать, джентльменский набор, с которым аналитику приходится сталкиваться каждый день. Протекторы, в отличие от упаковщиков, призваны защитить исходный файл от обратной разработки, соответственно, при этом они используют более изощренные методы, чем просто упаковщики: обфускацию, шифрование с использованием самописного либо популярного криптоалгоритма, такого, например, как RSA-1024, встраивание антиотладочных функций. Как мы понимаем, чтобы добраться до нужного нам кода, который мы будем анализировать, сначала требуется распаковать файл, то есть снять все навесные защиты, восстановить оригинальную OEP и таблицу импорта, это как минимум. Частенько распаковка — это задача, укладывающаяся в стандартный набор действий, но иногда она становится творческой и выливается в целое хакерское исследование — с ящиками пива, блоками сигарет и сантиметрами сожженных нервных волокон :). Ликбез по теорииИтак, как мы понимаем, использование упаковщиков/протекторов/крипторов значительно усложняет реверсинг. Помимо этого, писатели зловредов могут использовать многократную упаковку (так называемый послойный пак), применять малоизвестные или вовсе самописные тулзы (для тех, кто хочет накодить что-то свое, небольшой ликбез), сигнатуры которых будут отсутствовать, к примеру, в том же PEiD. Интересно, что любой пакер, не созданный специально для шифрования малвари, оставляет свою уникальную сигнатуру в бинарнике, а соответственно, умея пользоваться Hex-редакторами, можно определить его сигнатуру и без PE-анализатора. Общий принцип рассматриваемых инструментов упаковки/защиты таков: после клика на EXE-файле и его запуска выполнение основного кода программы начинается с так называемой точки входа (Entry Point) — адреса, по которому передается управление после загрузки программы в оперативную память. Когда программа запакована, алгоритм работы несколько изменится. Упаковщик запоминает точку входа EP, потом, используя алгоритмы архивирования, сжимает содержимое файла (как правило, это секция кода и данных), после чего дописывает свою сигнатуру после либо до сжатого кода программы и перенаправляет ее не в основной код программы, а в код упаковщика (точнее сказать — распаковщика). Сам же код распаковщика, находящийся теперь внутри файла, получает управление первым и распаковывает упакованные секции кода/данных в памяти! На диске исходный файл остается нетронутым, то есть упакованным, неизменным. После того как код и данные программы распакованы, код распаковщика восстанавливает таблицу импорта и передает управление основному коду программы, на бывшую точку входа, которая в упакованных программах называется оригинальной точкой входа (Original Entry Point). Если кратко, то это все основные моменты. Схема упаковки исполняемого файла Другие статьи в выпуске: Сжатие данных (упаковка) основывается на свойстве энтропии информации, а алгоритмы по своей сути очень схожи с теми, что применяются в архиваторах, только в отличие от первых упаковщики для исполняемых файлов распаковывают данные в оперативную память. Протекторы, как и некоторые упаковщики, используют ряд приемов борьбы с динамической распаковкой, например расшифровывают код не полностью, а лишь по мере исполнения или создают образ и распаковывают его в память только на момент запуска. Протекторы, используя API-функции, могут определять, что их код запущен под отладчиком, после чего прекращают свою работу. Причиной тому — результат вызова функции API IsDebuggerPresent(), которая определяет, отлаживается программа или нет. Помимо этого, протекторы внедряют процедуры проверки целостности исходного файла, шифруют таблицу импорта, запрещают снятие дампа с определенных адресов виртуальной памяти и иногда используют малодокументированные и недокументированные API-функции, защищающие от трассировки и установки аппаратных точек останова. Ручная и автоматическая распаковкаС большой долей вероятности все рабочие экземпляры малвари будут запакованы тем или иным упаковщиком/протектором. Но чтобы все-таки убедиться, что файл запакован, запускаем PEiD или любой другой PE-анализатор. В 90% случаев этого будет достаточно, PEiD имеет большую базу данных сигнатур и плагинов, что позволяет обойтись без лишних хлопот. Дальнейшим шагом станет распаковка файла (восстановление) в его исходный (wild source) вид. И тут есть несколько сценариев действий. Первый — это использовать автораспаковщики, тулзы, специально заточенные под автоматическую распаковку файла, основываясь на уже известном алгоритме упаковщика/протектора. Например, UN-PACK — это анпакер для UPX, ACKiller — для программ, защищенных протектором ACProtect, Stripper — для файлов, запакованных ASProtect, ASPack unp — для накрытых упаковщиком ASPack. Второй вариант — использовать универсальные распаковщики, например QuickUnpack, RL!dePacker или Dr.Web FLY-CODE Unpacker, основанный на движке FLY-CODE антивируса Dr.Web. Фича программ в том, что они сами автоматически анализируют файл и ищут в нем ОЕР, а после дампят программу (в том числе и импорт восстанавливают). Однако часты случаи, когда сдампленный файл оказывается неработоспособным из-за некорректности его обработки универсальным распаковщиком или из-за изменения алгоритма пакера, который несовместим с тем, что использует универсальный распаковщик. Но есть и плюс: иногда, если файл не удается распаковать до рабочего состояния, секция кода в любом случае получается распакованной, а этого вполне достаточно для анализа. И третий сценарий, более длительный, но в перспективе более успешный, — ручная пошаговая распаковка с помощью OllyDbg. Если файл запакован чем-то неизвестным, это легко определить по наличию в таблице импорта защищаемого приложения WinAPI-функций из библиотеки kernel, таких как GetProcAddressA, LoadLibraryA или GetModuleHandle. Рекомендую прочесть статью с подробным описанием всех существующих на сегодня анализаторов, в ней можно ознакомиться с кратким описанием каждого и даже их скачать. А вот аналогичная страница, но только на этот раз про распаковщики (на всякий случай зеркало тут). Авторы вредоносного ПО широко используют упаковщики и протекторы для усложнения его детектирования и для противодействия анализу. Большинство из них анализируются стандартным арсеналом инструментов реверс-аналитика, но некоторые требуют нестандартного подхода и глубокого знания PE-архитектуры. Учимся скрывать присутствие отладчика и обходить методы противодействияВ одной из статей нашего журнала были описаны наиболее интересные плагины для OllyDbg. Нам обязательно понадобятся:
Все самые нужные плагины OllyDbg 2.xx Plugins можно забрать с файлового архива Tuts4you тут и тут. Набор плагинов для IDA Pro с подробным описанием доступен на GitHub или на Tuts4you. Тем же, кто готов написать свой плагин, могу рекомендовать интересную статью. Шифрование кодаПри анализе различных защит нередко приходится определять, какой алгоритм был использован для шифрования данных. Часто зловредописатели не изобретают велосипедов, а используют уже готовые алгоритмы шифрования. К примеру, если алгоритмы стандартные, то их можно идентифицировать по некоторым характерным константам-полиномам, таблицам преобразований или по последовательности выполняемых операций. Для поиска криптоалгоритмов в исполняемых файлах созданы специальные программы, которые можно посмотреть и скачать тут. Наиболее популярен плагин Krypto ANALyzer для PEiD. Найденные значения можно просто посмотреть или экспортировать в скрипт для дизассемблера IDA Pro. Краткое руководство по анализуТиповой набор действий банален: определение сигнатуры упаковщика, поиск OEP, дамп программы на диск, восстановление таблицы импорта, восстановление релоков, пересборка. А если же файл не просто был запакован, а еще и обработан протектором, то могут потребоваться дополнительные действия, такие, например, как удаление мусорных инструкций, обход антиотладочных приемов, изоляции функций проверки целостности кода CRC. Несколько слов о динамических библиотеках. Распаковка DLL практически не отличается от распаковки EXE-файла. У DLL, как и у EXE, есть точка входа в код программы — Entry Point, созданная пакером, и оригинальная OEP. Таким образом, нужно остановиться на DLL в Entry Point, распарсить и оттуда идти к единственно верной OEP нашей DLL. Дальше можно стандартно дампить. И еще пара коротких абзацев из матчасти, которая сегодня нам пригодится. Несколько слов о breakpoints (точках останова)Точки останова — часто используемый и незаменимый прием любого реверс-аналитика. Основные режимы — это:
Команда CALL $+5 POP REG характерна для защитных механизмов, к примеру копирующих себя на стек. А часто возникающая инструкция PUSHFD присутствует в самотрассирующихся программах и антиотладочных защитных механизмах. Представим, что нам нужно запустить некий зловредный код на машине жертвы. Доступа к этому компу у нас нет, и кажется, что самым простым вариантом будет вынудить жертву сделать все за нас. Конечно, никто в здравом уме не запустит сомнительное ПО на своем девайсе, поэтому жертву нужно заинтересовать — предложить что‑то полезное. Тут в дело вступает джоинер — тулза, которая встроит в полезную нагрузку наш код и скрытно его запустит. warningСтатья предназначена для «белых хакеров», профессиональных пентестеров и руководителей службы информационной безопасности (CISO). Ни автор, ни редакция не несут ответственности за любой возможный вред, причиненный применением информации данной статьи. Существуют ли готовые решения, предназначенные для склейки программ и вредоносной нагрузки? Безусловно, но здесь есть ряд проблем. Такие инструменты детектятся антивирусами, стоят денег и часто продаются как сервис, то есть требуют оплаты за разовую склейку. Бесплатные и простые способы встроить полезную нагрузку вида «поместим файлы в самораспаковывающийся архив» и вовсе банальный фуфломицин. Решение же, сделанное своими руками, может быть улучшено, исправлено в случае детекта и, конечно, останется бесплатным. Немного теорииДжоинер может и должен склеивать два исполняемых файла. Первый — визуальная оболочка, красивая картинка и отвлекающий маневр. Это то, что увидит юзер на экране своего компьютера, когда запустит исполняемый файл. Второй — полезная нагрузка, которая запускается без явного желания пользователя. По умолчанию второй файл не будет как‑то скрыт: если в нем присутствуют окна или, например, громкое музыкальное сопровождение, то это все юзер заметит. Поэтому нужно обеспечить скрытную работу полезной нагрузки. Джоинер лишь склеивает, но не маскирует вредоносное приложение. А может ли джоинер склеить исполняемый файл с картинкой? Может, но это не имеет смысла. Чисто теоретически, если бы он склеивал исполняемый файл и картинку, на выходе все равно получался бы исполняемый файл, который не имел бы расширения . jpg , . png или другого подобного. Редакторы и просмотрщики картинок такой файл открыть не смогут. Либо мы получим картинку, но в таком случае не сможем запустить исполняемый файл. Есть еще вариант, когда приложение стартует и открывает картинку через API ShellExecute. Действие занятное, но только в качестве фокуса — пользы от него никакой. Как устроен наш вариантНашей целью будет Windows 10 x64, но, поняв принцип, легко можно переработать инструментарий под другие версии семейства Windows. Код должен работать и на Windows 7/8, но не тестировался там. Мы будем использовать смесь С++ и ассемблера. Алгоритм работыОболочка — наш первый ехе , который будет виден клиенту. Это, так сказать, приманка. Нагрузка — второй ехе , в котором содержится зловредный контент. В оболочку добавляется дополнительная секция, куда записывается шелл‑код и нагрузка. Управление сразу передается на шелл‑код, задача которого — извлечь нагрузку, сохранить ее на диск и запустить. На верхнем уровне все сводится к тому, что мы получаем некий байтовый массив, который должны положить в дополнительную секцию. Потом останется лишь исправить точку входа у оболочки, и все — склейка завершена. Мы добавим в консольный проект 2 exe, а именно в ресусры, это может быть 1 полезная прога и 2 ваша малварь, это не суть, суть в том что бы склеить 2 любых exe и запустить их из 1 exe при том не палясь перед АВ. Нам понадобится: Запускаем Visual Studio 2019 и создаем консольный проект: Теперь установим нужные NuGet пакеты, жмем в верхнем меню кнопку «Проект» и далее «Управление NuGet пакетами» 1. Жмем вкладку «Обзор» и вводим в строку поиска: SharpZipLib > «Установить» 2. Там же в строке поиска вводим «Costura.Fody» > «Установить» 3. Справа жмем по Program.cs Начнем писать код. Удаляем все в редакторе и вставляем мой код, в коде смотрите комментарии что можно изменить, название файлов, архивов, все что я комментил все можно изменить на ваши имена, поехали: Учтите если вы назвали проект не как уменя: ViJoy То после вставки кода переименуйте: namespace «ViJoy» < на свой Для примера я буду использовать 2 программы:
Их мы и будем склеивать, вы можете представить это так:
Теперь надо 2 эти программы добавить в наш exe билд который мы написали. Для начала будем использовать 7zip и запакуем их в 1 архив под паролем. Выделяем эти 2 файла, жмем правой кнопкой мыши и жмем: 7-zip > добавить к архиву
Пароль любой, ваш, только в коде выше его не забудьте поменять в строке примерно 21й. В моем случаи пароль будет 123 ahiv.zip, его давайте переименуем в другой формат и название: Теперь этот архив надо добавить в наш exe который мы кодили в Visual Studio 2019 (Далее буду назвать это VS). Открываем снова VS: 1. Жмем по проекту правой кнопкой мыши:
Уже готово! Но. Теперь давайте скроем окно консоли. Опять правой кнопкой про проекту, скрин выше > свойства > слева в меню: Приложение > Тип выходных данных выбираем: приложение Windows Теперь нам надо все собрать/скомпилить, ура! Выбираем в окне VS вместо Debug > Release Теперь соберем наши exe и весь проект в 1 exe! Жмем в верхнем меню «СБОРКА» > «Собрать решение» Что бы найти наш exe файл снова жмем по проекту правой кнопкой мыши > «открыть папку в проводнике» Идем в папку bin > Release и видим наш exe файл. Запускаем. и Оп: Вы так же можете добавить по этой технологии сколько угодно exe! хоть 100шт и запускать все разом, данный код не ограничен только двумя exe файлами. Исходники проекта который мы с вами разобрали в статье можете скачать тут Отказ от ответственности: Автор или издатель не публиковали эту статью для вредоносных целей. Вся размещенная информация была взята из открытых источников и представлена исключительно в ознакомительных целях а также не несет призыва к действию. Создано лишь в образовательных и развлекательных целях. Вся информация направлена на то, чтобы уберечь читателей от противозаконных действий. Все причиненные возможные убытки посетитель берет на себя. Автор проделывает все действия лишь на собственном оборудовании и в собственной сети. Не повторяйте ничего из прочитанного в реальной жизни. | Так же, если вы являетесь правообладателем размещенного на страницах портала материала, просьба написать нам через контактную форму жалобу на удаление определенной страницы, а также ознакомиться с инструкцией для правообладателей материалов. Спасибо за понимание. Обычно результатом компиляции проекта является сборка (assembly) проекта, а также его зависимости (Referenced Assemblies). Однако иногда нужно чтобы результатом был один файл единственный файл, независимый от других сборок. Например простая утилита, которую можно будет куда угодно скопировать и она будет работать. ПримерУсловно говоря после: Получаются: На Хабре уже присутствует решение со встраиванием зависимостей в ресурсы, здесь я покажу как это сделать с помощью ILMerge и Post Build Event в Visual Studio. ИсходникиИнструментыILMerge — Программа от Microsoft Research, которая собственно и обладает требуемой функциональностью. ПодготовкаСодержание merge_all.batЛицензияС сайта ILMerge: Читайте также:
|