Защита исполняемого файла от обратного инжиниринга? - PullRequest
200 голосов
/ 26 июня 2011

Я размышлял, как защитить мой код C / C ++ от разборки и обратного инжиниринга. Обычно я никогда не потворствую этому поведению в своем коде; однако текущий протокол, над которым я работал, никогда не должен быть проверен или понятен для безопасности различных людей.

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

Некоторые вещи, о которых я думал до сих пор:

  • Внедрение кода (вызов фиктивных функций до и после фактических вызовов функций)
  • Обфускация кода (искажение двоичного кода)
  • Напишите мои собственные процедуры запуска (сложнее привязать отладчики)

    void startup();  
    int _start()   
    {  
        startup( );  
        exit   (0)   
    }  
    void startup()  
    {  
        /* code here */  
    }
    
  • Проверка времени выполнения для отладчиков (и принудительное завершение при обнаружении)

  • Функциональные батуты

     void trampoline(void (*fnptr)(), bool ping = false)  
     {  
       if(ping)  
         fnptr();  
       else  
         trampoline(fnptr, true);  
     }
    
  • Бессмысленные распределения и освобождения (стек сильно меняется)

  • Бессмысленные фиктивные звонки и батуты (тонны прыжков на выходе разборки)
  • Тонны литья (для запутанной разборки)

Я имею в виду, что это некоторые из вещей, о которых я думал, но все они могут быть обойдены и / или выяснены аналитиками кода при условии правильных временных рамок. Есть ли у меня что-нибудь еще?

Ответы [ 24 ]

170 голосов
/ 26 июня 2011

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

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

146 голосов
/ 26 июня 2011

То, что сказала Эмбер, совершенно верно.Вы можете сделать реверс-инжиниринг сложнее, но вы никогда не сможете предотвратить это.Вы никогда не должны доверять "безопасности", которая опирается на предотвращение обратного инжиниринга .

При этом лучшие методы анти-обратного инжиниринга, которые я видел, были направлены не на запутывание кода, но вместо того, чтобы ломать инструменты, которые люди обычно используют, чтобы понять, как работает код.Поиск творческих способов взломать дизассемблеры, отладчики и т. Д., Скорее всего, будет более эффективным, а также более интеллектуально удовлетворяющим, чем просто создание множества ужасного кода спагетти.Это никак не блокирует решительного нападающего, но увеличивает вероятность того, что J Random Cracker уйдет и вместо этого будет работать над чем-то более простым.

40 голосов
/ 26 июня 2011

Safe Net Sentinel (ранее Аладдин). Однако, предостережения - их API отстой, документация отстой, и то и другое великолепно по сравнению с их инструментами SDK.

Я использовал их аппаратный метод защиты ( Sentinel HASP HL ​​) в течение многих лет. Для этого требуется запатентованный USB-брелок, который действует как «лицензия» для программного обеспечения. Их SDK шифрует и запутывает ваш исполняемый файл и библиотеки и позволяет связывать различные функции в вашем приложении с функциями, записанными в ключе. Без ключа USB, предоставленного и активированного лицензиаром, программное обеспечение не может расшифровать и, следовательно, не будет работать. Ключ даже использует настраиваемый протокол связи USB (вне моей компетенции, я не специалист по драйверам устройств), чтобы затруднить создание виртуального ключа или вмешательство в связь между оболочкой времени выполнения и ключом. Их SDK не очень удобен для разработчиков, и довольно сложно интегрировать добавленную защиту с автоматическим процессом сборки (но возможно).

До того, как мы внедрили защиту HASP HL, было 7 известных пиратов, которые сняли «защиту» dotfuscator с продукта. Мы добавили защиту HASP в то же время, что и серьезное обновление программного обеспечения, которое выполняет тяжелые вычисления на видео в реальном времени. Как я могу судить по профилированию и бенчмаркингу, защита HASP HL ​​только замедлила интенсивные вычисления примерно на 3%. С тех пор, как это программное обеспечение было выпущено около 5 лет назад, не было найдено ни одного нового пиратского продукта. Программное обеспечение, которое оно защищает, пользуется большим спросом в своем сегменте рынка, и клиенту известно о нескольких конкурентах, активно пытающихся провести реинжиниринг (пока безуспешно). Мы знаем, что они пытались получить помощь от нескольких групп в России, которые рекламируют услугу по нарушению защиты программного обеспечения, поскольку многочисленные публикации в различных группах новостей и форумах включали более новые версии защищенного продукта.

Недавно мы опробовали их решение по лицензированию программного обеспечения (HASP SL) для небольшого проекта, который был достаточно прост, чтобы начать работать, если вы уже знакомы с продуктом HL. Кажется, работает; не было зарегистрировано случаев пиратства, но спрос на этот продукт намного ниже ..

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

21 голосов
/ 27 июня 2011

Взять, к примеру, алгоритм AES . Это очень, очень публичный алгоритм, и он ОЧЕНЬ безопасен. Зачем? Две причины: он был рассмотрен многими умными людьми, и «секретная» часть - это не сам алгоритм - секретная часть - это ключ, который является одним из входных данных алгоритма. Это гораздо лучший подход для разработки вашего протокола с использованием сгенерированного «секрета», который находится за пределами вашего кода, а не для того, чтобы сделать сам код секретным. Код всегда можно интерпретировать независимо от того, что вы делаете, и (в идеале) сгенерированный секрет может быть поставлен под угрозу только в результате грубого перебора или кражи.

Мне кажется, интересный вопрос: " Почему Вы хотите запутать свой код?" Вы хотите, чтобы злоумышленникам было трудно взломать ваши алгоритмы? Чтобы им было труднее находить уязвимые ошибки в вашем коде? Вам не нужно было бы запутывать код, если бы код был изначально не взломанным. Корень проблемы - взломанное программное обеспечение. Исправьте корень вашей проблемы, не запутывайте ее.

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

21 голосов
/ 26 июня 2011

Лучшие приемы против дизассемблера, в частности, для наборов команд с переменной длиной слова, содержатся в ассемблере / машинном коде, а не в C. Например,

CLC
BCC over
.byte 0x09
over:

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

Я думаю, что это было в начале «Языка ассемблера» Майкла Абраша, где он показал простой трюк против дизассемблера и отладчика.У 8088/6 была очередь предварительной выборки, у вас была инструкция, которая изменила следующую инструкцию или пару вперед.Если пошагово, то вы выполнили модифицированную инструкцию, если симулятор набора команд не полностью имитировал оборудование, вы выполнили измененную инструкцию.На реальном оборудовании, работающем нормально, настоящая инструкция уже будет в очереди, и измененное расположение в памяти не повредит, если вы не выполняете эту строку инструкций снова.Возможно, вы все еще можете использовать такой трюк сегодня, когда конвейерные процессоры получают следующую инструкцию.Или, если вы знаете, что аппаратное обеспечение имеет отдельный кеш инструкций и данных, вы можете изменить количество байтов вперед, если вы правильно выровняете этот код в строке кеша, модифицированный байт будет записан не в кеш инструкций, а в кеш данных, иИмитатор набора команд, который не имел надлежащих имитаторов кэша, не сможет работать должным образом.Я думаю, что только программные решения не помогут вам продвинуться далеко вперед.

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

Раньше хакеры бралиоколо 18 месяцев, чтобы что-то придумать, например, DVD.Сейчас они составляют в среднем от 2 дней до 2 недель (если мотивированы) (синий луч, iphones и т. Д.).Это значит для меня, что если я потрачу на безопасность более нескольких дней, я, скорее всего, потрачу впустую свое время.Единственная реальная защита, которую вы получите, - это аппаратное обеспечение (например, ваши инструкции зашифрованы, и только ядро ​​процессора, находящееся внутри чипа, дешифрует непосредственно перед выполнением, так что оно не может раскрыть расшифрованные инструкции).Это может купить вам месяцы вместо дней.

Также прочитайте книгу Кевина Митника «Искусство обмана».Такой человек может взять трубку и попросить вас или коллегу передать секреты системы, думая, что это менеджер, другой сотрудник или инженер по аппаратному обеспечению в другой части компании.И ваша безопасность взорвана.Безопасность - это не только управление технологиями, но и управление людьми.

19 голосов
/ 26 июня 2011

Создание кода, затрудняющего обратное проектирование, называется обфускацией кода.

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

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

a = useless_computation();
a = 42;

сделать это:

a = complicated_computation_that_uses_many_inputs_but_always_returns_42();

Или вместо этого:

if (running_under_a_debugger()) abort();
a = 42;

Сделайте это (где running_under_a_debugger не должно быть легко идентифицируемым как функция, которая проверяет, выполняется ли код под отладчиком - она ​​должна смешивать полезные вычисления с обнаружением отладчика):

a = 42 - running_under_a_debugger();

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

some_function();

сделайте это, когда вам случится узнать точное ожидаемое расположение битов в some_data_structure:

goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT;

Если высерьезно относитесь к запутыванию, добавьте несколько месяцев к своему планированию;запутывание не дается дешево.И учтите, что лучший способ избежать перепроектирования вашего кода - это сделать его бесполезным, чтобы он не беспокоился.Это простое экономическое соображение: они перепроектируют, если ценность для них будет больше, чем стоимость;но повышение их стоимости также значительно увеличивает ваши затраты, поэтому попробуйте снизить их стоимость.

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

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

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

Рекомендуемое чтение:

12 голосов
/ 26 июня 2011

Во многих случаях страх того, что ваш продукт может быть переработан, неуместен. Да, это может быть перепроектировано; но станет ли он настолько известным в течение короткого периода времени, что хакеры найдут, что стоит поменять его. это? (эта работа - не малое время, для существенных строк кода).

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

ИМХО, примите основные меры предосторожности, которые вы собираетесь предпринять, и отпустите его. Если это станет точкой обратного инжиниринга, означающей, что вы проделали действительно хорошую работу, вы сами найдете лучшие способы ее преодоления. Удачи.

11 голосов
/ 26 июня 2011

Прочитайте http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against. Я уверен, что другие, вероятно, также могли бы дать лучшие источники того, почему безопасность из-за неясности - это плохо.

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

7 голосов
/ 27 июня 2011

Чтобы узнать себя, прочитайте академическую литературу по коду запутывания . Кристиан Коллберг из Университета Аризоны является авторитетным ученым в этой области; Салил Вадхан из Гарвардского университета также проделал хорошую работу.

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

7 голосов
/ 01 марта 2014

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

В этой статье Quanta Magazine и в этой статье IEEE Spectrum .

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

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

...