Как эти обфускаторы JavaScript генерируют реальный рабочий код? - PullRequest
26 голосов
/ 16 января 2012

Есть это и это , и они оба генерируют совершенно нечитаемый код, один из которых более восхитителен, чем другой.

Теперь я не экспертв Javascript, но я не вижу, как

゚ω゚ノ= /`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) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

и

$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$._$_+$._$$+$.__+$.$_$_+$.$$__+"\\"+$.__$+$.$_$+$._$$+"\\"+$.__$+$.__$+$.$$$+"\\"+$.__$+$.$$_+$.$$_+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.$$$$+(![]+"")[$._$_]+$._$+"\\"+$.__$+$.$$_+$.$$$+"\\\")"+"\"")())();

являются действительными действительными JavaScript, которые делают, как ожидалось.Серьезно, запусти их.Они оба alert("StackOverflow").Я мог понять запутывание некоторой логики или запутывание строк, но нет никаких видимых управляющих операторов.Неужели этот обфускатор тянет за собой магию в стиле Язык, который не будет назван ?Я доволен тем, что мой код тоже выглядит счастливым, но я совершенно не понимаю магию, стоящую за ним.

Я пытался выбрать исходный код обеих страниц, и они так же сбивают меня с толку, как и я.код, который они генерируют.

Как это работает?

Ответы [ 4 ]

28 голосов
/ 17 января 2012

Как весело! Вот мой путь. В основном здесь происходит набор чисел и строк, которые присваиваются переменным. Эти переменные объединяются для формирования закодированной строки. Эта закодированная строка декодируется для формирования строки кода JavaScript. Этот код устанавливается как тело функции, которая затем выполняется.

Давайте рассмотрим это построчно:

Строка 1:

゚ω゚ノ = /`m´)ノ ~┻━┻   //*´∇`*/['_'];

゚ω゚ノ - глобальная переменная
/`m´)ノ ~┻━┻ / - регулярное выражение
/*´∇`*/ - многострочный комментарий
['_'] - получить свойство _ регулярного выражения.

Поскольку RegExp не имеет свойства _, переменная ゚ω゚ノ содержит значение undefined.

Строка 2:

o = (゚ー゚) = _ = 3;

Определите переменные o, ゚ー゚ и _ и установите для каждого из их значений значение 3.

Строка 3:

c = (゚Θ゚) = (゚ー゚) - (゚ー゚);

Определите переменные c и ゚Θ゚ и установите их значения на 0. (゚ー゚ равно 3, поэтому (゚ー゚) - (゚ー゚) совпадает с ゚ー゚ - ゚ー゚ совпадает с 3 - 3. Теперь c и ゚Θ゚ оба содержат 1;

Строка 4:

(゚Д゚) = (゚Θ゚) = (o ^ _ ^ o) / (o ^ _ ^ o);

Определите переменную ゚Д゚ и переопределите переменную ゚Θ゚. ^ является побитовым оператором XOR и o и _ оба 3.
o ^ _ ^ o совпадает с 3 ^ 3 ^ 3.
3 ^ 3 это 0, 3 ^ 0 это 3.
Тогда 3 / 3 равно 1.
゚Д゚ и ゚Θ゚ теперь содержат 1.

Строка 5:

(゚Д゚) = { ゚Θ゚: '_', ゚ω゚ノ: ((゚ω゚ノ == 3) + '_')[゚Θ゚], ゚ー゚ノ: (゚ω゚ノ + '_')[o ^ _ ^ o - (゚Θ゚)], ゚Д゚ノ: ((゚ー゚ == 3) + '_')[゚ー゚] };

С разрывом строки и отступом:

(゚Д゚) = {
    ゚Θ゚: '_',
    ゚ω゚ノ: ((゚ω゚ノ == 3) + '_')[゚Θ゚],
    ゚ー゚ノ: (゚ω゚ノ + '_')[o ^ _ ^ o - (゚Θ゚)],
    ゚Д゚ノ: ((゚ー゚ == 3) + '_')[゚ー゚]
};

Переопределить ゚Д゚ как литерал объекта со свойствами ゚Θ゚, ゚ω゚ノ, ゚ー゚ノ и ゚Д゚ノ.
゚Д゚.゚Θ゚ это "_".
゚Д゚.゚ω゚ノ это ((undefined == 3) + "_")[1], что "false_"[1], что "a".
゚Д゚.゚ー゚ノ - это (undefined + "_")[3 ^ 3 ^ 3 - 1], что "undefined_"[2], что "d".
゚Д゚.゚Д゚ノ это ((3 == 3) + "_")[3] что "true_"[3] что "u".

Строка 6:

(゚Д゚)[゚Θ゚] = ((゚ω゚ノ == 3) + '_')[c ^ _ ^ o];

То же, что и

゚Д゚.゚Θ゚ = ((undefined == 3) + "_")[1 ^ 3 ^ 3];

Что совпадает с:

゚Д゚.゚Θ゚ = "false_"[1];

То есть ゚Д゚.゚Θ゚ это "a".

Строки 7 - 16:

И так продолжается, присваивая строки и числа переменным и свойствам объекта. До последней строки:

Строка 17:

(゚Д゚)['_']((゚Д゚)['_'](゚ε゚ + (゚Д゚)[゚o゚] + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + ((゚ー゚) + (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + ((゚ー゚) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚ー゚) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + (゚ー゚) + (o ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (c ^ _ ^ o) + (゚Д゚)[゚ε゚] + (゚Θ゚) + ((o ^ _ ^ o) + (o ^ _ ^ o)) + (゚ー゚) + (゚Д゚)[゚ε゚] + (゚ー゚) + ((o ^ _ ^ o) - (゚Θ゚)) + (゚Д゚)[゚ε゚] + ((゚ー゚) + (゚Θ゚)) + (゚Θ゚) + (゚Д゚)[゚o゚])(゚Θ゚))('_');

К этому времени у нас есть следующие переменные:

゚ω゚ノ    // undefined
o       // 3
゚ー゚     // 4
_       // 3
c       // 0
゚Θ゚     // 1
゚Д゚     /* {
            "1": "f",
            ゚Θ゚: "_",
            ゚ω゚ノ: "a",
            ゚ー゚ノ: "d",
            ゚Д゚ノ: "e",
            c: "c",
            o: "o",
            return: "\\",
            ゚Θ゚ノ: "b",
            constructor: "\"",
            _: Function
        } */
゚o゚     // "constructor"
゚ε゚     // "return"
o゚ー゚o   // "u"

Эта строка - в основном одна большая конкатенация строк. Мы можем сделать его немного более читабельным, удалив ненужные скобки и добавив разрывы строк:

゚Д゚['_'](
    ゚Д゚['_'](
        ゚ε゚ + 
        ゚Д゚[゚o゚] + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        ゚Θ゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        (゚ー゚ + ゚Θ゚) + 
        (c ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚ー゚ + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚Θ゚ + 
        (c ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        (゚ー゚ + ゚Θ゚) + 
        (゚ー゚ + (o ^ _ ^ o)) + 
        ゚Д゚[゚ε゚] + 
        (゚ー゚ + ゚Θ゚) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        ゚ー゚ + 
        (c ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        ゚Θ゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        ゚Θ゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        (o ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ゚ー゚ + 
        (o ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        (゚ー゚ + ゚Θ゚) + 
        ゚Θ゚ + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        (c ^ _ ^ o) + 
        ゚Д゚[゚ε゚] + 
        ゚Θ゚ + 
        ((o ^ _ ^ o) + (o ^ _ ^ o)) + 
        ゚ー゚ + 
        ゚Д゚[゚ε゚] + 
        ゚ー゚ + 
        ((o ^ _ ^ o) - ゚Θ゚) + 
        ゚Д゚[゚ε゚] + 
        (゚ー゚ + ゚Θ゚) + 
        ゚Θ゚ + 
        ゚Д゚[゚o゚]
    )(゚Θ゚)
)("_");

Значение этой объединенной строки:

return"\141\154\145\162\164\50\42\110\145\154\154\157\54\40\112\141\166\141\123\143\162\151\160\164\42\51"

Итак, заменив все переменные литералами, мы получим следующий JavaScript, который выполняется в последней строке:

Function(Function("return\"\\141\\154\\145\\162\\164\\50\\42\\110\\145\\154\\154\\157\\54\\40\\112\\141\\166\\141\\123\\143\\162\\151\\160\\164\\42\\51\"")(1))("_")

Разбивая эту строку, в середине мы видим, что объединенная строка передается конструктору Function, что делает строку телом функции:

Function("return\"\\141\\154\\145\\162\\164\\50\\42\\110\\145\\154\\154\\157\\54\\40\\112\\141\\166\\141\\123\\143\\162\\151\\160\\164\\42\\51\"")

Итак, эта строка оценивается как JavaScript, и конструктор Function возвращает эту функцию:

function () {
    return"\141\154\145\162\164\50\42\110\145\154\154\157\54\40\112\141\166\141\123\143\162\151\160\164\42\51";
}

Эта функция выполняется немедленно:

Function("return\"\\141\\154\\145\\...\\51\"")(1)

И возвращает строку:

alert("Hello, JavaScript")

Эй, это похоже на JavaScript! Но это еще не так. Это просто строка. Но эта строка передается другому конструктору Function, что дает нам функцию, которая выполняет строку как JavaScript:

Function("alert(\"Hello, JavaScript\")")

То же самое, что и

function () {
    alert("Hello, JavaScript");
}

Эта функция выполняется немедленно:

Function("alert(\"Hello, JavaScript\")")("_")

И наш необоснованный код, наконец, называется.

23 голосов
/ 16 января 2012

По мере того, как мой javascript превышал день, строка за строкой ломалась.Заметьте, что я сгенерировал мой с alert("Hello")

$ = ~[];   // var $ = -1
$ = 
    {
    ___ : ++$,              // ++(-1) == 0
    $$$$:(![]+"")[$],       // ![] == false, false + "" == "false", "false"[0] == "f"
    __$:++$,                // ++(0) == 1    
    $_$_:(![]+"")[$],       // ![] == false, false + "" == "false", "false"[1] == "a"
    _$_:++$,                // ++(1) == 2
    $_$$:({}+"")[$],        // {} + "" == "[object Object]", "[object Object]"[2] == "b"
    $$_$:($[$]+"")[$],      // 2[2] == undefined + "" == "undefined", "undefined"[2] == "d"
    _$$:++$,                // ++(2) == 3
    $$$_:(!""+"")[$],       // !"" == true + "" == "true", "true"[3] == "e"
    $__:++$,                // ++(3) == 4
    $_$:++$,                // ++(4) == 5
    $$__:({}+"")[$],        // ({} + "") == [object Object]", "[object Object]"[5] == "c"
    $$_:++$,                // ++(5) == 6
    $$$:++$,                // ++(6) == 7
    $___:++$,               // ++(7) == 8
    $__$:++$                // ++(8) == 9
};

$.$_ = 
    ($.$_=$+"")[$.$_$] +        // "[object Object]"[5] == "c" +  (also $.$_ = "[object Object]")
    ($._$=$.$_[$.__$]) +        // "[object Object]"[1] == "o" + (also $._$ = "o")
    ($.$$=($.$+"")[$.__$]) +    // $.$+"" == "undefined", "undefined"[1] == "n" + (also $.$$ = "n")
    ((!$)+"")[$._$$] +          // !$ == false, false+"" == "false", "false"[3] == "s" +
    ($.__=$.$_[$.$$_]) +        // "[object Object]"[6] == "t" (also $.__ = "t") +
    ($.$=(!""+"")[$.__$]) +     // !"" == true, true + "" == "true", "true"[2] == "r" +(also $.$="r")
    ($._=(!""+"")[$._$_]) +     // !"" == true, true + "" == "true", "true"[3] == "u" +(also $._="u")
    $.$_[$.$_$] +               // "[object Object]"[5] == "c" +
    $.__ +                      // "t" +
    $._$ +                      // "o" +
    $.$;                        // "r"

// $.$_ = "constructor"

$.$$ = 
    $.$ +                       // "r" +
    (!""+"")[$._$$] +           // "true"[3] == "e" +
    $.__ +                      // "t" +
    $._  +                      // "u" +
    $.$ +                       // "r" +
    $.$$;                       // "n" 
// $.$$ = "return"

$.$ = ($.___)[$.$_][$.$_];      // (0)["constructor"]["constructor"]
// $.$ = Function

// This is the part that changes when you change the input string.

$.$(                            // Function( 
    $.$(                        // Function (
        $.$$ +                  // "return"+
        "\""+                   // '"' +
        $.$_$_ +                // "a" + 
        (![]+"")[$._$_]+        // "l" + 
        $.$$$_+                 // "e" + 
        "\\"+                   // "\" +            
        $.__$+                  // "1" + 
        $.$$_+                  // "6" + 
        $._$_+                  // "2" +   (note '\162' = 'r')   
        $.__+                   // "t" + 
        "(\\\"\\"+              // '(\"\' +    
        $.__$+                  // 1 + 
        $.__$+                  // 1 + 
        $.___+                  // 0 +     (note '\110' = 'H')    
        $.$$$_+                 // e + 
        (![]+"")[$._$_]+        // "false"[2] == "l", "l" + 
        (![]+"")[$._$_]+        // "false"[2] == "l", "l" + 
        $._$+                   // "o" + 
        "\\\")"+                // '\")' +
        "\""                    // '"''
    )()                         // invoke
)();                            // invoke

, но я не нахожусь на нем, он создает строку, а затем вызывает ее.

Редактировать - и я надеваюУ меня нет времени для декодирования другой версии, но я представляю, что она делает что-то похожее, но с нелатинскими символами.

12 голосов
/ 16 января 2012

Введите $ в консоли (после запуска кода) и разверните объект. Затем вы сможете легче проанализировать его.

enter image description here

Они набирают достаточное количество слов / символов, используя хитрые средства, и ссылаются на них в объекте $, затем используют их для построения программы и, вероятно, eval при вызове Function(...)().

Так что это должно сводиться к ...

Function('alert("StackOverflow")')();

... или что-то подобное.


Начинаем раскручивать, ...

$=~[];  // -1

$={
  0:++$,         //  0
  f:(![]+"")[$], // "f", (![]+"") is "false", and [$] gives index 0, or "f"
  1:++$,         //  1
  a:(![]+"")[$], // "a", (![]+"") is "false", and [$] gives index 1, or "a"
  2:++$,         //  2
  b:({}+"")[$],  // "b", ({}+"") is "[object Object]", and [$] gives index 2, or "b"
  d:($[$]+"")[$],// "d", ($[$]+"") is "undefined", and [$] gives index 2, or "d"
  3:++$,         //  3
  e:(!""+"")[$], // "e", (!""+"") is "true", and [$] gives index 3, or "e"
  4:++$,         //  4
  5:++$,         //  5
  c:({}+"")[$],  // "c", ({}+"") is "[object Object]", and [$] gives index 5, or "c"
  6:++$,         //  6
  7:++$,         //  7
  8:++$,         //  8
  9:++$          //  9
};

$.constructor=($.constructor=$+"")[$[5]]+($.o=$.constructor[$[1]])+($.return=($.$+"")[$[1]])+((!$)+"")[$[3]]+($.t=$.constructor[$[6]])+($.$=(!""+"")[$[1]])+($.u=(!""+"")[$[2]])+$.constructor[$[5]]+$.t+$.o+$.$;
$.return=$.$+(!""+"")[$[3]]+$.t+$.u+$.$+$.return;
$.$=($[0])[$.constructor][$.constructor];
$.$($.$($.return+"\""+$.a+(![]+"")[$[2]]+$.e+"\\"+$[1]+$[6]+$[2]+$.t+"(\\\"\\"+$[1]+$[2]+$[3]+$.t+$.a+$.c+"\\"+$[1]+$[5]+$[3]+"\\"+$[1]+$[1]+$[7]+"\\"+$[1]+$[6]+$[6]+$.e+"\\"+$[1]+$[6]+$[2]+$.f+(![]+"")[$[2]]+$.o+"\\"+$[1]+$[6]+$[7]+"\\\")"+"\"")())();

Тогда ...

$.constructor=($.constructor=$+"")[5]+($.o=$.constructor[1])+($.return=($.$+"")[1])+((!$)+"")[3]+($.t=$.constructor[6])+($.$=(!""+"")[1])+($.u=(!""+"")[2])+$.constructor[5]+$.t+$.o+$.$;
$.return=$.$+(!""+"")[3]+$.t+$.u+$.$+$.return;
$.$=(0)[$.constructor][$.constructor];
$.$($.$($.return+"\""+$.a+(![]+"")[2]+$.e+"\\"+$[1]+$[6]+$[2]+$.t+"(\\\"\\"+$[1]+$[2]+$[3]+$.t+$.a+$.c+"\\"+$[1]+$[5]+$[3]+"\\"+$[1]+$[1]+$[7]+"\\"+$[1]+$[6]+$[6]+$.e+"\\"+$[1]+$[6]+$[2]+$.f+(![]+"")[2]+$.o+"\\"+$[1]+$[6]+$[7]+"\\\")"+"\"")())();

... эх, потеря интереса.

9 голосов
/ 17 января 2012

Так как каждый другой ответ - только анализ кода, который вы дали, я буду расширять, как вы можете генерировать их самостоятельно (без инструментов). Я верю, что это даст вам лучший обзор того, как это работает.

Большинство этих обфускаций основаны на нескольких особенностях / принципах JavaScript. Во-первых, имя переменной может использовать Юникод Буква ( Лу , Лл , Лт , Лм, Lo , Nl ) и Unicode Число ( Nd ). В первом примере, который вы привели, символ может выглядеть как символ, но это буква Unicode или номер Unicode.

Вторым является то, что добавление пустой строки к чему-либо в JavaScript приведет к ее преобразованию в строку. Если вы также используете тот факт, что строки представляют собой массивоподобную структуру в JavaScript, вы можете легко создать такие вещи, как: (false+"")[0], который также может быть записан с (!1+"")[0]. С этого момента вы можете составлять свои собственные строчные буквы за буквой.

Третье - доступ к любому свойству объекта с помощью записи []. Например: window["alert"]("test") совпадает с window.alert("test"). Если вы смешаете это с предыдущим абзацем, я думаю, вы легко увидите, куда это может пойти.

Единственное, чего нам не хватает для начала, так это ссылки на window или Function. Другие ответы уже предоставляют вам способ доступа к Function, который можно использовать как eval. Чтобы получить window, проще всего пропустить его через Array.concat следующим образом:

t= [].concat;
a = t()[0]; // "a" now contains window

Если у вас есть window, вы можете использовать window["eval"] или позвонить напрямую window["alert"].

Это все для основы того, как вы на самом деле делаете подобные запутывания. Остальное - просто вариация предыдущих пунктов. Если вам нужна дополнительная информация, я сделал пару постов в блоге об этом, вы можете найти их здесь: http://holyvier.blogspot.com/2011/10/javascript-obfuscation-introduction.html

...