Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do these javascript obfuscators generate actual working code?

There's this one and this one and they both generate completely unreadable code, one being more adorable than the other.

Now, I'm no expert in Javascript, but I fail to see how

゚ω゚ノ= /`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゚]) (゚Θ゚)) ('_'); 

and

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

are actual valid javascript that do as expected. Seriously, run them. They're both alert("StackOverflow"). I could understand obfuscating some logic or string obfuscation, but there's no visible control statements. Is this obfuscator pulling some magic in the style of The Language Which Shall Not Be Named? I'm happy with my code looking happy too, but I'm completely not understanding the magic behind it.

I've tried picking through the sourcecode of both pages, and they're as confusing for me as the code they generate.

How does this work?

like image 905
Cyclone Avatar asked Jan 16 '12 17:01

Cyclone


People also ask

How do JavaScript Obfuscators work?

How does the obfuscation work? Through a series of transformations, such as variable / function / arguments renaming, string removal, and others, your source code is transformed into something unreadable, while working exactly as before.

Should JavaScript be obfuscated?

Advantages of obfuscating JSPrevent people from copying or modifying your code without authorization. The obfuscated JavaScript will be way larger and difficult to understand.

Which of the below tool can be used for JavaScript obfuscation?

Tools For Code Obfuscation In Javascript You can use an online tool like: JavaScript Obfuscator. Beautifytools.


1 Answers

What fun! Here's my go at it. Basically what is happening here is a bunch of numbers and strings are being assigned to variables. Those variables are being concatenated to form an encoded string. That encoded string is decoded to form a string of JavaScript code. That code is set as the body of a function, which is then executed.

Let's take it line by line:

Line 1:

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

゚ω゚ノ - a global variable
/`m´)ノ ~┻━┻ / - a regular expression
/*´∇`*/ - a multi-line comment
['_'] - get the property _ of the regular expression.

Since a RegExp does not have a _ property, the variable ゚ω゚ノ contains the value undefined.

Line 2:

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

Define the variables o, ゚ー゚, and _, and set each of their values to 3.

Line 3:

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

Define the variables c and ゚Θ゚ and set their values to 0. (゚ー゚ is 3, so (゚ー゚) - (゚ー゚) is the same as ゚ー゚ - ゚ー゚ is the same as 3 - 3. Now c and ゚Θ゚ both contain 1;

Line 4:

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

Define the variable ゚Д゚ and redefine the variable ゚Θ゚. ^ is the bitwise XOR operator and o and _ are both 3.
o ^ _ ^ o is the same as 3 ^ 3 ^ 3.
3 ^ 3 is 0, 3 ^ 0 is 3.
Then 3 / 3 is 1.
゚Д゚ and ゚Θ゚ both now contain 1.

Line 5:

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

With line breaks and indentation:

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

Redefine ゚Д゚ as an object literal, with properties ゚Θ゚, ゚ω゚ノ, ゚ー゚ノ, and ゚Д゚ノ.
゚Д゚.゚Θ゚ is "_".
゚Д゚.゚ω゚ノ is ((undefined == 3) + "_")[1] which is "false_"[1] which is "a".
゚Д゚.゚ー゚ノ is (undefined + "_")[3 ^ 3 ^ 3 - 1] which is "undefined_"[2] which is "d".
゚Д゚.゚Д゚ノ is ((3 == 3) + "_")[3] which is "true_"[3] which is "u".

Line 6:

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

Is the same as:

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

Which is the same as:

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

So ゚Д゚.゚Θ゚ is "a".

Lines 7 - 16:

And so it continues, assigning strings and numbers to variables and object properties. Until the last line:

Line 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゚])(゚Θ゚))('_'); 

By this time, we have the following variables:

゚ω゚ノ    // 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" 

That line is mostly one big string concatenation. We can make it slightly more readable by removing the unnecessary parentheses and adding line breaks:

゚Д゚['_'](     ゚Д゚['_'](         ゚ε゚ +          ゚Д゚[゚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゚]     )(゚Θ゚) )("_"); 

The value of that concatenated string is:

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" 

So, replacing all the variables with literals, we end up with the following JavaScript which gets executed on that last line:

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))("_") 

Breaking that line down, in the middle we see the concatenated string is passed to a Function constructor, making the string the function body:

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\"") 

So, that string is evaluated as JavaScript, and the Function constructor returns this 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"; } 

That function is immediately executed:

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

And returns the string:

alert("Hello, JavaScript") 

Hey, that looks like JavaScript! But it's not yet. It's just a string. But that string is passed to another Function constructor, giving us a function that executes the string as JavaScript:

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

That is the same as:

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

That function is immediately executed:

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

And our unobfuscated code is finally called.

like image 90
gilly3 Avatar answered Oct 20 '22 00:10

gilly3