Question

I came across a cryptic jQuery and am interested to understand how it works.

http://jsfiddle.net/fsW6U/

Also check the code below:

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

Can someone break this code down line-by-line and explain how each line works?

Was it helpful?

Solution

If you notice, by assigning a value to $ ($ becomes an integer) immediately, jquery is actually never used in this code.

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

The following code creates a javascript object. Since ![] is false, (![] + "") converts the boolean to a string, "false". Each [$] is grabbing a letter at the specified index, $, in the string, "false" or various other return values. The code stores a series of integers and letters in an object and then assigns it to $.

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

The ideas that follows are similar to that above. Each piece (separated by the +) returns a letter based on the return value, which are then combined to form a string.

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

The code below assigns "return" and function Function() { [native code] }.

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

In the final lines,

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

is equivalent to

"return"ale\162t(\"\110\151!\");""

When passed to $.$(), it becomes a function

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

Then the final statement that actually executes the alert.

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

To make the whole concept easier to understand, I've provided semi-deobfuscated code as well.

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"ale\162t(\"\110\151!\");"";
body1 = obj.$$ + "\"" + obj.$_$_ + (![] + "")[obj._$_] + obj.$$$_ + "\\" + obj.__$ +    obj.$$_ + obj._$_ + obj.__ + "(\\\"\\" + obj.__$ + obj.__$ + obj.___ + "\\" + obj.__$ +       obj.$_$ + obj.__$ + "!\\\");" + "\"";

// body2 = "alert("Hi!");" since \162 = "r", \"\110\151\!" = "Hi!"
body2 = obj.$(body1)();

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

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

OTHER TIPS

jQuery becomes irrelevant in the first line of code:

$ = ~[];

This results in -1. Right after it, you see an object being assigned to $ making references to it at the same time, like:

___: ++$,              // $.___ 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

And so on... If you get piece by piece and execute it you will see how Javascript behaves. Eventually you will find that your code calls alert by making js output values through these evaluations and combine them into alert.

This question reminds me of Obfuscated javascript code with binary values?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top