Comments 85
Как у этих методов со скоростью работы? И все ли браузеры его правильно поймут?
Третий способ очень понравился :-)
Третий способ очень понравился :-)
А следующим шагом будет создание невидимого html6 =)
mathiasbynens.be/demo/css-without-html (Opera, Firefox).
Самый бескомпромисный обфускатор — это Google Closure Compiler в режиме Extreme. Правда для него надо код специально писать и теггировать с нуля. Люблю его.
Эффективность этого метода напрямую зависит от того насколько он неизвестен. Поскольку написать скрипт выдающий исходный код не проблема. И зачем тогда огород городить. Тот кто сможет прочитать логику не шифрованного скрипта, сможет прочитать и шифрованный.
вручную написан — вручную и дешифровать. Другое дело что овчинка выделки может не стоить — в пошаговой отладке все труды шифрующего будут как на ладони.
Извращенная логика — лучший обфускатор!
НО придумал вариант последнего пункта. Берем в диве текст. Слова разделены пробелами. Нечетное количество пробелов 1, четное 0. Все равно 2 и 1 пробел отображаются как 1 в браузере, так что верстка не плывет. Длинную программу так не написать, но можно так спрятать некую критическую (напр. «аффторскую») функцию. Кстати избыточность кода снижается поскольку пробелы по любому нужны.
Отмечу что я не очень верю в полезность этого. Большинство авторских функций — просто жуткие велосипеды.
НО придумал вариант последнего пункта. Берем в диве текст. Слова разделены пробелами. Нечетное количество пробелов 1, четное 0. Все равно 2 и 1 пробел отображаются как 1 в браузере, так что верстка не плывет. Длинную программу так не написать, но можно так спрятать некую критическую (напр. «аффторскую») функцию. Кстати избыточность кода снижается поскольку пробелы по любому нужны.
Отмечу что я не очень верю в полезность этого. Большинство авторских функций — просто жуткие велосипеды.
Да, вот только логика, извлекающая код из пробелов, будет слишком уж на виду. Её как прятать? Повторять процесс до бесконечности?
Есть в юникоде один символ, U+200B. Вот он: "". Прямо между кавычками. Zero width space называется, пользуйтесь :)
Думаю, если поискать — можно еще найти символы такого рода.
Думаю, если поискать — можно еще найти символы такого рода.
Вы взорвали мой мозг! До сих пор не могу поверить что это работает. Я почему-то был уверен, что как минимум «eval» в коде должно быть. А оно воно как…
>>Буду рад ответить на ваши вопросы
Вы бы могли привести минимальный JS пример, не содержащий ни одного слова?
>>Буду рад ответить на ваши вопросы
Вы бы могли привести минимальный JS пример, не содержащий ни одного слова?
jquery код ни один из видимых способов не сделал рабочим
Ради спортивного интереса, какой процент хабравчан желают скрывать написаный ими код в своих проектах, а кому не жалко если кто-то им воспользуется?
Есть просто другая ситуация, не все ведут свои проекты, кто-то просто работает на дядю. Я вот будучи сотрудником одной крупной компании столкнулся с ситуацией, когда начальство дали задание — запретить пользователю копировать текст, вот я песка то поел, т.к. ответ «это не возможно» их не устраивал :-) С JS была похожая ситуация, но благо обфускация помогла отбиться :-)
Проекты разные все-таки бывают… На сайтах — не жалко. А вот у меня, например, интерфейс для встраиваемых устройств на JS, который я продаю. Там килобайт 200 кода, где помимо функционала — еще и UI-фреймворк заточенный для работы на embedded. Без обфускации — никак. Делать OpenSourcе при всей моей любви к нему тоже нельзя, т.к. слишком узкий рынок.
Но кроме Closure Compiler не вижу смысла что-то рассматривать — он ведь еще и ускоряет код хоть немного. А тут несчастные 300Мгц MIPS'овские железки совсем сдохнут… :-)
Но кроме Closure Compiler не вижу смысла что-то рассматривать — он ведь еще и ускоряет код хоть немного. А тут несчастные 300Мгц MIPS'овские железки совсем сдохнут… :-)
3й способ по своей идее напоминает javascript в png.
Пишем однострочники на перле яваскрипте?
> parseInt©
Парсер — лох.
Парсер — лох.
По последнему способу. Не обязательно в 8 раз, часть символов, например как unicode в js строки надо будет преобразовать например в 2 байта, а тогда уже стремимся к числу в 16 раз больше :)
А меня вот другое интересует.
Вы занимались обфускацией?
Зачем вы это делали?
Конечно же, я имею ввиду обфускацию НЕ с целью уменьшения размера скрипта или увеличения скорости его исполнения.
Защищаетесь? От чего?
Вы занимались обфускацией?
Зачем вы это делали?
Конечно же, я имею ввиду обфускацию НЕ с целью уменьшения размера скрипта или увеличения скорости его исполнения.
Защищаетесь? От чего?
Вы пишите проект, проект крутится на ваших JS бибилиотеках ( не только JS конечно, но в данном случае ) и Вы не хотите:
1) Чтобы Ваши библиотеки уплыли куда либо в другие не Ваши проекты
2) Чтобы в случае чего-либо понадобившегося Вашему клиенту, заказ получили Вы а не фрилансер Вася Пупкин
Например так, и это далеко не все.
1) Чтобы Ваши библиотеки уплыли куда либо в другие не Ваши проекты
2) Чтобы в случае чего-либо понадобившегося Вашему клиенту, заказ получили Вы а не фрилансер Вася Пупкин
Например так, и это далеко не все.
Ну так это ж все расшифровывается так или иначе.
По-моему что обфускация, что защита программ всякими «старфорсами» все это комплексы какие-то. Пишите качественно и количество (денег) не заставит себя долго ждать.
Цели разные бывают. Вот например я сделал игру Алхимия на JS. Суть сводится к тому, чтобы комбинируя имеющиеся элементы получать новые. Все доступные комбинации элементов хранятся в js и доступны любому, кто знает про вошебную комбинацию Ctrl+U. Таким образом, скрыв код, мы сильно сузим множество «читеров». Конечно, комбинации все равно можно будет прочитать, но сделать это будет сложнее.
Это я к тому, что бывают и непараноидальные поводы скрыть код:)
Это я к тому, что бывают и непараноидальные поводы скрыть код:)
Превращать свои «хорошие» скрипты в вот в такое месево это зло злейшее.
Если вы не желаете открывать код — вам не стоит писать на JavaScript. Даже если обработать все GCC, то исходник мы так или иначе получим. А распаковка вот такого добра, которое раз в 20 длиннее кода, может занять несколько секунд и код мы тоже получим.
Вышеположенные способы представлены исключительно ради спортивного интереса и восновном используются для сокрытия «плохого» JavaScript (XSS скриптов), ворующего ваши куки.
Мораль: бесполезно бороться с уводом кук регулярками, бьющими по document.cookie. Лучше всего совсем не давать пользователю вводить html разметку (Markdown наше все), если даете вводить, то тщательно фильтруйте источники XSS, а не их код.
Если вы не желаете открывать код — вам не стоит писать на JavaScript. Даже если обработать все GCC, то исходник мы так или иначе получим. А распаковка вот такого добра, которое раз в 20 длиннее кода, может занять несколько секунд и код мы тоже получим.
Вышеположенные способы представлены исключительно ради спортивного интереса и восновном используются для сокрытия «плохого» JavaScript (XSS скриптов), ворующего ваши куки.
Мораль: бесполезно бороться с уводом кук регулярками, бьющими по document.cookie. Лучше всего совсем не давать пользователю вводить html разметку (Markdown наше все), если даете вводить, то тщательно фильтруйте источники XSS, а не их код.
Обфускация — вовсе не всегда удлинение кода (компрессия, байт код например), это раз, во вторых что угодно можно декомпилировать, вопрос только во времени и ресурсах.
В большинстве случаев для неюзанья своих библиотек вполне хватит скомпрессить код, укоротив названия методов и перменных максимально.
В большинстве случаев для неюзанья своих библиотек вполне хватит скомпрессить код, укоротив названия методов и перменных максимально.
За первый способ я двумя руками за, остальные для XSS и извращенцев.
С моей точки зрения способ хорошо если:
1) увеличивает код не более чем на 5%
2) уменьшает быстродействие не более чем 5%
3) степень геморроя по желанию
:-D
1) увеличивает код не более чем на 5%
2) уменьшает быстродействие не более чем 5%
3) степень геморроя по желанию
:-D
Что же тогда использовать вместо JavaScript??? Flash не предлагать.
>Представленный код может не работать, ибо хабрапарсер©
От хабрапарсера отлично помогает тег <pre>
От хабрапарсера отлично помогает тег <pre>
Уже так и вижу, как толпа «праграммистаф на Джаве» будет прятать свой уникальный скрипт снежинок или часов в невидимый текст.
А ещё эту статью можно было назвать: «Новая веха в XSS»…
Паковка в png habrahabr.ru/blogs/crazydev/102394/ — наверное тоже разновидность обфускации
спасибо за статью, узнал много нового!
а также ради интереса сделал обфускатор, который делает яваскрипт невидимым — www.freedomscripts.org/js-invis.html
только не пойму, почему в опере при декодировании получается такая каша. в ФФ все нормально
а также ради интереса сделал обфускатор, который делает яваскрипт невидимым — www.freedomscripts.org/js-invis.html
только не пойму, почему в опере при декодировании получается такая каша. в ФФ все нормально
Это оперный баг, она корежит/удаляет невидимые символы в textarea
Добавьте ещё один скрытый элемент:
В функции decode берите код из него
В функции encode сохраняйте результат в оба элемента
Добавьте ещё один скрытый элемент:
<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;
FF 3.6, обфусцированный код не выполняется, при декодировании такая фигня:
̰̉΄ΐɀ̌lj̃ƓЀ̡ΐġs (это было alert('fuck it'); )
̰̉΄ΐɀ̌lj̃ƓЀ̡ΐġs (это было alert('fuck it'); )
Ну, описанное безусловно интересно, но и решается довольно просто. Выделяем код между тегами script, сохраняем в отдельный файл, в начало лепим eval=print; ставим SpiderMonkey, запускаем:
и в итоге получаем расшифрованный код.
JSUnpack позволяет делать то же и даже большее, например, обходит хитрости с эмуляцией DOM, когда в скрипте принимают участие другие части html-кода, ну как в классическом примере:
$ 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, где возможности ещё шире и интереснее.
Даешь верблюда на JS: ru.wikipedia.org/wiki/JAPH :)
блин прочитал бы я эту статью пораньше, задумался бы…
Вы можете стать популярным на 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
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
Интересно, что будет, если обфускатору подсунуть обфусцированный код?
Тема arguments.callee в виде ключа дешифрации не затронута.
Вот самый простенький энкодер жаваскрипта на жаваскрипте, с примитивной защитой от модификации тела декодера.
Воткните вместо eval например alert и получите мусор — тело переменной hash изменится, и декодировка сломается.
Дальше можно опираться на значение eval.toString() и отлавливать подмену тела функции eval, что тоже усложнит декодировку.
Воткните вместо 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() — поручик был такой выдумщик ;)
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 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, обфусцируйте имена переменных, и получите вполне труднодекодируемый код.
Добавьте utf8 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, обфусцируйте имена переменных, и получите вполне труднодекодируемый код.
Вы как маленький. Код — proof of concept.
Добавьте utf8 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, и получите вполне труднодекодируемый код.
Добавьте utf8 в имена переменных и функций, не вырезайте их регуляркой, спрячьте декодер, и получите вполне труднодекодируемый код.
Спасибо большое за статью!
Может вопрос будет звучать и глупо, но все же спрошу.
Можно ли function(p,a,c,k,e,d) как то превратить в нормальный код на сервере, например с помощью PHP?
Можно ли function(p,a,c,k,e,d) как то превратить в нормальный код на сервере, например с помощью PHP?
Насчет PHP не знаю. Можно распарсить код в AST на JS, а потом нарисовать его в читаемом виде.
Ого! Не знал, что в таком коде можно вот так вот детально разобраться. Спасибо большое! Теперь буду знать!
никакой из обфускаторов так не сможет
Как же? Практически один-в-один происходит в jsfuck.
Там
function
выдёргивается через []["filter"]
, а сами символы f-i-l-t-e-r берутся из true
и false
, которые в свою очередь !![]
и ![]
.Sign up to leave a comment.
Обфускация JavaScript