Выполнить данные как код? - PullRequest
5 голосов
/ 15 августа 2010

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

Итак, я накопил свои знания о переносимых исполняемых файлах и пришел с такой идеей:

  • Шифрование исполняемого файла
  • Прикрепите это к концу исполняемого файлавместе с его размером
  • Загрузчик дешифрует данные
  • Копирует код на страницу, выделенную для VirtualAlloc с правами на выполнение
  • Он находит точку входа приложения
  • Прыжки туда и все готово.

У меня проблема с тем, как прыгать туда.Как я могу это сделать?Если бы я установил указатель на функцию, какой была бы подпись?Подпись функции main () загруженного исполняемого файла?Или мне нужно прибегнуть к сборке?

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

Редактировать: Работа с окнами и компиляция с GCC.При необходимости я могу переключить компилятор Microsoft.

Edit2: Чтобы уточнить: я ЗНАЮ, что в основном это бессмысленно.Я считаю, что это означает любой вид DRM.Это зависит от моего клиента, и он все еще хочет этого, несмотря на то, что я предупреждаю его об этом.

Заранее спасибо.

Ответы [ 8 ]

11 голосов
/ 15 августа 2010

К сожалению, переход к точке входа вашего кода - это наименьшее количество ваших забот.Файл Portable Executable (PE) (формат файлов, используемый для файлов EXE и DLL в Windows) - это не то, что вы можете просто загрузить в один блок памяти и затем запустить.Ваш пользовательский загрузчик PE должен позаботиться о следующих заданиях:

  • Загрузка различных разделов кода и данных в файле PE в отдельные блоки памяти.

  • Разрешение зависимостей из таблицы импорта для загрузки библиотек DLL, от которых зависит ваш EXE-файл.

  • Выполнение перемещений.

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

Редактировать: Google быстро предлагает вам взглянуть на следующее:

  • EXECryptor (фирменный)

  • RLPack (фирменный)

  • UPX (GPL) Этот, насколько я понимаю, выполняет сжатие, но вы можете использовать Источник для добавления шифрования (если GPL совместим с вашими потребностями).

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

Еще одно редактирование:

В журнале MSDN опубликована статья Мэтта Питрека под названием «В-Глубокий анализ формата исполняемых файлов Win32 "( Часть 1 , Часть 2 ).Он содержит много информации о формате файла PE, которая должна быть полезной для вас.Один интересный момент: последние версии компоновщика Microsoft, по-видимому, по умолчанию исключают базовые перемещения для EXE-файлов.Вы, вероятно, захотите дать указание компоновщику вставить их обратно, поскольку вполне вероятно, что ваш EXE-файл оболочки уже загружен по предпочтительному адресу загрузки вашего полезного файла EXE.В качестве альтернативы, вы можете попытаться дать вашему EXE-обертке экзотический предпочтительный адрес загрузки, который, как мы надеемся, не будет мешать полезной нагрузке EXE.

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

4 голосов
/ 15 августа 2010

Как уже упоминали другие, простая загрузка всего EXE-файла в раздел данных и связывание его во время выполнения - сложная задача; тем не менее, вот еще один вариант.

Возьмите ваш ввод EXE; найти его код и инициализированные данные (в том числе постоянные) разделы. Переименуйте эти разделы и преобразуйте их в разделы инициализированных данных для чтения и записи; зашифровать содержимое. Теперь добавьте новый сегмент кода, содержащий вашу заглушку расшифровки, и измените точку входа там. Эта заглушка должна расшифровать сегменты на месте, затем изменить их защиту на подходящую для их типа и перейти к исходной точке входа.

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

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

4 голосов
/ 15 августа 2010

В дополнение ко всем хлопотам по поводу правильной загрузки PE-образа вам также нужно будет позаботиться о Data Execution Protection , которая предназначена для предотвращения подобных действий.

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

1 голос
/ 17 августа 2010

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

1 голос
/ 15 августа 2010

Загрузчик расшифровывает данные

Это говорит само за себя.

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

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

Может быть, это то, что вы подразумеваете под "ложным чувством безопасности"?

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

1 голос
/ 15 августа 2010

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

Я думаю, вы можете сделать что-то вроде:

  1. Транспортируйте зашифрованный файл dll с вашей секретной сборкой
  2. Зашифруйте ее в каталоге tmp
  3. do LoadLibrary на этом
  4. Разблокировать файл DLL и удалить из системы?
0 голосов
/ 15 августа 2010

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

0 голосов
/ 15 августа 2010

Вы должны быть в состоянии c-style привести ваш адрес к указателю на функцию и вызвать его:

typedef void (*MyPtr)();

MyPtr p = (MyPtr)1234;
p();
...