Как защитить код c

Обфусация кода, Защита от декомпиляции

Собственно, кто какие способы защиты от декомпиляции программы и кто какие способы обфуксации кода написанного на c# знает?

Vadim Ovchinnikov's user avatar

Но я вижу, что здесь только издеваются, так что, закройте кто-нибудь тему

@MadKeks никто над вами не издевается, не преувеличивайте. Дело в том, что необходимость в обфускации программ на C# сама по себе довольно сомнительна — очень существенная часть C# кода — это веб-приложения, веб-сервисы и прочий код, который работает на сервере, а следовательно, конечный пользователь его не видит и покопаться в нем не сможет даже с помощью ildasm’a или Reflector’a. Большая часть оставшегося софта — это программы, используемые очень ограниченным кругом лиц (внутрикорпоративные десктоп-приложения например), а следовательно, никому не придет в голову воровать их исходный код, не представляющий особой ценности. К примеру, на своей первой работе я получил в сопровождение кучу адского говнокода, нарушающего все возможные и невозможные каноны чистоты кода и в каккой-то степени благодаря этому уже являвшийся обфусцированным (справедливости ради, мои навыки на тот момент как раз того и стоили — из под моих пальцев вытекал точно такой же кривой говнокод). Так вот что тогда, что сейчас я бы не только не стал этот код воровать с помощью декомпиляции, я бы не стал брать его даже даром из исходников.

В подобной защите, вероятно, нуждается серьезное проприетарное ПО, скажем, какой-нибудь Photoshop, но оно на C# обычно не пишется.

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

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

Впрочем, при желании материалов на эту тему можно найти достаточно. Например вот и вот

UPD

Стоит кстати заметить, что обфускация во многом зависит от средств конкретного языка

Защищаем приложение, написанное на C#

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

К сожалению, дотнетовские программы, равно как джавовские, довольно-таки просто «вскрыть». Виной всему байт-код, позволяющий специальными программами легко дизассемблировать и воссоздать первоначальный код. Далеко ходить не нужно за примерами, так как даже VS поставляется с дизассемблером ILDasm.

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

Методы защиты C# приложения

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

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

Как я уже писал, главная проблема дотнетовских программ, равно как джавашных – легкий способ получения исходников. Да, получить исходный код сейчас просто плевое дело. Например, можно воспользоваться бесплатным dotPeek от JetBrains. Фактически, основанный на базе известного Resharper от этой же студии, данный инструмент позволяет легко и непринужденно вскрыть внутренности исследуемой программы, если незадачливый программист не позаботился о ее своевременной защите.

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

  • Декомпиляция сборок .NET версий в исходный код C# и IL-код

Для отображения декомпилированного кода dotPeek использует большинство функций, привычных пользователям Microsoft Visual Studio: открытие декомпилированных файлов в отдельных вкладках, подсветка синтаксиса, сворачивание блоков кода, нумерация строк и многое другое.

2) Преобразование и экспорт сборок .NET в проекты Microsoft Visual Studio

Если вы хотите не только исследовать сборку, но и внести в нее изменения, dotPeek позволит вам преобразовать и сохранить ее в проект Microsoft Visual Studio и, таким образом, продолжить работу уже с исходным кодом сборки.

Занятная тулза, не так ли? Но самое главное – dotPeek абсолютно бесплатный, в отличие от «дедушки» .NET Reflector, который раньше был едва ли не стандартом де-факто для декомпиляции дотнетовских приложений. Так как вам все равно нужно будет смотреть то, насколько хорошо вы защитили свое приложение, то dotPeek должен быть у вас всегда. Скачать его можно на сайте https://jetbrains.ru/products/dotpeek/

Естественно, что когда все знают о том, что программу на C# может «взломать» любой, способный крякнуть игру, начинается шевеление и волнение. В итоге, нужно устранить очевидные проблемы в защите.

  • Как бы это банально не звучало, но для начала сделаем обфускациюприложения. Иными словами, мы максимально запутаем исходный код, но сохраним функциональность. Достаточно действенный способ, если бы не одно «но» — на публичные обфускаторы есть масса деобфускаторов. Кроме того, основная масса обфускаторов платные. Вы без труда найдете обзоры наиболее «распиаренных». Могу лишь сказать, что часто их функционал оставляет желать лучшего. Иногда после такой обфускации программа может даже перестать нормально работать, особенно, если вы прошлись по ней взломанным обфускатором. Конечно, Майкрософт в свои студии разработки вставляла бесплатный Dotfuscator Software Services.

  • Вернее, он бесплатный только для личного использования, для бизнеса он стоит ну очень много убитых енотов. Он уже интегрирован в Visual Studio. Честно, помню недовольные отзывы о нем в плане неочевидности и прочего, но как по мне, пользоваться им достаточно просто. Да, есть хромые места, но идеальных обфускаторов, думаю вообще не существует. В любом случае, начните хотя бы с него. По крайней мере, у него есть также и защита от отладки. Для новичков он будет весьма и весьма кстати.

Еще один обфускатор, который лично мне нравится – это пресловутый ConfuserEx. Он опенсорсный и дает весьма сильную защиту. Например, можете увидеть то, как он «путает» код и не дает прочитать его с помощью еще одного исследователя ILSpy.

Скачать его можете на https://yck1509.github.io/ConfuserEx/. Тем не менее, его можно все же снять небезызвестным De4dot, при условии, что реверсер его правильно определит, имейте это в виду.

2 ) Крипторы и пакеры. На самом деле, хотя и дают сильную защиту, но большинство проектов попросту брошены или они стоят безумно больших денег. Поэтому на них я останавливаться не стану.

3) Новые студии разработки (начиная с 2015) меня больше радуют. Майкрософт разработала технологию .NET Native, позволяющую скомпилировать дотнетовское приложение в нативный код.

А вот этот момент весьма и весьма интересен, так как для реверсера предстанет весьма любопытный плюсовский код, «приправленный» автоматическим кодом AOT-компилятором .NET. Это очень усложнит задачу по взлому и реверсингу приложения. Фактически, я бы посоветовал его. Но проблема есть и у этого способа – все будет только работать на майкрософтовской платформе.

Резюме

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

C# приложения были изначально уязвимы для реверсинга. В этом плане, они не сильно далеко ушли даже от того же JS, хотя там вообще все очевидно. Обфускация запутает код и инструменты типа dotPeek или ILSpy. Но важно понимать, что все они обрасли дополнительными плагинами, которые позволяют определить защиту и всячески ее снять. Тем не менее, пренебрегать ими не стоит.

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

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

Русские Блоги

C # упаковщики инструменты, чтобы сделать защиту шифрования кода

В настоящее время сфера применения C # .net язык все более и более широко, IIS архитектура сервера с выделенным кодом, WinForm приложений для настольных компьютеров, логические сценарии Unity3D используются. C # .net с мощными и удобными функциями, которые делают стоимость разработки является очень низкой. Как язык .net, но и позволяют разработчик головных болей недугов — очень легко декомпилировать. Рынок Dnspy, ILspy, de4dot и другие инструменты могут быть очень легко декомпилировать путать защищенный C # .net программы.

решение

Думая делать независимую защиту исследований для C # .net языка оболочки: Virbox Protector версию .NET. C # .net скомпилированы в выполнении программы (.exe), динамически подключаемой библиотеки (DLL) непосредственно втянута в пакера для завершения операции защиты, это очень удобно. Источник и имеет не видеть влияния на логику. Быть

Virbox Protector Шифрование Особенности

Имя спутанность (.NET)

Метод .net имен с использованием случайной строки имени класса для переименования, экспорта и внешнее имя не изменится.

рендеры защиты

Защита перед тем, как показано на рисунке:

После защиты, как показано ниже:

компрессия

Virbox Protector сжатия, его основной целью является не «компресс» не предназначен для уменьшения объема и разработки программ. Это на самом деле роль кода и данных сегментов сделать шифрование, а оригинал таблицы импорта и перемещение скрытие информации, а затем «путь», чтобы сделать оригинальное сжатие данных.

принцип

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

Функции

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

преимущество

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

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

рендеры защиты

Защита перед тем, как показано на рисунке:

После защиты, как показано ниже:

Удалить сильную подпись

1, сильное имя (StrongName) в .NET обеспечивает механизм аутентификации, включая оригинальный автор определяет версию и идентичность.

2, сильное имя может быть использовано для помочь пользователям получить свои собственные процедуры, чтобы проверить, писал ли первоначальный автор срез не был изменен (например, добавление вредоносного кода), с самоконтролем несколько похоже.

3, таким образом, добавляя сильное имя, которое будет удалены, когда программа сильных имен пакеры и повторно пакеры после добавления строгого имени.

Уровень защиты Функция — Код шифрования

принцип

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

Функции

Анти артобстрел, чтобы предотвратить прямой Dump.

преимущество

1, высокая эффективность, практически без потери производительности.

рендеры защиты

Защита перед тем, как показано на рисунке:

После защиты, как показано ниже:

Код запутывания

принцип

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

поддержка Virbox протектор для x86 / ARM / .net иль серий инструкций запутанных.

Безопасность доступа кода

XYZ School

Чем важна модель безопасности доступа кода (Code Access Security)? С помощью модели безопасности на основе ролей можно указывать, что разрешено делать пользователю, а с помощью модели безопасности доступа кода — что разрешено делать коду. В .NET 4 эта модель упростилась, благодаря удалению необходимости в настройке сложных политик безопасности и добавлению второго уровня прозрачной безопасности (Security Transparency Level 2). Один такой уровень существовал и ранее, а второй является нововведением .NET 4.

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

Критичный для безопасности код (Security-Critical Code)

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

Безопасный код (Safe-Critical Code)

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

Прозрачный код

В рамках этого кода может выполняться очень ограниченное число операций. Этому коду разрешено выполняться только с определенным набором разрешений и только в песочнице (sandbox). В нем не может содержаться никакого небезопасного или непроверяемого кода и вызываться критичный для безопасности код. При написании Windows-приложений ограничение прав кода не применяется.

Приложения, выполняющиеся в настольной среде, обладают всеми привилегиями доверия и могут содержать любой код. Технология изоляции кода на время выполнения в называемую песочницей (sandbox) ограниченную среду применяется с приложениями SilverLight, а также приложениями ASP.NET, которые обслуживаются веб-провайдером или обладают специфической функциональностью, например, предусматривают запуск дополнительных надстроек за счет использования Managed Add-In Framework.

Второй уровень прозрачной безопасности

Сборку можно снабжать атрибутом SecurityRules и устанавливать для него значение SecurityRuleSet.Level2 для применения нового уровня прозрачности, который доступен в .NET 4. (По умолчанию в .NET 4 используется именно этот уровень.) Для обеспечения обратной совместимости для него следует установить значение Level1:

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

Атрибут AllowPartiallyTrustedCallers позволяет сделать код чем-то средним между прозрачным кодом и кодом остальных категорий. В случае применения этого атрибута код по умолчанию интерпретируется как прозрачный, но отдельные типы или члены внутри него могут иметь и другие атрибуты:

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

Полномочия

В случае выполнения кода внутри песочницы указывать, что коду разрешено делать, можно в самой песочнице за счет определения полномочий .NET. Если приложениям, запущенным в настольной среде, предоставляется полный набор полномочий, который позволяет им предпринимать любые действия, то приложениям, выполняющимся в песочнице, предоставляется лишь набор полномочий, который главная среда (хост) передает песочнице и который позволяет выполнять лишь определенные действия. Можно также определять полномочия для домена приложений, запускаемого из настольных приложений. Для этого должен использоваться API-интерфейс Sandbox.

Под полномочиями, или разрешениями, понимаются действия, которые разрешается (или запрещается) выполнять каждой группе кода. Например, полномочия могут включать в себя «чтение файлов из файловой системы», «выполнение операций записи в Active Directory» и «использование сокетов для открытия сетевых соединений». Есть несколько предопределенных полномочий, и можно также создавать собственные.

Полномочия .NET не зависят от разрешений операционной системы. Полномочия .NET просто проверяются исполняющей средой. Сборка требует выдачи полномочия для выполнения определенной операции (например, класс File требует выдачи полномочия FileIOPermission), а среда CLR проверяет, чтобы сборке было выдано необходимое полномочие, и она могла продолжить свою работу.

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

Позволяет управлять возможностью получать доступ к Active Directory с помощью классов System.DirectoryServices.

DnsPermission

Позволяет управлять возможностью использования DNS (Domain Name System — служба имен доменов).

EnvironmentPermission

Позволяет управлять возможностью выполнять чтение и запись в переменных среды.

EventLogPermission

Позволяет управлять возможностью выполнять операции чтения и записи в журнале событий.

FileDialogPemission

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

FileIOPermission

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

IsolatedStorageFilePermission

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

IsolatedStoragePermission

Позволяет управлять возможностью доступа к изолированным хранилищам, т.е. хранилищам, ассоциируемым с отдельными пользователями и имеющими какие-то идентификационные данные в коде.

MessageQueuePermission

Позволяет управлять возможностью использования очереди сообщений через службу Microsoft Message Queue.

PerformanceCounterPermission

Позволяет управлять возможностью использования счетчиков производительности.

PrintingPermission

Позволяет управлять возможностью выполнения печати.

ReflectionPermission

Позволяет управлять возможностью обнаружения информации о типах во время выполнения с использованием класса System.Reflection.

RegistryPermission

Позволяет управлять возможностью чтения, записи, создания и удаления разделов и параметров в системном реестре.

SecurityPermission

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

ServiceControllerPermission

Позволяет управлять возможностью осуществлять управление службами Windows.

Socket Permission

Позволяет управлять возможностью создания или приема соединений TCP/IP по сетевому транспортному адресу.

SQLClientPermission

Позволяет управлять возможностью доступа к базам данных SQL Server с помощью предусмотренного в .NET поставщика данных для SQL Server.

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

Наборы полномочий

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

Назначение полномочий группам кода избавляет от необходимости иметь дело с одиночными полномочиями и позволяет применять полномочия сразу целыми блоками, для чего в .NET и предусмотрена концепция наборов полномочий. Эти наборы, по сути, представляют собой списки предоставляемых коду прав, объединенные в именованный набор. Ниже приведено краткое описание семи именованных наборов полномочий, которые поставляются в .NET изначально:

Тип полномочия Описание
FullTrust Подразумевает отсутствие всяких ограничений в полномочиях.
SkipVerification Подразумевает обход верификации.
Execution Позволяет коду выполняться, но не получать доступ ни к каким защищенным ресурсам.
Nothing Не предоставляет коду никаких полномочий и не позволяет ему выполняться.
Local Intranet Предоставляет лишь подмножество из полного набора полномочий. Например, операции файлового ввода-вывода ограничиваются возможностью доступа только для чтения к общему ресурсу, который является источником сборки. В .NET 3.5 и более ранних выпусках (до появления .NET 3.5 с пакетом обновлений SP1) этот набор полномочий применялся в случае выполнения приложения из сетевого общего ресурса.
Internet Предусматривает использование стандартной политики безопасности для кода неизвестного происхождения. Из всех перечисленных наборов полномочий этот является самым ограниченным. Например, коду, выполняющемуся в рамках этого набора полномочий, не разрешены ни файловые операции ввода-вывода, ни операций чтения и записи журнала событий, ни операции чтения и записи переменных среды.
Everything Предусматривает выдачу всех перечисленных выше полномочий за исключением SkipVerification. Администратор может изменять любое из полномочий в этом наборе. Это удобно, если необходимо ужесточить стандартную политику безопасности.

Важно обратить внимание на то, что изменять определения полномочий можно только в наборе Everything (Все); остальные наборы являются фиксированными и изменяться не могут. Разумеется, можно создавать и собственные наборы полномочий.

Запрос полномочий программным образом

Сборка может запрашивать полномочия как декларативным, так и программным образом. В следующем фрагменте кода показано, как запрашивать полномочия с помощью метода DemandFileIOPermissions(). После импорта пространства имен System.Security.Permisions можно выполнять проверку на предмет наличия необходимых полномочий, создавая объект FileIOPermission и вызывая его метод Demand().

Этот метод позволяет проверить, есть ли у кода, вызывающего метод, в данном случае — DemandFileIOPermissions, необходимые полномочия. Если метод Demand() завершается неудачей, генерируется исключение типа SecurityException. Это исключение можно не перехватывать, и предоставлять его обработку вызывающему коду.

Класс FileIOPermission содержится внутри пространства имен System.Security.Permisions, в котором определен полный набор полномочий, а также классы для декларативных атрибутов полномочий и перечисления для параметров, применяемых для создания объектов полномочий (например, создания объекта FileIOPermission, указывающего, требуется доступ только для чтения или же полный доступ).

Для перехвата исключений, генерируемых исполняющей средой CLR, когда код пытается выполнить какие-то противоречащие выданным ему полномочиям действия, можно организовать перехват исключения типа SecurityException. Это исключение предоставляет доступ к набору полезных фрагментов информации, в том числе читабельной трассировке стека (SecurityException.StackTrace) и ссылке на метод, который привел к выдаче исключения (SecurityException.TargetSite). Вдобавок SecurityException предоставляет свойство SecurityException.PermissionType, которое возвращает информацию о типе объекта Permission, вызвавшего генерацию исключения.

В случае применения только классов .NET для операций файлового ввода и вывода самостоятельно запрашивать FileIOPermission не обязательно, поскольку классы .NET, позволяющие производить такие операции, умеют делать это сами. Однако при создании оболочек для вызова собственных методов API-интерфейса, таких как CreateFileTransacted(), его нужно запрашивать самостоятельно. Этот механизм также можно применять для запроса специальных полномочий у вызывающего кода.

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

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