Обфускация JavaScript

    В статье собраны всем известные методы и предельно извращенные. Эту статью я решил написать после недавнего прочтения поста в блоге Badass JavaScript и решил её дополнить своими находками.

    Первый способ


    Он всем известен — обфускация минимизаторами такими как JS Packer, JSmin, YUI Compressor, Closure compiler или можно просто пугуглить «JavaScript Obfuscator» и найдется ещё сто штук разных обфускаторов.
    Они превращают существующий код
    function MyClass(){
        this.foo = function(argument1, argument2){
            var addedArgs = parseInt(argument1)+parseInt(argument2);
            return addedArgs;
        }
        var anonymousInnerFunction = function(){
            // do stuff here!
        }
    }

    В какой-то такой вид:
    function MyClass(){this.foo=function(c,b){var d=parseInt(c)+parseInt(b);return d};var a=function(){}};

    Или такой:
    var _0xd799=["\x66\x6F\x6F"];function MyClass(){this[_0xd799[0]]=function (_0xefcax2,_0xefcax3){var _0xefcax4=parseInt(_0xefcax2)+parseInt(_0xefcax3);return _0xefcax4;} ;var _0xefcax5=function (){} ;} ;

    Или вот такой:
    eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--){d[c]=k[c]||c}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('4 0="3 5!";9 2(1){6(1+"\\7"+0)}2("8");',10,10,'a|msg|MsgBox|Hello|var|World|alert|n|OK|function'.split('|'),0,{}))

    Но ничего не стоит его восстановить с помощью jsbeautifier.org либо просто убрать eval и получить исходный код, многое потеряем, но смысл кода восстановим. Ну и с первого взгляда мы видим, что перед нами JavaScript.

    Все это были цветочки под катом жесткие методы обфускации.

    Способ второй


    Изменение кода до неузнаваемости, который превратит наш мизерный скрипт:
    alert(0)

    В такой Braifuck-подобный вид:
    ([][(![]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]()[(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]])(+[])

    Или вот в такой (код может не работать ибо хабрапарсер):
    ゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((o^_^o) +(o^_^o))+ (c^_^o)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

    Тут с первого раза и не скажешь, что перед нами работающий JavaScript.
    Тулза делающая код вида один, код вида два. Vladson нашел ещё одну тулзу jjencode

    Объяснение некоторых моментов способа два

    Пример:
    ($=[$=[]][(__=!$+$)[_=-~-~-~$]+({}+$)[_/_]+
    ($$=($_=!''+$)[_/_]+$_[+$])])()[__[_/_]+__
    [_+~$]+$_[_]+$$](_/_)

    Имеем какое-то месево символов, но на самом деле в нем скрывается alert(1), но ведь там нет ни одной строки и ни одного символа, откуда это?!

    Будем разбираться:
    $=[] это пустой массив
    $=[$=[]] это массив с ссылкой на массив
    В переменной $ будет 0.
    Теперь у нас есть 0 и мы можем ссылаться. Делаем __ = "false" через (__ = !$ + $ )
    Далее _ = -~-~-~$
    Оператор ~ в JavaScript означает -(N+1) поэтому -~ = +1
    Если $ = 0 тогда -~-~-~$ = 3
    Получаем: _ = 3

    Таким образом _/_ = 3/3 = 1

    (__ = !$ + $ )[ _ = -~-~-~$]
    ("false")[_]
    ("false")[3]
    "false"[3] = s


    ({} + $)[_/_]
    (" object")[_/_]
    (" object")[1]
    " object"[1] = o


    $$ = ( $_ = !'' + $)[_/_]
    $$ = ( "true")[1]
    "true"[1] = r

    $_[+$] = "true"[0] = t

    $_ = "true"null
    $$ = rt


    ($$ = ( $_ = !'' + $)[_/_] + $_[+$] ))

    !'' = "true"
    $_ = (true)
    $_[1] = r
    $_[0] = t
    $$ = rt


    Таким образом первая строка станет ($ = [] ["s" + "o"+ "r"+ "t" ] )()
    ($=[]["sort"])()

    Идем дельше
    [__[_/_]+__[_+~$]+$_[_]+$$](_/_)

    $ = 0
    _ = 3
    __ = "false"
    $_ = "true"
    $$ = "rt"


    Строка превращается…
    [__[_/_]+__[_+~$]+$_[_]+$$](_/_)

    Превращается…
    [__[1] + __[3 + -1] + $_[3] + $$)(1);

    Превращается…
    ["false"[1] + "false"[3 + -1 ] + "true"[3] + "rt"] (1)

    Превращается в
    [ "a" + "l" + "e" + "r" + "t" ](1)

    В конце мы получаем ($=[]["sort"])()["alert"](1)

    Разобьём по частям
    a = [] // Создает массив
    b = a["sort"] // Получает ссылку на метод sort
    c = b() // Выполяет метод вне контекста массива для получения ссылки на window
    d = c["alert"] // Получает ссылку на window.alert
    d(1) // Выполняет window.alert с аргументом 1


    Итог: window["alert"](1)

    Это, конечно, искусственный пример и никакой из обфускаторов так не сможет.

    Способ третий


    Первый способ делал код похожим на JavaScript, второй совершенно не похожим, а третий сделает код вообще невидимым.

    Готовых решений не видел, концепт, подсмотренный с одного из видео JS конференций.
    Код будет состоять из двух частей: видимая честь — можно использовать что-нибудь описанное выше для её обфускации и невидимая часть.
    Если с видимой все ясно, то секрет невидимой вот в чем: Имеющийся «плохой код» (иначе зачем его прятать) мы пропускаем через наш обфускатор-изчезатор, который превращает видимый скрипт в невидимый т.е. в строку состоящую из знаков табуляции (бит 1) и пробелов (бит 0).
    В итоге мы получим в 8 раз больше кода чем имели. Видимая часть будет декодировать невидимую часть и её выполнять: декодирует биты в число, а число переделает в символ String.fromCharCode() ну а дальше eval

    В конце получается что-то такое (невидимую часть не обязательно скрывать в элементе)
    decodeAndEval(document.getElementById("evilCode").innerHTML);
    <div id="evilCode">

    </div>

    deex написал обфускатор-изчезатор

    По мотивам: badassjs.com/post/2929065287/obfuscation adamcecc.blogspot.com/2011/01/javascript.html

    Буду рад ответить на ваши вопросы и увидеть способы обфускации известные вам.

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

    UPD В комментариях ещё несколько раз писали про способ обфускации в png подробнее
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 85
    • +5
      Как у этих методов со скоростью работы? И все ли браузеры его правильно поймут?
      Третий способ очень понравился :-)
    • +2
      А следующим шагом будет создание невидимого html6 =)
      • 0
        Вы мне напомнили еще один способ обфускации (вернее, второго варианта написания) Expression closure.
        Вот, например, данные выражения идентичны:
        // Обычный синтаксис
        function() { return x * x }

        // Expression closure
        function(x) x * x
        Вот здесь об этом довольно интересно расписано.
        • 0
          Для этого нужен JS 1.8, который мало где есть.
          • 0
            Да, как и написано в статье — работает пока что в FF.
      • +6
        Самый бескомпромисный обфускатор — это Google Closure Compiler в режиме Extreme. Правда для него надо код специально писать и теггировать с нуля. Люблю его.
        • +1
          Эффективность этого метода напрямую зависит от того насколько он неизвестен. Поскольку написать скрипт выдающий исходный код не проблема. И зачем тогда огород городить. Тот кто сможет прочитать логику не шифрованного скрипта, сможет прочитать и шифрованный.
          • 0
            вручную написан — вручную и дешифровать. Другое дело что овчинка выделки может не стоить — в пошаговой отладке все труды шифрующего будут как на ладони.
            • +4
              Извращенная логика — лучший обфускатор!

              НО придумал вариант последнего пункта. Берем в диве текст. Слова разделены пробелами. Нечетное количество пробелов 1, четное 0. Все равно 2 и 1 пробел отображаются как 1 в браузере, так что верстка не плывет. Длинную программу так не написать, но можно так спрятать некую критическую (напр. «аффторскую») функцию. Кстати избыточность кода снижается поскольку пробелы по любому нужны.

              Отмечу что я не очень верю в полезность этого. Большинство авторских функций — просто жуткие велосипеды.
              • 0
                Да, вот только логика, извлекающая код из пробелов, будет слишком уж на виду. Её как прятать? Повторять процесс до бесконечности?
                • 0
                  Спрятать в функции делающей нечто полезное. Напр. удаляющей «лишние» пробелы. И ее зашифровать любым из вышеизложенных способов. + похожие имена переменных.

                  Я повторяюсь — главное извращенная логика.
                • 0
                  Есть в юникоде один символ, U+200B. Вот он: "​". Прямо между кавычками. Zero width space называется, пользуйтесь :)
                  Думаю, если поискать — можно еще найти символы такого рода.
                  • 0
                    Черт, хабрапарсер съел. Ну да в любом случае, его код вы узнали.
            • +1
              Вы взорвали мой мозг! До сих пор не могу поверить что это работает. Я почему-то был уверен, что как минимум «eval» в коде должно быть. А оно воно как…

              >>Буду рад ответить на ваши вопросы

              Вы бы могли привести минимальный JS пример, не содержащий ни одного слова?
              • +1
                Не заметил, в вашей статье уже есть минимальный пример. Почему-то подумал что это фрагмент.

                Спасибо.
              • 0
                jquery код ни один из видимых способов не сделал рабочим
                • +2
                  Ради спортивного интереса, какой процент хабравчан желают скрывать написаный ими код в своих проектах, а кому не жалко если кто-то им воспользуется?
                  • 0
                    Есть просто другая ситуация, не все ведут свои проекты, кто-то просто работает на дядю. Я вот будучи сотрудником одной крупной компании столкнулся с ситуацией, когда начальство дали задание — запретить пользователю копировать текст, вот я песка то поел, т.к. ответ «это не возможно» их не устраивал :-) С JS была похожая ситуация, но благо обфускация помогла отбиться :-)
                    • +7
                      Позвольте поинтересоваться, как вы заставили начальство считать, что у вас текст копировать нельзя? :)
                      • +2
                        убрал его с сайта, видимо, это единственный способ
                        • 0
                          нет, просто привел кучу статей с авторитетных сайтов, где говорится что этого сделать невозможно :-)
                        • 0
                          А отображать его в виде картинки, сгенерированной на сервере, нельзя? Конечно его и так можно будет распознать, но это гемор.
                        • +1
                          Проекты разные все-таки бывают… На сайтах — не жалко. А вот у меня, например, интерфейс для встраиваемых устройств на JS, который я продаю. Там килобайт 200 кода, где помимо функционала — еще и UI-фреймворк заточенный для работы на embedded. Без обфускации — никак. Делать OpenSourcе при всей моей любви к нему тоже нельзя, т.к. слишком узкий рынок.
                          Но кроме Closure Compiler не вижу смысла что-то рассматривать — он ведь еще и ускоряет код хоть немного. А тут несчастные 300Мгц MIPS'овские железки совсем сдохнут… :-)
                        • 0
                          3й способ по своей идее напоминает javascript в png.
                          • 0
                            Особо хорошо в png будут смотреться табуляции и пробелы )
                          • 0
                            Пишем однострочники на перле яваскрипте?
                            • +1
                              Превращаем javascript в помесь perl и brainfuck скорее.
                            • +2
                              > parseInt©
                              Парсер — лох.
                              • –1
                                По последнему способу. Не обязательно в 8 раз, часть символов, например как unicode в js строки надо будет преобразовать например в 2 байта, а тогда уже стремимся к числу в 16 раз больше :)
                                • 0
                                  Все равно в 8 раз больше :) как не крути! И так будет всегда, пока в байте будет 8 бит :) Если, конечно не извращаться и при обфускации не превращать utf8 в utf16.
                                • –3
                                  А меня вот другое интересует.

                                  Вы занимались обфускацией?
                                  Зачем вы это делали?

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

                                  Защищаетесь? От чего?
                                  • –1
                                    Вы пишите проект, проект крутится на ваших JS бибилиотеках ( не только JS конечно, но в данном случае ) и Вы не хотите:

                                    1) Чтобы Ваши библиотеки уплыли куда либо в другие не Ваши проекты

                                    2) Чтобы в случае чего-либо понадобившегося Вашему клиенту, заказ получили Вы а не фрилансер Вася Пупкин

                                    Например так, и это далеко не все.
                                    • 0
                                      Ну так это ж все расшифровывается так или иначе.
                                      • 0
                                        Все расшифровывается так или иначе :-D

                                        Дело во времени, в ресурсах и целях )
                                      • +4
                                        По-моему что обфускация, что защита программ всякими «старфорсами» все это комплексы какие-то. Пишите качественно и количество (денег) не заставит себя долго ждать.
                                        • 0
                                          Цели разные бывают. Вот например я сделал игру Алхимия на JS. Суть сводится к тому, чтобы комбинируя имеющиеся элементы получать новые. Все доступные комбинации элементов хранятся в js и доступны любому, кто знает про вошебную комбинацию Ctrl+U. Таким образом, скрыв код, мы сильно сузим множество «читеров». Конечно, комбинации все равно можно будет прочитать, но сделать это будет сложнее.
                                          Это я к тому, что бывают и непараноидальные поводы скрыть код:)
                                        • +2
                                          Превращать свои «хорошие» скрипты в вот в такое месево это зло злейшее.
                                          Если вы не желаете открывать код — вам не стоит писать на JavaScript. Даже если обработать все GCC, то исходник мы так или иначе получим. А распаковка вот такого добра, которое раз в 20 длиннее кода, может занять несколько секунд и код мы тоже получим.
                                          Вышеположенные способы представлены исключительно ради спортивного интереса и восновном используются для сокрытия «плохого» JavaScript (XSS скриптов), ворующего ваши куки.
                                          Мораль: бесполезно бороться с уводом кук регулярками, бьющими по document.cookie. Лучше всего совсем не давать пользователю вводить html разметку (Markdown наше все), если даете вводить, то тщательно фильтруйте источники XSS, а не их код.
                                          • 0
                                            Обфускация — вовсе не всегда удлинение кода (компрессия, байт код например), это раз, во вторых что угодно можно декомпилировать, вопрос только во времени и ресурсах.
                                            В большинстве случаев для неюзанья своих библиотек вполне хватит скомпрессить код, укоротив названия методов и перменных максимально.
                                            • 0
                                              За первый способ я двумя руками за, остальные для XSS и извращенцев.
                                              • 0
                                                С моей точки зрения способ хорошо если:
                                                1) увеличивает код не более чем на 5%
                                                2) уменьшает быстродействие не более чем 5%
                                                3) степень геморроя по желанию

                                                :-D
                                                • 0
                                                  Если отходить от YUI Compressor
                                                  1. Всегда уменьшает
                                                  2. Быстродействие не изменится, даже будет на йоту быстрее из-за коротких переменных.
                                                  3. Прибавит если вы мазохист и отлаживаете сжатые скрипты: Error on line 1 character 5477 // WOW!
                                                  • 0
                                                    я имел ввиду что каждый сам выбирает уровень геморроя )))
                                                    но вообще отлаживать компрешенные скрипты — это надо тру дзеном быть )))))
                                                    • 0
                                                      для компрешенных, кроме упомянутого бьютифаера, есть reformat/reindent code в различных ide, как например NetBeans и Intellij IDEA )
                                            • 0
                                              Что же тогда использовать вместо JavaScript??? Flash не предлагать.
                                      • +1
                                        >Представленный код может не работать, ибо хабрапарсер©

                                        От хабрапарсера отлично помогает тег <pre>
                                        • 0
                                          Подскажите как использовать тег <pre> с тегом <source>? Как ни крутил не работает.
                                          function © {} 
                                          • 0
                                            Мой совет с pre скорее относился к случаям, когда source использовать бессмыссленно, например, в коде сразу после фразы «Или вот в такой (код может не работать ибо хабрапарсер)»
                                        • +10
                                          Уже так и вижу, как толпа «праграммистаф на Джаве» будет прятать свой уникальный скрипт снежинок или часов в невидимый текст.
                                          • –1
                                            А ещё эту статью можно было назвать: «Новая веха в XSS»…
                                            • 0
                                              Паковка в png habrahabr.ru/blogs/crazydev/102394/ — наверное тоже разновидность обфускации
                                              • +1
                                                спасибо за статью, узнал много нового!
                                                а также ради интереса сделал обфускатор, который делает яваскрипт невидимым — www.freedomscripts.org/js-invis.html

                                                только не пойму, почему в опере при декодировании получается такая каша. в ФФ все нормально
                                                • +2
                                                  Это оперный баг, она корежит/удаляет невидимые символы в textarea
                                                  Добавьте ещё один скрытый элемент:
                                                  <input type="hidden" id='code-2' value="" />

                                                  В функции decode берите код из него
                                                  xcode = document.getElementById('code-2').value.split("\n");

                                                  В функции encode сохраняйте результат в оба элемента
                                                  document.getElementById('code').value = result;
                                                  document.getElementById('code-2').value = result;
                                                  • 0
                                                    спасибо, поправил. а также добавил возможность задания кастомных символов вместо таб и пробел, теперь можно получить более забавную кашу, например js из смайликов
                                                  • 0
                                                    FF 3.6, обфусцированный код не выполняется, при декодировании такая фигня:
                                                    ؁̰̉΄ΐɀ‡̌lj̃ƓЀ̡ΐ‡ġs (это было alert('fuck it'); )
                                                    • 0
                                                      оказывается ff не понимает таб-ы в текстовых полях, оттого не работал декодер
                                                      исправил
                                                  • +2
                                                    Ну, описанное безусловно интересно, но и решается довольно просто. Выделяем код между тегами script, сохраняем в отдельный файл, в начало лепим eval=print; ставим SpiderMonkey, запускаем:
                                                    $ js example_js_eval.txt | indent
                                                    и в итоге получаем расшифрованный код.

                                                    JSUnpack позволяет делать то же и даже большее, например, обходит хитрости с эмуляцией DOM, когда в скрипте принимают участие другие части html-кода, ну как в классическом примере:
                                                    <+html>
                                                    <+head>
                                                    <+title>MyEncrypi0nK3y<+/title>
                                                    <+/head>
                                                    <+script>
                                                    function decrypt(key, input) {
                                                    var output = “”;
                                                    return output;
                                                    }
                                                    eval(decrypt(document.title, “258ff2c006e9bd6”));
                                                    <+/script>
                                                    <+/html><+/code>

                                                    (плюсы добавлены в теги, что отобразить их в комментах, Хабр блокирует).

                                                    Понятно, что суть обфускации - закриптовать код, но надо ведь ещё и скрыть процедуру декрипта.

                                                    Всё вышесказанное касается js в html, но нельзя забывать о js в pdf и swf, где возможности ещё шире и интереснее.
                                                    • 0
                                                      Даешь верблюда на JS: ru.wikipedia.org/wiki/JAPH :)
                                                      • 0
                                                        блин прочитал бы я эту статью пораньше, задумался бы…
                                                        • 0
                                                          Вы можете стать популярным на wtfjs.com/, если закините туда пару цитат из этого кода :)
                                                          • 0
                                                            Теперь ждем, когда на собеседованиях начнут в качестве тестовых заданий на знание js предлагать определить что-же делает «Braifuck-подобный» код. -__-
                                                            • +1
                                                              Для Ample SDK писал обфускатор/минификатор сам (компрессия лучше чем в YUI, Closure). Вот фрагмент кода:

                                                              dg7x5x5656x=_[5];6y Q=8x,kb=0,kc=10;8z hz0w{6y lA=0y cW,kB,kC,kz,ku,kD,kx,kA,kE,kt,kw,ky,kv;7z(6y jt=0,lH,lH,lH;lH=Q[jt];jt0v){kC=lH5x3756x;kz=lH5x3756x*lH5x7216x;if(lH5x7226x7wjw)kz=lH5x7216x4w1?lH5x7226x:db5x5846x(kz,lH5x7226x);ku=kz;kD=lA-lH5x8026x;kx=lH5x7966x>0?kD*lH5x7966x:ku-kD*db5x2006x(lH5x7966x);if((lH5x3946x5x6236x1wkD3vlH5x3946x5x6236x)2w(kD3vku*(lH5x2456x?2:1)/lH5x7966x)){hC(lH);if(lH5x6606x 9z dn){7z(6y o=lH5x6606x5x2886x,je=o5x236x(lH);je<o5x5566x;je0v)if(o[je+1] 9z dp){hB(o[je+1]);0z}}}6z if(lH 9z df1w!(lH 9z _b)){kA=kC*(lH5x2456x?2:1);kE=kx-kA*db5x4256x(kx/kA);if(lH5x2456x1wkE3vkC)kE=2*kC-kE;kB=1/(1-lH5x2026x/2-lH5x3486x/2);kt=kC*lH5x2026x;kw=kC*lH5x3486x;if(kE<kt)ky=kE*(kB*kE/kt)/2;6z if(kE>kC-kw){kv=kE-(kC-kw);ky=kB*(kC-kt/2-kw+kv*(2-kv/kw)/2)}6z ky=kB*(kE-kt/2);hx(lH,ky/kC)}}kb=hM(hz,kc)};gd(dg);ew(lg,_[561],8z0w{kb=hM(hz,kc)},9y);ew(lg,_[866],8z0w{gX(kb)},9y);6y dp=8z0w{dg5x2346x(3x,2x)};dp7x=0y dg(_[7]);8z hD(lM){6y lH=lM5x3406x;lH5x2526x=hE(lH5x2436x5x2526x);lH5x3946x=hE(lH5x2436x5x3946x);lH5x3756x=hF(lH5x2436x5x3756x);lH5x7216x=hG(lH5x2436x5x7216x,1);lH5x7226x=hF(lH5x2436x5x7226x);lH5x2456x=lH5x2436x5x2456x4w_[859];lH5x2026x=hG(lH5x2436x5x2026x,0);lH5x3486x=hG(lH5x2436x5x3486x,0);

                                                              Слайды на тему: Extreme (yet non-intelligent) Minification and Obfuscation of JavaScript
                                                              • 0
                                                                Почему в слайде у GCC вычеркнут Advanced Mode? Код сжимается безопасно (скрипт сам ставит где нужно; {} и т.п.)? Засоряет ли Global Scope?
                                                                • –1
                                                                  Вычеркнут, ибо GCC (Advanced Mode) не смог скомпилировать работающий код.
                                                              • 0
                                                                Интересно, что будет, если обфускатору подсунуть обфусцированный код?
                                                                • 0
                                                                  Он его обфусцирует?
                                                                • +1
                                                                  Тема arguments.callee в виде ключа дешифрации не затронута.
                                                                  • +1
                                                                    Вот самый простенький энкодер жаваскрипта на жаваскрипте, с примитивной защитой от модификации тела декодера.
                                                                    Воткните вместо eval например alert и получите мусор — тело переменной hash изменится, и декодировка сломается.
                                                                    Дальше можно опираться на значение eval.toString() и отлавливать подмену тела функции eval, что тоже усложнит декодировку.

                                                                    <html>
                                                                    <head>
                                                                    <style>textarea {width: 100%; height: 50%}</style>
                                                                    </head>
                                                                    <body>
                                                                    <script>

                                                                    simpleEncoder = {

                                                                      regex : /[^a-z]/g,

                                                                      /*
                                                                       *
                                                                       */
                                                                      encode : function(js)
                                                                      {
                                                                        var hash = this.decode.toString().replace(this.regex, '');
                                                                        var s = escape(this.xorStrings(js, hash));

                                                                        return "_=" + this.decode.toString() + "('" + s + "', " + this.regex + ")";
                                                                      },

                                                                      /*
                                                                       *
                                                                       */
                                                                      decode : function(code, regex)
                                                                      {
                                                                        xorStrings = function (str1, str2)
                                                                        {
                                                                          var s=new String();  
                                                                          for(var i=0; i < str1.length; i++)
                                                                          {
                                                                            var c1=str1[i].charCodeAt(0);
                                                                            var c2=str2[i % str2.length].charCodeAt(0);

                                                                            s+=String.fromCharCode((c1 ^ c2 ^ str2.length));            
                                                                          }
                                                                          return s;
                                                                        }

                                                                        code = unescape(code);
                                                                        hash = arguments.callee.toString().replace(regex, '');

                                                                        eval(xorStrings(code, hash));
                                                                      },

                                                                      /*
                                                                       *
                                                                       */
                                                                      xorChars : function (char1, char2)
                                                                      {
                                                                        return String.fromCharCode((char1.charCodeAt(0) ^ char2.charCodeAt(0)) % 255);
                                                                      },

                                                                      /*
                                                                       *
                                                                       */
                                                                      xorStrings : function (str1, str2)
                                                                      {
                                                                        var s=new String();  
                                                                        for(var i=0; i < str1.length; i++)
                                                                        {
                                                                          var c1=str1[i].charCodeAt(0);
                                                                          var c2=str2[i % str2.length].charCodeAt(0);

                                                                          s+=String.fromCharCode((c1 ^ c2 ^ str2.length));            
                                                                        }
                                                                        return s;
                                                                      }
                                                                    }

                                                                    var encoded_js = simpleEncoder.encode("alert('Hello World! Привет, мир!');");
                                                                    document.write("<textarea><script>" + encoded_js + "</script></textarea>");

                                                                    </script>
                                                                    </body>
                                                                    </html>

                                                                    * This source code was highlighted with Source Code Highlighter.
                                                                    • 0
                                                                      Надо же, работает.
                                                                      arguments.callee.toString() — поручик был такой выдумщик ;)
                                                                      • 0
                                                                        в вашем случае имея входные данные и сам алгоритм декодирования — все элементарно раскодируется,
                                                                        интересно — данный пример где-то юзается — или так — теория?
                                                                        • 0
                                                                          Это лишь пример ещё одного способа усложнения декодирования.
                                                                          • 0
                                                                            так а смысл — если раскодировать даже проще чем закодировать (

                                                                            hash_decode_fn = you_decode_fn.toString().replace(/[^a-z]/g, '');
                                                                            str_js = xorStrings(unescape(you_code), hash_decode_fn);
                                                                            
                                                                            • 0
                                                                              Вы как маленький. Код — proof of concept.
                                                                              Добавьте utf8 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, обфусцируйте имена переменных, и получите вполне труднодекодируемый код.
                                                                              • 0
                                                                                и что — сильно что-то изменится?
                                                                                кому не надо — тот и смотреть не будет, а кому надо — «труднодекодируемый» код — это +- 10-15-20 мин, потому что он все равно «декодируемый»
                                                                      • 0
                                                                        Вы как маленький. Код — proof of concept.
                                                                        Добавьте utf8 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, и получите вполне труднодекодируемый код.
                                                                        • 0
                                                                          Спасибо большое за статью!
                                                                          • 0
                                                                            Может вопрос будет звучать и глупо, но все же спрошу.
                                                                            Можно ли function(p,a,c,k,e,d) как то превратить в нормальный код на сервере, например с помощью PHP?
                                                                          • 0
                                                                            Ого! Не знал, что в таком коде можно вот так вот детально разобраться. Спасибо большое! Теперь буду знать!
                                                                            • +1
                                                                              никакой из обфускаторов так не сможет

                                                                              Как же? Практически один-в-один происходит в jsfuck.

                                                                              Там function выдёргивается через []["filter"], а сами символы f-i-l-t-e-r берутся из true и false, которые в свою очередь !![] и ![].
                                                                              • 0
                                                                                Поправочка: «i» берётся из undefined, который [][[]]

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