Как защититься от SWF-декомпиляторов

У меня в последнее время с завидной частотой спрашивают: «Как защитить данные, летающие между Flash Player и сервером?». Вместо ответа я предлагал прочитать любые книжки по криптографии, а от сильно наглых отбивался следующим кодом.

var myAge:Number = 23; //Ключ
var someTextToEncode:String = 'Sometext, or xml, or anything else'; //Текст для шифрования
var arr:Array = new Array();
var l:Number = someTextToEncode.length;
var encodedText:String = '';
for (var i:Number = 0; i< l; i++){
encodedText += String.fromCharCode(someTextToEncode.charCodeAt(i) + myAge); //Шифруем методом сдвига позиции кода символа. Просто и со вкусом. 90% "хакеров" на этом этапе уже отсеятся.
}
post(encodedText); //Метод, посылающий шифрованные данные на сервер


И от меня отвязывались, копипастя код. И всё у меня было хорошо, до тех пор, пока один из любопытных не спросил: «А как же защитить ключ? Ведь любую флешку можно утащить с сайта и декомпилировать!»

Способ, как оказалось, очень прост и не требует наличия никаких обфускаторов. Речь пойдёт о стендалон-флешках, скомпилированных одним файлом.

Немного теории

Любой декомпилятор анализирует ваш swf-файл и разбирает его на классы. Он способен прочитать даже имена свойств и методов класса, но лишь тех, которые доступны извне этого класса: то есть статические, public, inherited и protected. Переменные, защищённые модификатором доступа private, либо переменные определённые только в области видимости методов, декомпиляторы прочитать так же способны, но их имена заменяют например на _loc_1. Это лишь потому, что большинство компиляторов (это относится не только к flash) занимаются оптимизацией, выкидывая человеко-ориентированный легко читаемый код перед превращением в байт-код. Кто-то называет это мета-информацией, но для среды исполнения это всего лишь мусор, не несущий никакой смысловой нагрузки.

Особенности flash-технологии

Любой action-script проект можно скомпилировать как swc-файл: файл библиотеки. SWC является по сути архивом, содержащим swf-файл и xml-метафайл. В XML хранятся ссылки-указатели на классы, которые можно использовать при подключении этой библиотеки. На самом деле обходиться можно и без них, читая swf «вживую». Делается это при помощи параметров мета-тега Embed. Например, так:

[Embed(source = 'some.swf', symbol = 'SomeClass')] private const SomeClassFromSomeSWF:Class;

Дальше использовать этот класс можно как обычно — через вызов конструктора у SomeClassFromSomeSWF. Тип экземпляра этого класса будет точно таким же, как у класса SomeClass в some.swf. Однако, при помощи тега Embed можно внедрять не только определённые классы, но и всю SWF целиком (на самом деле внедрять можно что угодно, но сейчас речь не об этом). Какой же тип будет у экземпляра класса внедрённой SWF?

Внедрённая SWF

Для внедрённых файлов с mimeType равным application/x-shockwave-flash (то есть, например, swf-файлов) у Adobe есть специальный тип: MovieClipLoaderAsset, находящийся в пакете mx.core. Сам swf-файл при внедрении ложится в его свойство movieClipData как массив байт, исключая весь человекоориентированный «мусор» — то есть только то, что нужно flashplayer'у. Но и это ещё не всё. MovieClipLoaderAsset является наследником MovieClip, а значит может быть с чистой совестью добавлен в список отображения.

Зная всё это, решить исходную задачу «защиты от декомпиляторов» — дело трёх минут:

package {
import flash.display.Sprite;
import mx.core.MovieClipLoaderAsset;
public class Crypto extends Sprite {
[Embed(source = 'unprotected.swf')] public const ToProtect:Class;
public function Crypto():void {
var protectedSwf:MovieClipLoaderAsset=new ToProtect() as MovieClipLoaderAsset;
addChild(protectedSwf);
var messageToDecompiler:String = "Hello fellas. You can do nothing^^ Kekeke";
}
}
}


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

UPD: Анализатор байткода AS3 proxy, основанный на оптимизаторе apparat взломал данную защиту без особых проблем.

UPD 2: Данный метод не претендует на звание «абсолютная защита». Взломать можно всё, что существует. Этот метод всего лишь увеличивает временные и интеллектуальные затраты на получение ресурсов, зашитых в SWF: арт/музыку/расчётную логику. К тому же, в комментариях обнаружился декомпилятор, действующий по принципу «нажми-одну-кнопку», вскрывающий подобную защиту без проблем. Подводя итоги: не стоит использовать данный метод, как единственное защитное препятствие к взлому флешки. Однако будучи применён комплексно, при своей простоте и легковесности, он способен значительно помочь оградить ресурсы от вскрытия.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 78

    +12
    Что кроме лени помешает злоумышленнику экспортнуть внедренный swf и скормить его декомпилятору?
      –6
      Что вы имеете ввиду? Экспортнуть как? В каком виде? Куда?
        +9
        Имеем один swf внутри другого в виде массива байт. Достаем этот массив байт, сохраняем его в отдельный файл, получаем внутренний swf.
          –2
          Получаем интерпретируемый байт-код, который тем не менее весьма сложно проанализировать.
          Я не говорю о том, что взломать невозможно. Невозможно украсть только уничтоженные данные, да и то не всегда. Вопрос безопасности — баланс между доступностью и защищённостью. Я готов утверждать только то, что время анализа такого приложения возрастает в разы.
            +3
            В чем сложность его анализа, если по вашим же словам в movieClipData ложится сам swf-файл?
              –3
              >>Сам swf-файл при внедрении ложится в его свойство movieClipData как массив байт
                +4
                И? В чем сложность его оттуда сохранить?
                  –3
                  Сложности никакой, кроме той, что там лежит байткод, вместо человекочитаемого кода. Да и, кстати
                    +7
                    Да, естественно байткод. Там же swf, вы же сами это сказали.
      0
      Интересно услышать мнение об этом вопросе тех, кто тоже разбирается во флеше, ибо только из-за возможности спокойно получать исходники я не могу портануть проект на флеш :(
        +3
        Работал над одним из свф протекторов, технология что описана в этой статье обходится элементарно.
        Вот более вменяемое описание подобной технологии: Protect Your Flash Files From Decompilers by Using Encryption
        Но это всё так же обходится меньше чем за минуту. Вобщем это защита от дурачков. Очень тяжело разработать на флеше нормальную защиту, которая бы увеличивала трудозатраты на получение ресурсов и защищала от декомпиляции.
          0
          Это же обфускация сплошная. Естественно, если заняться переименованием методов/свойств, можно получить более внушающие результаты. Собственно, я думаю, что мой метод, как единственный ипользовать действительно смысла не имеет, а как одну из запертых дверей — почему бы и нет?
            0
            Большинство протекторов, которые не перестали развиваться — все реализуют подобное обёртывание, кто-то даже множественное обёртывание. Хотя множественное обёртывание никак не усложняет процесс вытаскивания конечной свфки. Кто-то там на alchemy пишет часть кода для дешифровки итп.
            Все это делают чтобы потом написать о том что у них используется и подобная технология :)
            От дурака это защитит, а те кто умеет пользоваться гуглом сразу найду способ обойти эту защиту. Скорость с которой злоумышленик захочет вытащить конечную свфку равна скорости загрузки этой свфки в плеере.
        +7
        Если можно, киньте swf который невозможно декомпильнуть. Задайте какой-нибудь переменной какое-нибудь контрольное значение внутри. Публика попробует поломать, тем самым доказав вашу или не вашу правоту.
          0
          Например вот-так. Требуется прочитать значение текстовой переменной, определённой во вложенной swf.
            +1
            Я может что-то неправильно понял, но вроде www.showmycode.com/ — отлично выдал сорс данной флешки.
            0
            попробуйте разобрать флешку игры timezero. В свое время на ней даже swf decompiler обламывался, не знаю как сейчас.
              0
              А что в ней разбирать? Весь арт лежит рядом, по папочкам расфасованный. Все обсчёты ведутся на сервере. Сокет-логику выдернуть? А толку?
                0
                бота написать который бы бродил и че нить делал, не знаю как щас, но раньше мы собирали из арсенала всякую шнягу автоматом. Мышекликами правда
                  0
                  Интересно. Я думал что это делали либо внешними макрос-сервисами, либо цепляли сниффером команды, уходящие на сервер
                    0
                    все проще ) запомнил куда кликать, выставил задержки и ушел курить )
                      0
                      Не, а вот у меня одно время был дезвинговский клиент, потом правда большинство его фич перенесли в VIP-аккаунты. Сейчас точно не помню, но из плюшек можно было видеть все хар-ки обвеса противника, был автопилот в шахте собирающий ресурсы с возможностью фильтрации, был еще автопилот по локам можно было ходить на атопилоте по маршрутам, особенно под таблетками сталкер летал между городом и заводом за 2 секунды/лока, так что даже не успевал появится в чате. В противовес этой фичи, были в клиенте макросы на цепляние таких вот бегунов с помощью команды %username% //batle или как-то так. Которая юзернейм выдирала из логов. Еще можно было вроде как в соседние клетки смотреть, как потом с помощью модуля бинокль. Еще много всего, довольно жирный был клиент, дающий огромное превосходство. Почти все топ кланы на них бегали, пока его не легализовали официально и за реал.
                  0
                  Вполне успешно и декомпилировали, и инжектили свой функционал.
                +4
                Не могу скачать. Видимо слишком зашифровано. :-) Положите на народ пожалуйста или что-нибудь «широкое».
                  0
                  Видимо лёг сервачок. Логи надо будет глянуть. Перезалил.
                    0
                    Скачал. Строка указывается явно или собирается?
                      0
                      Могу сразу строку сказать: если знать что искать, найти очень просто, даже банальным HEX'ом. :-)
                      Кинул SWF-ку другу. Он обещал заморочиться при помощи bytecode-анализатора. О результатах сообщу отдельно.
                        0
                        Не, не надо пока. Относительно хорошее решение. Действительно что бы «доковырять» нужно потратить достаточно времени. А если ещё заморочиться с рекурсией, типа байткод который генерит байткод, который… :-)
                  –40
                  Мое вам ФУ: в эпоху html5 рассуждать о каких-то некошерных flash… Вы еще ActiveX вспомните :)
                    +9
                    Толсто. Как только HTML5 сможет воспроизвести хотя бы половину того, что флеш делал лет пять назад — я может и заинтересуюсь.
                      –21
                      > Как только HTML5 сможет воспроизвести хотя бы половину того, что флеш делал лет пять назад — я может и заинтересуюсь.

                      Чего вам не хватает в html5, что вы используете flash?
                    +4
                    Зачем вы зашли в этот пост? Какая цель?
                      –30
                      > Зачем вы зашли в этот пост?

                      Да надоели уже проприетарщики, пихающие всякие ActiveX'ы и flash'и направо и налево, хотя в 99% случаев можно было бы использовать html5. А оставшийся 1% никому не интересен.
                        +9
                        Цель ясна. Спасибо.
                          –17
                          Вантузятнечки, минусуйте дальше. Совсем немного до read-only осталось!
                            +1
                            Вижу вас зеленым троллем в коже, с плёткой, стегающего себя и произносящего эту фразу.

                            Хочется комикс нарисовать, жаль у меня с рисованием как у вас с толерантностью :)
                              –10
                              Здесь я как раз не троллю. Достали просто вантузятники, считающиеся, что на их мастдае свет клином сошелся.
                                +2
                                Презираю трусов, молча «минусующих» пользователя только за то, что его мнение отличается от их мнения (как же так, миллионы мух не могут быть не правы!).
                                (из хабрапрофиля Eddy_Em)
                                Без проблем, минусую «вслух».

                                И не путайте, пожалуйста, понятия «высер» и «мнение». Если вас интересует разница, то последнее аргументировано не только эмоциями и ортодоксальной радикальностью.
                                  0
                                  Достали идиоты, дискредитировавшие слово «линуксоид».
                                  +1
                                  Да он уже получил, что хотел :) Рыдонля.
                        +12
                        UFO appears suddenly?
                          +1
                          Именно так. Можете описать метод анализа?
                            +15
                            Открыл WinHEX'ом, пропустил первые 8 байт, остальное скопировал в новый файл, к нему применил Edit->Convert->zlib inflate и распаковал 1ю флешку. В распакованной флешке поискал байты CWS, нашлись по смещению 0x241, опять же пропустил 8 байт, со смещения 0x249 начинаются сжатые данные и продолжаются до смещения 0x4FA (после глазами явно видны нули), опять копируем диапазон 0x249-0x4FA и распаковываем. Ну а дальше глазками смотрим и видим по смещению 0x29C байт 0x06 затем название класса String, байт 0x14 (длина строки) и сама строка «UFO appears suddenly».
                              +1
                              Красиво. Но не особо интуитивно. Для описанной операции нужно всё-таки поболе знаний, чем для использования декомпил-нюков.
                          +6
                          Буквально недавно обходил более веселую защиту, чем эту. Кроме прочего, исходник был «защищен» от декомпиляции. Зачем это делать? Если что-то исполняется на стороне клиента, он *может* его исследовать/изменить/разобрать.

                          //class Main
                          package 
                          {
                              import flash.display.*;
                              import flash.events.*;
                              
                              public class Main extends flash.display.Sprite
                              {
                                  public function Main()
                                  {
                                      super();
                                      if (stage) 
                                      {
                                          this.init();
                                      }
                                      else 
                                      {
                                          addEventListener(flash.events.Event.ADDED_TO_STAGE, this.init);
                                      }
                                      return;
                                  }
                          
                                  internal function init(arg1:flash.events.Event=null):void
                                  {
                                      removeEventListener(flash.events.Event.ADDED_TO_STAGE, this.init);
                                      var loc1:*=String("UFO appears suddenly");
                                      return;
                                  }
                              }
                          }
                          
                            +5
                            Как это делается? Из спецификаций SWF узнаем как он устоен, выдираем все объекты. Среди них — SWF файл.
                            Done.
                              0
                              В моём случае это применяется для того, чтобы не спёрли арт/механику игрушки и не подставили свою механику/арт. Удивительно, но большинство «серых» реселлеров флеш-игр не будут заморачиваться на анализ байткода. Если время, потраченное на «взлом» игры не оправдается полученной прибылью с «переделки» — они отказываются от взлома. Так что в некотором роде цель достигнута.
                                +1
                                В первый раз на разбор файла у меня ушло двадцать минут. Из них минут десять я искал чем сделать inflate :)

                                Разбирать SWF и разбирать байткод — разные вещи.
                                  +2
                                  Вот, кстати, как разбирается SWF: pastebin.com/ah4Mbagg
                                +2
                                В Trilix он бинарным файлом. Сохранил и открыл сразу :-)
                                  +2
                                  Хорошо. Буду искать другие способы «закрыться» :-) Топик из-за этого комментария, к сожалению, силу свою теряет.
                                  0
                                  Спасибо за утро! Движуха мозговая хоть. Приятно. :-)
                                    +3
                                    Отвечая на вопрос из топика — «Просто перестаньте юзать флэш»
                                      +1
                                      Нет, я не ярый противник флэша, тем более что если допилить AIR немного и будет замечательно. Просто ответил на вопрос из топика)
                                      +2
                                      Всё, что скачивается на комп юзера может и будет взломано. Это ж аксиома.

                                      Вне зависимости это флеш или хтмл5й

                                        +2
                                        Есть одно ноу-хау у меня:
                                        1)на AS2 делать SWF
                                        2)внутри нее в base64 байткод SWFки на AS3
                                        3)Обфусцируем
                                        4)Делим на части по 250 байт
                                        5)Кодим в base64

                                        6) Распихиваем как текст в кастомное поле EXIF произвольных джипегов.

                                        7) При загрузке ресурсов проверяем каждый загруженный ресурс на наличие EXIF
                                        8) Сливаем все части ведино, переводим в байткод и LoadBytes();

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

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

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

                                        Таким образом мы ограничиваем время на вычисление последовательности и осознание принципа сборки 30-ю сек.
                                          0
                                          >>1) на AS2 делать SWF
                                          >>2) внутри нее в base64 байткод SWFки на AS3
                                          А разве AVM1 нормально воспроизводит AS3 код?
                                            0
                                            Да при некоторых условиях. Просто превосходно воспроизведёт.
                                              0
                                              Можно подробней?
                                                0
                                                По-русски по-английски

                                                SWF-файлы, написанные в ActionScript 1.0 или 2.0, не могут загружать SWF-файлы, написанные в ActionScript 3.0. Это означает, что SWF-файлы, созданные в Adobe Flash 8 или Flex Builder 1.5, а также в более ранних версиях этих программ, не смогут загружать SWF-файлы в ActionScript 3.0.

                                                Единственным исключением из этого правила является то, что SWF-файл ActionScript 2.0 может заменить себя SWF-файлом ActionScript 3.0, если для этого SWF-файла ActionScript 2.0 не выполнялась какая-либо загрузка ни на один из его уровней. В SWF-файле ActionScript 2.0 это можно выполнить с помощью вызова loadMovieNum(), передав значение 0 параметру level.
                                              0
                                              Прочитайте еще раз внимательнее. AVM1 swf юзается только из-за полноценной обфускации кода в отличии от AS3/AVM2 мувиков. Он используется только как контейнер для хранения переведенного в строку (base64) и расзбросанного вместе с мусором искаженного клона байткодом настоящего мувика AVM2. Далее байткод AVM1 файла так же переводится в строку и бьется на куски по 255 символов. Далее эти куски распихиваются на лету с помощью сервака в EXIF всех отдаваемых жипегов. Отдаеются по очереди но не в каждом. В результате пишем на лямку, дешефруем… Далее слушаем локал конекшн (единственный способ коммуникации между AVM1 и AVM2), проверяем домены откуда загружено, проверяем целостность запросом на сервак. Далее AVM1 мувик вызывает функцию сборки запакованного в него в строке AVM2 мувика. Ну а дальше все ясно…
                                                0
                                                >>вызывает функцию сборки запакованного в него в строке мувика
                                                И делает с ним что? Возвращает на сервак?
                                                  0
                                                  LoadBytes с контекстом текущего апп. домена.
                                              0
                                              меняем все вызовы LoadBytes на вызов логгера, и получаем всё что вы там напрятали
                                                0
                                                Я не пользуюсь Loader классом для загрузки удаленного контента вообще из-за проблем с сессиями в некоторых браузерах. Поэтому почти весь контент грузится через LoadBytes. Уследить что из этого является шлюзом — сложно, при условии, что расположение и код меняется при каждом вызове.
                                                0
                                                Пост. -5 от защищённости игры. :)
                                                  0
                                                  В смысле раскрыл ноухау? :) Нет. Это один из механизмов. Все делается автоматом, поэтому накрутить 15-20 механизмов защиты является выходом от «ленивого хака». Взломать можно все. Просто копаться со взломом игры чтобы записать свое имя в топ — дело не благодарное ) Всегда есть модератор, который 95% хакерских результатов просто забанит. Ну и разумеется закодированный шлюз (это единственное что стоит охранять — там находятся все подробности общения с сервером) можно получить только после аутентификации. Аутентификация происходит с помощью соц сети. Что тоже является барьером для ленивых. Нужно будет иметь 100-200 левых акков.
                                                +3
                                                Как спастись от декомпиляторов? Не компилируйте.
                                                  +1
                                                  Хочешь защитить приложение — делай клиент тонким и переноси всю логику на сервер.
                                                    0
                                                    Не всегда подобное возможно. Иногда можно продублировать логику, но перенести полностью — это +3 к тормозам(не у всех пинг до сервера 1мс)
                                                    0
                                                    UFO appears suddenly
                                                    15 минут. 010Editor + Sothink + тулза для распаковки флешек самопальная(потом только узнал что есть уже готовые).
                                                      0
                                                      Уже до меня успели. Давайте чтоль крекми позанимаемся во флеше.
                                                      +4
                                                      помнится много лет назад iviv с не менее продвинутыми товарищами (простите, имена уже не вспомню) ваяли какой-то гиперхитрый протектор который базировался на хитрых манипуляциях с байткодом, позволяющих оставить байткод все еще читаемым плэйером, но заставляющий капитально заткнуться декомпиляторы. И вроде даже все было круто и работало… А потом началась чуть-ли не юридическая суета с Burak KALAYCI, который вроде как разобрался с тем как обходить эту защиту. Чем все закончилось за давностью лет уже не упомню, подробности можно в ruflash поискать. А рассказал я это потому что:
                                                      — тот метод был совсем уж не детским (не в обиду топикстартеру)
                                                      — все равно не устоял, емнип :(
                                                      В общем протектить флешки дело неблагодарное, что к клиенту попало, то рано или поздно будет пломано. единственный надежный способ — экономическая нецелесообразность взлома, да и та против упрямого фанатика не поможет. посему не держите в клиентской части ничего ценного, тогда и ломать не станут.
                                                        +1
                                                        Более-менее нормальная защита возможно при написании некой своей вируальной машины которая будет интерпретировать код в своём языке приходящий с сервера. Естественно там нужно нормальное шифрование и криптографическая подпись запросов и много чего ещё. Уникальная защита = дорогой и уникальный взлом. Простая защита = простой взлом. Взломать можно всё что есть на клиенте.
                                                          +1
                                                          Разработка декомпиляторов тоже не стоит на месте
                                                          Flash Decompiler Trillix показывает все внутренности приложенного файла
                                                          Результат (habrastorage)
                                                            +4
                                                            Хм, после прочтения комментов становится понятно как функционирует игровая индустрия…

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

                                                            Самое читаемое