Pull to refresh

Comments 85

Как у этих методов со скоростью работы? И все ли браузеры его правильно поймут?
Третий способ очень понравился :-)
А следующим шагом будет создание невидимого html6 =)
как он хитро через заголовки передал:

  Link <css-without-html.css>;rel=stylesheet


надо запомнить
Вы мне напомнили еще один способ обфускации (вернее, второго варианта написания) Expression closure.
Вот, например, данные выражения идентичны:
// Обычный синтаксис
function() { return x * x }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

только не пойму, почему в опере при декодировании получается такая каша. в ФФ все нормально
Это оперный баг, она корежит/удаляет невидимые символы в 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;
спасибо, поправил. а также добавил возможность задания кастомных символов вместо таб и пробел, теперь можно получить более забавную кашу, например js из смайликов
FF 3.6, обфусцированный код не выполняется, при декодировании такая фигня:
؁̰̉΄ΐɀ‡̌lj̃ƓЀ̡ΐ‡ġs (это было alert('fuck it'); )
оказывается ff не понимает таб-ы в текстовых полях, оттого не работал декодер
исправил
Ну, описанное безусловно интересно, но и решается довольно просто. Выделяем код между тегами 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, где возможности ещё шире и интереснее.
блин прочитал бы я эту статью пораньше, задумался бы…
Вы можете стать популярным на wtfjs.com/, если закините туда пару цитат из этого кода :)
Теперь ждем, когда на собеседованиях начнут в качестве тестовых заданий на знание js предлагать определить что-же делает «Braifuck-подобный» код. -__-
Для 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
Почему в слайде у GCC вычеркнут Advanced Mode? Код сжимается безопасно (скрипт сам ставит где нужно; {} и т.п.)? Засоряет ли Global Scope?
Вычеркнут, ибо GCC (Advanced Mode) не смог скомпилировать работающий код.
Интересно, что будет, если обфускатору подсунуть обфусцированный код?
Тема arguments.callee в виде ключа дешифрации не затронута.
Вот самый простенький энкодер жаваскрипта на жаваскрипте, с примитивной защитой от модификации тела декодера.
Воткните вместо 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.
Надо же, работает.
arguments.callee.toString() — поручик был такой выдумщик ;)
в вашем случае имея входные данные и сам алгоритм декодирования — все элементарно раскодируется,
интересно — данный пример где-то юзается — или так — теория?
Это лишь пример ещё одного способа усложнения декодирования.
так а смысл — если раскодировать даже проще чем закодировать (

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

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

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

Articles