Зашить программу в программу

Обновлено: 19.04.2024

Однако существуют программы, использующие сторонние библиотеки, но при этом состоящие из одного единственного файла. Все утилиты от 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 );

// Загрузка запакованной сборки из ресурсов, ее распаковка и подстановка
using ( var resource = new MemoryStream ( Resources .AutoMapper_dll ) )
using ( var deflated = new DeflateStream ( resource, CompressionMode .Decompress ) )
using ( var reader = new BinaryReader ( deflated ) )
var one_megabyte = 1024 * 1024;
var buffer = reader.ReadBytes( one_megabyte );
return Assembly .Load( buffer );
>
>

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

По умолчанию зависимые библиотеки, добавляемые через References, копируются в выходную директорию проекта. Чтобы AssemblyResolve сработал, нужно либо скопировать выходной exe файл в другую директорию, либо запретить копировать зависимые библиотеки в конечную директорию через References-AutoMapper-Properties-Copy Local=false.

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

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

Задача: создать один exe, содержащий в себе интерпретатор питоновский + некоторый набор файлов.
Тобишь, чтобы юзер запускал программу не имея интерпретатора питоновского и в гуи была одна кнопка "сделать хорошо", по нажатию на которую будет идти распаковка файлов (зашитых внутрь исполняемой программы).

Вопрос по большей части интересует каким образом можно зашить файлы с которым придется работать внутрь исполняемой программы?

Как сделать исполняемую программу в планировщике невидимой или невсплываемой
Добрый день! Имеется Windows 7. Познакомился с планировщиком заданий совсем не давно. Поставил.

Как зашить txt файл
Всем привет, не подскажете, как зашить txt файл в exe-шник? Добавлено через 4 минуты искал по.

Дан символьный файл f. Добавить в его конец символы e,n,d (если это необходимо, использовать дополнительный файл g ).
всем привет помогите плиз я в си не силен)) пришлите код программы вот задача: Дан символьный файл.

[Файлы] Составьте программу, которая создает файл RANDOM2.dat.
Помогите с решением задачи :-Составьте программу, которая создает файл RANDOM2.dat, состоящий из 50.

Vanek2009, А ты, что хочешь то? Знать как работает эта сборка изнутри или просто собрать своё приложение?
Ты уточни, что надо, а то у меня сложить впечатление, что тебе просто собрать все в одну кучу надо.

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

Ты, думаешь о том как распространять свою библиотеку?

Наверное не правильно выразился, задача стоит в написании архиватора/разархиватора.
Пример есть такие файлы: 1.jpg, 2.txt, 3.jpg, собираем все в один файл files.archive, теперь собираем питоновское приложение как один program.exe и запаковываем туда files.archive.
Что мы имеем? Один program.exe файл, в котором питоновский интерпретатор + архивный файл (очень важно один файл, а не несколько), далее нажимаем кнопка "распаковать" и файлы 1.jpg, 2.txt, 3.jpg распаковываются.

Это своего рода патчер, который ищет директорию, где установлена игра и заменяем там файлы и закрывает запущенное приложение игры, чтобы заменить полностью. Текущие проблемы:
1. если давать в .rar или zip и т.д., то не у всех он есть (да и такие бывают);
2. не могут найти папку с игрой;
3. не понимают, что сперва надо закрыть игру, а потом патчить.
и т.д.

Очень важно дать один .exe, который "сделает как надо все сам", игроку не надо знать, где игра, что заменять, закрывать и т.д.

Какие есть предложения?

sfx это самораспаковывыщийся архив, которому ненужен установленный winrar и тому подобное.

Насколько я понял по гуглежу, то можно создать автораспаковывающийся архив, который будет запускать программу лежащую внутри него. То есть соберёшь в exe свою приложуху, которая будет патчить, рядом с ней ложишь файлы для замены и пакуешь все это в архив. Архив распакуется куда нибудь во врменную папку, запустит твою приложуху, которая уже все пропатчит.
Примерный алгоритм такой, но надо уточнять детали.

Составить программу в Си : дополнительный код
Нужно задать отрицательное число в 10й СС и написать программу , которая выведет на экран.

Перевод строки в исполняемую функцию
Недавно столкнулся с проблемой перевода вводимой строки в исполняемую программой функцию. Ну.

Преобразование строки в исполняемую инструкцию.
Подскажите, пожалуйста, возможно ли задать строку, к примеру: string str="sin(x)*log(x)", а затем.

Добавить дополнительный цикл в имеющуюся программу
Здравствуйте, есть код программы нужно добавить дополнительный цикл. var y,x,a,y1,p:real;.

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

Вопрос в том где можно найти бесплатно такой сервак или может есть другой способ ?

Простейшая защита программы: где хранить число срабатываний программы?
День добрый! Написал одну небольшую программу, которая может быть интересна специализированной.

Защита программы от НСД. Защита путем шифрования части программы на флеш-диске или флешке
Написать программу на любом известном Вам языке программирования. Программа должна выполнять.

Защита триальной программы через запись в реестре
Написал простенькую программу и хочу также просто её защитить. С помощью записи в реестр, чтобы.

Защита программы которая активируется через определенный термин
Hello World коротко - пишу софтину на фирму , выполняю заказ через посредника (дядя с большой.

как тебе такая идея - поднять на бесплатном хостинге простейший сайт, и если программа может получить определенную страницу по интернету - работает, не может - не работает

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


Открываем твою программу, заменяем je на jne (или какие там аналоги в msil?) и пользуемся до посинения.

NightmareZ,
можно поподробнее что это вообще такое?
с ассемблером как то связано или что?

и какой вариант защиты по твоему нужно использовать что бы никто ничего не взломал?

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

Хм. А этой программе действительно для работы требуется соединение с Сетью? Меня бы "прога", которая без всякого видимого повода и потребности лезет в Инет, насторожила бы - троян-с, немедленно "получила бы по рукам" от файервола и была бы снесена в Корзину навечно.
К тому же, этот метод защиты обходится на раз.

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

CheshireCat
выход в инет не нужен для работы, но я то скажу тому кому дам прогу что без выхода в инет она работать не будет я же ее не продаю тут проблем нет
КАК это защита обходиться можете рассказать по пунктам я хочу сам взломать свою прогу если это так легко ?

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

Код проги же у меня закрыт как кто то сможет залезть в мой код и поменять там переменную ?
прога у меня в виде длл
Если к примеру поставить в ней условие чтобы был определенный файл на локальном компе если по инету один раз выполниться условие что на удаленном серваке нет нужного файла локальный файл удаляеться а без него прога тоже не будет запускаеться
Это тоже легко обойти ? или легко только если прога для работы требует выход в инет и проверку файла на удаленном серваке ?

Руками. Открой для себя существование дизассемблеров и отладчиков.

Если это легко можешь написать в двух словах какой отладчик и дизасемблер мне нужен и что там мне надо сделать?

Если это легко можешь написать в двух словах какой отладчик и дизасемблер мне нужен и что там мне надо сделать?

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

NightmareZ,
Я хочу сам взломапть свою прогу, решение я уже нашел хочу проверить правда ли его так легко обойти
Поэтому объясните мне плз как мне это сделать через дизасемблемр итд
пишу на C++ в VS2008

Открываем твою программу, заменяем je на jne (или какие там аналоги в msil?) и пользуемся до посинения.

NightmareZ,
Я хочу сам взломапть свою прогу, решение я уже нашел хочу проверить правда ли его так легко обойти
Поэтому объясните мне плз как мне это сделать через дизасемблемр итд
пишу на C++ в VS2008

Суть в том, что есть некоторый пароль, который мы не знаем. В данном случае это "root", но значения это не имеет, ибо на практике пароль не будет константой, а будет как-то вычисляться, и, возможно, весьма нетривиально. Потому трогать пароль не будем.

Открываем экзешник в IL DASM, входящем в состав Visual Studio (см. первый скриншот).
На интересует единственный метод Main, даблкликаем на нём и смотрим листинг на CIL (см. второй скриншот).

Сразу бросается в глаза условный переход brtrue.s, его то и будем менять на brfalse.s
Что из этого выйдет? Из этого выйдет то, что надпись "Success!" мы будем получать всегда, когда введём неправильный пароль.

Делаем дамп, для чего нажимаем в IL DASM комбинацию Ctrl+D (см. третий скриншот).

На выходе получим файл с расширением .il

Теперь открываем Visual Studio Command Prompt и из него компилируем изменённый исходник. У меня имя файла: "code.il", потому я делаю так:

На выходе получаем экзешник. Запускаем его. На запрос программы вводим случайный набор символов или просто нажимаем Enter: программа выводит "Success!", чего и добивались


Или то, почему вы не можете издать свою улучшенную версию Counter Strike и уехать жить на Гавайи.

О чём речь?

Обфуска́ция (от английского obfuscate — делать неочевидным, запутанным, сбивать с толку) в широком смысле - приведение исходного текста или исполняемого кода программы к виду, сохраняющему её функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции.

Красивый пример из Википедии кода, прошедшего обфускацию.

Красивый пример из Википедии кода, прошедшего обфускацию.

Далее в программе

Зачем это нужно?

Как это должно работать?

Как это работает?

Состояние дел сейчас

Зачем это нужно?

Как известно, одним из основных методов взлома программного обеспечения является исследование кода, полученного в результате работы дизассемблера на предмет уязвимостей. На основе такого когда нетрудно, например, составить программу генерации ключей активации коммерческого программного обеспечения или, наоборот, внести в исполняемый файл изменение - патч, позволяющий злоумышленникам отключить "нежелательные" модули исходной программы.

Всему вышеперечисленному как раз и может противодействовать специальная программа - обфускатор.

Так же, алгоритмы обфускации активно используются не только для затруднения анализа кода, но и для уменьшения размера программного кода, что, в свою очередь, активно используется при разработке различных веб-сервисов и баз данных.

Как это должно работать?

Как понятно из вышесказанного, методы обфускации должны усложнить код, преобразовав его таким образом, чтобы скрыть от третьих лиц логику его работы.

В идеале хотелось бы, чтобы программа, прошедшая обфускацию, давала бы не больше информации нежели чёрный ящик, имитирующий поведение исходной программы. Гипотетический алгоритм, реализующий такое преобразование называется "Обфускация чёрного ящика". Декомпиляция зашифрованной таким образом программы дала бы злоумышленникам не больше информации, чем декомпиляция клиента мессенджера, представляющего собой лишь обёртку над апи "настоящего" приложения, что бы полностью решило поставленную в предыдущем блоке проблему. Однако показано [3] , что реализация такого алгоритма для произвольной программы невозможна.

Как это работает

Большинство методов обфускации преобразуют следующие аспектов кода:

• Данные: делают элементы кода похожими на то, чем они не являются

• Поток кода: выставляют исполняемую логику программы абсурдной или даже недетерминированной

• Структура формата: применяют различное форматирование данных, переименование идентификаторов, удаление комментариев кода и т.д.

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

При обфускации кода, важно правильно оценить, какие части когда можно эффективно запутать. Следует избегать обфускации кода, критичного относительно производительности.

Методы


1. Преобразование данных

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

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

2. Обфускация потока управления кодом

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

3. Обфускация адресов

Данный метод изменяет структура хранения данных, так чтобы усложнить их использование. Например алгоритм, может выбирать случайными адреса данных в памяти, а также относительные расстояния между различными элементами данных. Данный подход примечателен тем, что даже если злоумышленник и сможет "декодировать" данные, используемые приложением на каком-то конкретном устройстве, то на других устройствах он всё равно не сможет воспроизвести свой успех.

4. Регулярное обновление кода

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

5. Обфускация инструкций ассемблера

Преобразование и изменение ассемблерного когда также может затруднить процесс обратного инжиниринга. Одним из таких методов является использование перекрывающихся инструкций (jump-in-a-middle), в результате чего дизассемблер может произвести неправильный вывод. Ассемблерный код также может быть усилен против проникновения за счёт включения бесполезных управляющих операторов и прочего мусорного кода.

6. Обфускация отладочной информации

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

Заключение

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

Данная статья была написана в 2015 году, и мне не удалось найти в интернете существенного количества статей и иных материалов на тему моего поста, накопившихся за это время. На мой взгляд, в наш век всё большую популярность приобретает разработка всевозможных веб приложений, которые мало нуждаются в обфускации в качестве метода защиты информации. Однако как раз таки сжатие исходного кода программ, при помощи методов обфускации в таких приложениях зачастую оказывается полезным.

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


Ссылки и источники

[3] Barak B., Goldreich O., Impagliazzo R., Rudich S., Sahai A., Vadhan S. and Yang K. «On the (im) possibility of obfuscating programs.» CRYPTO 2001.

image

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

image

Для защиты я выбрал USB ключ с HID интерфейсом и с открытым кодом программного модуля защиты. Такой HID-ключ позволяет обойтись без установки драйверов ключа, что очень удобно для конечного пользователя. Также HID интерфейс прекрасно работает в «SafeMode» режимах загрузки операционных систем.
Открытый код модуля защиты – не нужно линковать библиотеки и прилагать к защищаемой программе чужие *.dll файлы.
Сам ключ содержит 5 участков памяти по 2 кБайта и RTC (часы с батарейкой), каждый участок защищен ПИН-кодом из 16 байт.

Цель защиты

— не запускать приложение при отсутствии ключа защиты;
— предупреждать и закрывать приложение при удалении ключа защиты.
Ограничивать время использования программы будем в следующий раз. Для построения защиты буду использовать один защищенный участок памяти в ключе.

Защищаемый объект

image

Для примера создадим самую простую программу: диалоговое окно MFC, воспользовавшись волшебником visual studio. В наше приложение, кроме потока окна, добавим поток, который в основном окне печатает текущее время.

Подготовка ключа

image

Прежде чем использовать ключ его необходимо сконфигурировать с помощью утилиты из SDK ключа:
— установить на защищенный участок памяти свой секретный ПИН код (заводские значения: ).
— заполнить необходимыми данными сам участок памяти.

ПИН я сменил на: < 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f >.
Такой же последовательностью заполнил первые 16 байт в памяти ключа.

Установка защиты

Для внедрения программного модуля защиты в созданный проект нужно подключить 2 файла: «HID_1.cpp» и «HID_1.h». В них находится исходный код класса, который позволяет обращаться к ключу.
В файле «HID_1.h» можно изменить настройки модуля, и параметры шины USB ключа — оставим все по умолчанию. Компилируем проект.

После успешной компиляции и запуска всё это выглядит так:

image

Теперь все готово для работы с ключом

В коде, где создается само окно приложения, файл «Example_1.cpp», добавляем обращение к ключу:

Код потока, следящего за ключом

.
volatile bool glob_exit_f = false;
.
DWORD WINAPI myThread_watchdog(LPVOID lParam)
BYTE my_main_pin[16] = ;
BYTE data_in_key[16] = ;
HID_bridge my_hid(
my_main_pin, //Указатель на массив ПИН-кода.
HID_DEFAULT_PROFILE_ID); //Устанвка номера профиля.
BYTE my_buf[16]; //буфер, в который будут считаны данные из ключа
int result = -1;
int answ = -1;
while(!glob_exit_f) <
answ = my_hid.read_closed_data_ex(
my_buf, // Указатель на буфер, в который сохранятся принятые данные профиля.
0, // Адрес в профиле, с которого начнется чтение, в данном случае чтение с самого начала профиля (с 0-го байта).
sizeof(my_buf)); // Количество байт, которое нужно прочесть. Размер буфера.
result = -1;
if(answ == HID_KEY_OK) < // анализируем ответ
// Если ключ найден и данные считаны - анализируем эти данные
// Данные, которые должны быть записаны в ключе:
BYTE data_in_key[16] = ;
result = memcmp(data_in_key, my_buf, sizeof(my_buf)); // Сравниваем полученные данные
>
if(result) glob_exit_f = true;
> else Sleep(WATCHDOG_SLEEP_TIME);
>
>
return 0;
>

В итоге

image

Поставленная задача защиты решена. Обращаю Ваше внимание, что это пример, в котором всё упрощено. Строить настоящую защиту на одном флаге, конечно же, не стоит. А хранить ПИН-код доступа как в примере — вообще преступление.
АПИ ключа намного шире, в данном примере я использовал лишь малую часть всех возможностей.

А что же происходит на шине USB?

image

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

image

image

Для меня важным показателем является время ответа ключа на команду. На рисунке «черным» выделена команда к ключу, «синим» — ответ ключа. В среднем время отклика составляет 32 мс (+31… +32 . ). Т.е. за это время ключ обработал команду и вернул ответ. Больших задержек это не вносит.

Криптографическая защита протокола обмена

image

image

HID пакеты на шине USB имеют длину 64 байта. Как сказано в описании ключа первые 32 байта этого пакета технологические, остальные 32 байта – шифрованные алгоритмом RC6, причем для каждой пары пакетов (TX-RX) ключ шифрования выбирается случайно. Этот временный ключ шифруется ключом, созданным на основе ПИН-кода, того самого в 16 байт, о котором написано выше.
Получается, что передача одной и той же команды ключу и получение одного и того же ответа приводит к абсолютно не связанным транзакциям на шине USB. Если кто-то решит анализировать трафик с целью написания табличного эмулятора, то он будет разочарован. Так как пары — (TX-RX) ни разу не повторяются.

Читайте также: