Как разблокировать аккаунты, защитить компьютер и стать хакером
Полезные инструменты

Ваш IP

Узнай свой IP адрес

Проверить сайт

Test tools by WebSitePulse

Генератор MD5

1. Введите строку Строка:


2. Копировать MD5:

Реклама

интернетконецформыначалоформыПрим редактора: Реальное название статьи — «защита игр от взлома», но игра — это тоже программа, а значит и защищают их аналогично
Обычно о защите вспоминают в последний момент, перед самой сдачей проекта. Дописывают код впопыхах, а потом удивляются, почему взломанные версии доходят до рынка раньше официальных. Защита должна быть глубоко интегрирована в программу и должна разрабатываться заранее. То же самое скажет любой эксперт. Однако если к защите подходят вот таким, должным образом, к багам самой программы добавляются глюки защиты и проект рискует не уложиться в срок. Кроме того, неясно, как отлаживать программу, если она доверху нашпигована антиотладочными приемами и активно сопротивляется отладчику.
Лучше всего реализовать защитный механизм в виде модулей, готовых к интеграции в программу в любой момент. Рабочая версия вместо защитных функций вызывает процедуры-пустышки, заменяемые в финальной версии реальным кодом. О том, как проектировать эти модули, и поговорим.
Арсенал защиты
Вот три кита, на которых держатся защитные механизмы: машинный код, шифровка и p-код. Электронные ключи и прочие экзотические технологии этого типа здесь не рассматриваются. Массовая продукция именитых фирм давно взломана, а разработка собственного ключа с нуля — занятие не для слабонервных, к тому же он будет выгодным только при серийном производстве, иначе защита даже не окупится.
Аппаратная защита — совсем другой разговор. При желании в микрочип можно перенести программу даже целиком, и тогда никто не сможет скопировать (если, конечно, выбрать правильный чип). Однако процесс разработки и отладки усложняется в десятки и даже сотни раз, «железное обеспечение» получается крайне негибким, неудобным в тиражировании и распространении, не говоря уже о невозможности исправить обнаруженные ошибки. Даже если чип имеет перепрошиваемое ПЗУ, разрешение на запись равносильно разрешению на чтение, так как самое ценное в железе — это прошивка. Скопировать железо намного проще, чем выдрать из защищенного чипа прошивку, если же она будет свободно распространяться как обновление… Можно, конечно, распространять не всю прошивку, а только измененные модули или даже их части. Что сделает хакер? Он просто создаст слегка модифицированный модуль, считывающий содержимое ПЗУ и выводящий его наружу контрабандным путем.
Защиты, о которых будем говорить, не требуют никакого дополнительного железа, они системно независимы, работают на прикладном уровне и не требуют прав администратора. Никаких драйверов! Никакого ассемблера! Возможно ли эффективно противостоять опытным хакерам в таких условиях? Возможно! Большинство защит ломаются из-за досадных ошибок и мелких конструктивных просчетов, допущенных разработчиком, который никогда не заглядывал в дизассемблерный листинг и не пытался взломать свое творение.
Тайники машинного кода
Сокрытие алгоритма в машинном коде — широко распространенный, но неэффективный защитный примем. Понятно, что дизассемблерный листинг — это не исходный код и одна строка на языке высокого уровня может транслироваться в десятки машинных команд, часто перемешанных. К тому же в двоичном файле нет комментариев, зато все остальное очень даже встречается: структура классов, имена функций/переменных…
Текстовые строки
ASCII- и UNICODE-строки несут в себе очень богатую информацию: и текстовые сообщения, выводимые на экран при регистрации/окончании trial-срока/неправильном вводе пароля, и ветви реестра, и имена ключевых файлов, иногда и сами серийные номера/пароли. С паролями все ясно. Хранить их в открытом виде нельзя, нужно хэшировать их. А что плохого в текстовых сообщениях? Обнаружив их в теле программы, хакер по перекрестным ссылкам очень быстро найдет тот код, выводящий их, — вот что плохо. То же самое относится и к именам ключевых файлов с ветвями реестра.
Листинг
текстовая строка «wrong s/n» с перекрестной ссылкой, ведущей к процедуре sub_401000
.text:00401016 call sub_401000
.text:0040101B add esp, 4
.text:0040101E test eax, eax
.text:00401020 jz short loc_40102F
.text:00401022 push offset aWrongSN ; «wrong s/n\n» ; указатель на строку
.text:00401027 call _printf
..
.data:00406030 aWrongSN db ‘wrong s/n’,0Ah,0 ; DATA XREF: 00401022h^o
Чтобы затруднить анализ, необходимо либо зашифровать все строки, расшифровывая только перед непосредственным употреблением (если расшифровать сразу же после запуска программы, хакер просто снимет дамп и увидит их в виде прямого текста), либо поместить их в ресурсы и грузить через LoadString — это программируется легче, но в то же время легче ломается. Хакеру достаточно открыть файл в любом редакторе ресурсов, найти нужную строку, запомнить ее идентификатор, запустить отладчик и установить условную точку останова. Далее — дождаться вызова LoadString с нужным uID, определить адрес буфера lpBuffer, установить на него точку останова и… если lpBuffer выводится не сразу, а передается через цепочку промежуточных буферов, хакер матерится, но ничего не делает, потому что не может сделать ничего. Аппаратных точек останова всего четыре, и если защита использует не последний буфер в цепочке, то отследить момент реального обращения к строке становится невозможно (на самом деле возможно: с помощью секретного хакерского оружия NO_ACCESS на страницу, только об этом не все знают).
В дизассемблере же отследить перемещение строки по локальным буферам практические невозможно (во всяком случае, автоматически). Глобальные буфера (в которые компилятор пихает константные строки, в том числе зашифрованные) отслеживаются сразу, так что LoadString по некоторым позициям очень даже рулит!
Символьная информация
отладочная информация
По умолчанию компилятор генерирует файл без отладочной информации, и она попадет туда только в исключительном случае, но все-таки попадет. Такая участь настигает не только начинающих программистов, не знающих, чем отличается Debug от Release, но и «маститые» фирмы, выпускающие достойные программные продукты. Допустим, у нас имеется глобальная программа IsRegistered, тогда смысл пары машинных команд будет ясен и без комментариев.
Листинг
дизассемблерный листинг исполняемого файла с отладочной информацией
.text:00405664 cmp _IsRegistered, 0
.text:0040566B jz short loc_40567A
Никогда не оставляй отладочную информацию в откомпилированной программе!
динамические библиотеки
Имена неэкспортируемых функций уничтожаются компилятором, экспортируемые же по умолчанию остаются «как есть». С++-компиляторы в дополнение «замангляют» имена, дописывая к ним «зашифрованный» прототип функции, но IDA PRO с легкостью возвращает их в исходный вид. Если защитный модуль реализуется в виде динамической библиотеки (очень часто случается именно так), наличие символьных имен (причем с готовыми прототипами) значительно упрощает анализ. Например, OO Software (создатель одноименного дефрагментатора) любит таскать за собой библиотеку oorwiz.dll (очевидно, расшифровывается как «OO Registration Wizard»), экспортирующую всего три функции, но зато какие…

Листинг
библиотека oorwiz.dll от OO Software экспортирует функции, говорящие сами за себя
3 0 00001FD0 RegWiz_InitLicMgr
1 1 000019D0 RegWiz_InitReadOnly
2 2 00001D00 RegWiz_InitTrial
Всегда удаляй все символьные имена из экспорта и вызывай функции только по ординалу.
rtti

Динамические классы, тесно связанные с механизмом RTTI (Runtime Type Identification) и активно используемые компиляторами DELPHI/Borland С++ Builder, сохраняют в откомпилированном файле не только свою структуру, но и символьные имена! Если брать как пример результат работы утилиты DEDE, реконструировавшей структуру классов программы Etlin HTTP Proxy Server, сразу в глаза бросится класс TfrmRegister, который соответствует форме fRegister и обрабатывает нажатие кнопки «OK» процедурой bOKClick, расположенной по адресу 48D2DCh. Благодаря динамическим классам сердце защитного механизма было локализовано всего за несколько секунд!
Не используй RTTI в защитных механизмах или, по крайней мере, не давай формам и обработчикам осмысленные имена!
Обфускация
Код, генерируемый компилятором, очень громоздок, и разобраться в нем крайне непросто, но возможно. Чтобы помешать злоумышленникам, некоторые протекторы используют «запутывание», или обфускацию (англ. obfuscation). В простейшем случае автоматический кодогенератор, свинченный с полиморфного движка, внедряет в код огромное количество незначащих команд типа NOP, XCHG EAX, EBX/XHG EBX, EAX, нашпиговывая ими программу как рождественскую утку/гуся. Более совершенные генераторы используют разветвленную систему условных переходов, математические операции и присвоения, результат которых никак не используется, и другие полиморфные технологии.
Листинг
фрагмент программы, защищенной протектором armadillo
.00434000: 60 pushad
.00434001: E800000000 call .000434006 ——— (1)
.00434006: 5D pop ebp
.00434007: 50 push eax
.00434008: 51 push ecx
.00434009: EB0F jmps .00043401A ——— (2)
.0043400B: B9EB0FB8EB mov ecx,0EBB80FEB ;«e?0e»
.00434010: 07 pop es
.00434011: B9EB0F90EB mov ecx,0EB900FEB ;«e?0e»
.00434016: 08FD or ch,bh
.00434018: EB0B jmps .000434025 ——— (3)
.0043401A: F2 repne
.0043401B: EBF5 jmps .000434012 ——— (4)
.0043401D: EBF6 jmps .000434015 ——— (5)
.0043401F: F2 repne
.00434020: EB08 jmps .00043402A ——— (6)
.00434022: FD std
.00434023: EBE9 jmps .00043400E ——— (7)
.00434025: F3 repe
.00434026: EBE4 jmps .00043400C ——— (8)
.00434028: FC cld
.00434029: E959585051 jmp 051533887
.0043402E: EB0F jmps .00043403F ——— (9)
Можно сгенерировать хоть миллион команд — это легко. Проанализировать их намного сложнее, если вообще возможно. Назначающие команды и заведомо никогда не исполняющиеся условные переходы типа XOR EAX, EAX/JNZ trg сможет отсеять и компьютер (достаточно написать простенький плагин к дизассемблеру IDA PRO). Освободиться от ненужных вычислений значительно сложнее. Как минимум, необходимо загнать все команды на граф, отображающий зависимости по данным, и убрать замыкающиеся ветви. Некоторые хакерские команды уже решили эту задачу (например, группа Володи с wasm’а), однако готовых инструментов в публичном доступе что-то не наблюдается, значит, юные взломщики, наткнувшись на обфускаторный код, скорее обломаются, чем взломают его. С точки зрения разработчика программы очень хорошо!
Высаживаться на разработку собственного обфускатора совершенно необязательно, есть готовые — как коммерческие, так и бесплатные. Например, .NET Obfuscator — http://blogs.msdn.com/obfuscator/default.aspx. Забавно, но большинство обфускаторов не используют обфускацию для защиты самих себя от взлома! А все потому, что в программах, критичных к производительности (к ним, например, относятся трехмерные игры), обфускация вызывает значительные тормоза и запутывать можно только редко вызываемые модули, например код защитного механизма. Однако здесь возникает угроза: хакер просто «выломает» защитный механизм из программы не анализируя его устройство. Как правило, для этого достаточно проанализировать код материнской процедуры (которая не подвергалась обфускации) и удалить вызов «запутанной» защитной функции, подсунув «правильный» код возврата, который ожидает вызывающая функция. Чтобы помешать подобным действиям хакера, защитная процедура, кроме проверки аутентичности копии программы, должна делать что-то полезное, такое, без чего программа не сможет работать. Но и в этом случае шансы хакера на взлом остаются высокими: шпионаж за API-функциями и реестром дает богатую пищу для размышлений, которая часто избавляет от необходимости анализировать машинный код.
Обфускация — не панацея. Слепое использование готовых обфускаторов лишь увеличивает объем защищаемой программы и ухудшает производительность, но далеко не всегда затрудняет взлом!

Скорость печати
Набирайте отображаемый текст и вы узнаете вашу скорость набора текста


Рейтинг@Mail.ru


Copyright © 2025 Как разблокировать аккаунт. Все права защищены.