Как работает этот запутанный код javascript?

я наткнулся на загадочный jQuery и мне интересно понять, как он работает.

http://jsfiddle.net/fsW6U/

также проверьте код ниже:

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

может ли кто-нибудь разбить этот код по строкам и объяснить, как работает каждая строка?

2 ответов


если вы заметили, присвоив значение $ ($ становится целым числом) немедленно, jquery фактически никогда не используется в этом коде.

// ~ is bitwise not, so this set $ = -1
$ = ~ [];

следующий код создает объект JavaScript. С ![] is false, (![] + "") преобразует логическое значение в строке "false". Каждый [$] захватывает букву по указанному индексу,$ в строке "false" или различные другие возвращаемые значения. В коде хранится ряд целых чисел и букв в объекте а затем присваивает его $.

$ = { 
    ___: ++$, // 0 since $ was -1
    $$$$: (![] + "")[$], // "f"
    __$: ++$, // 1
    $_$_: (![] + "")[$], // "a"
    _$_: ++$, // 2
    $_$$: ({} + "")[$],
    $$_$: ($[$] + "")[$], // "b"
    _$$: ++$, // see the patter when ++$ is assigned?
    $$$_: (!"" + "")[$], // see the pattern with the letters?
    $__: ++$,
    $_$: ++$,
    $$__: ({} + "")[$],
    $$_: ++$,
    $$$: ++$,
    $___: ++$,
    $__$: ++$
};

следующие идеи аналогичны приведенным выше. Каждая часть (разделенная +) возвращает букву на основе возвращаемого значения, которые затем объединяются в строку.

// "constructor"
$.$_ = ($.$_ = $ + "")[$.$_$] + ($._$ = $.$_[$.__$]) + ($.$$ = ($.$ + "")[$.__$]) + ((!$)      + "")[$._$$] + ($.__ = $.$_[$.$$_]) + ($.$ = (!"" + "")[$.__$]) + ($._ = (!"" + "")[$._$_]) +     $.$_[$.$_$] + $.__ + $._$ + $.$;

код ниже назначает "return" и function Function() { [native code] }.

// "return"
$.$$ = $.$ + (!"" + "")[$._$$] + $.__ + $._ + $.$ + $.$$;
// function Function() { [native code] }
$.$ = ($.___)[$.$_][$.$_];

в последних строках,

$.$$ + "\"" + $.$_$_ + (![] + "")[$._$_] + $.$$$_ + "\" + $.__$ + $.$$_ + $._$_ +        $.__ + "(\\"\" + $.__$ + $.__$ + $.___ + "\" + $.__$ + $.$_$ + $.__$ + "!\\");" + "\""`

эквивалентно

"return"ale2t(\"01!\");""

при передаче $.$(), оно становится функцией

function anonymous() { return "alert(\"Hi!\");"; }

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

$.$($.$($.$$ + "\"" + $.$_$_ + (![] + "")[$._$_] + $.$$$_ + "\" + $.__$ + $.$$_ + $._$_ + $.__ + "(\\"\" + $.__$ + $.__$ + $.___ + "\" + $.__$ + $.$_$ + $.__$ + "!\\");" + "\"")())();

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

obj = {
    ___: ++index, // = 0
    $$$$: (![] + "")[index], // = "f" from 'f'alse
    __$: ++index, // = 1
    $_$_: (![] + "")[index], // = "a" from f'a'lse
    _$_: ++index, // = 2
    $_$$: ({} + "")[index], // = "b" from [o'b'ject Object]
    $$_$: (index[index] + "")[index], // = "d" from un'd'efined
    _$$: ++index, // = 3
    $$$_: (!"" + "")[index], // = "e" from tru'e'
    $__: ++index, // = 4
    $_$: ++index, // = 5
    $$__: ({} + "")[index], // = "c" from [obje'c't Object]
    $$_: ++index, // = 6
    $$$: ++index, // = 7
    $___: ++index, // = 8
    $__$: ++index // = 9
};

// obj.$_ = "c" + "o" + "n" + "s" + "t" + "r" + "u" + "c" + "t" + "o" + "r";
obj.$_ = (obj.$_ = obj + "")[obj.$_$] + (obj._$ = obj.$_[obj.__$]) + (obj.$$ = (obj.$ + "")[obj.__$]) + ((!obj) + "")[obj._$$] + (obj.__ = obj.$_[obj.$$_]) + (obj.$ = (!"" + "")[obj.__$]) + (obj._ = (!"" + "")[obj._$_]) + obj.$_[obj.$_$] + obj.__ + obj._$ + obj.$;

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

// obj.$ = function Function() { [native code] } <- a function constructor
obj.$ = (obj.___)[obj.$_][obj.$_];

// If you don't know what Function() is, read
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function to learn about Function()
// before continuing.  It'll make more sense.

// body1 = "return"ale2t(\"01!\");"";
body1 = obj.$$ + "\"" + obj.$_$_ + (![] + "")[obj._$_] + obj.$$$_ + "\" + obj.__$ +    obj.$$_ + obj._$_ + obj.__ + "(\\"\" + obj.__$ + obj.__$ + obj.___ + "\" + obj.__$ +       obj.$_$ + obj.__$ + "!\\");" + "\"";

// body2 = "alert("Hi!");" since 2 = "r", \"01\!" = "Hi!"
body2 = obj.$(body1)();

// calls "alert("Hi!");"
obj.$(body2)();

// This works because the last argument to Function() becomes the
// body of that function.

библиотека jQuery становится неактуальным в первой строке кода:

$ = ~[];

в результате -1. Сразу после этого вы видите объект, назначенный $ делая ссылки на него в то же время, как:

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

и так далее... Если вы получаете кусок за куском и выполняете его, вы увидите, как ведет себя Javascript. В конце концов вы обнаружите, что ваш код вызывает предупреждение, делая выходные значения js через эти оценки и объединяя их в alert.

этот вопрос напоминает мне запутанный код javascript с двоичными значениями?