This is a small piece of JavaScript code that alerts "Hello world":
゚ω゚ノ=/`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)-(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚Θ゚)+(c^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚)+(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚ー゚)+(c^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((o^_^o)-(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((o^_^o)+(o^_^o))+((o^_^o)-(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚ー゚)+((o^_^o)-(゚Θ゚))+(゚Д゚)[゚ε゚]+((゚ー゚)+(゚Θ゚))+(゚Θ゚)+(゚Д゚)[゚o゚])(゚Θ゚))('_');
A good looking version:
゚ω゚ノ = /`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)-(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚Θ゚)+(c^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚)+(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚ー゚)+(c^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((o^_^o)-(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+((゚ー゚)+(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((o^_^o)+(o^_^o))+((o^_^o)-(゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚)+(゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚ー゚)+((o^_^o)-(゚Θ゚))+(゚Д゚)[゚ε゚]+((゚ー゚)+(゚Θ゚))+(゚Θ゚)+(゚Д゚)[゚o゚])(゚Θ゚))('_');
It is taken from here: https://codegolf.stackexchange.com/questions/23975/obfuscation-challenge/24041#24041
How does it work? I don't even see the alert
in that code.
Before looking closer at the code, you have to know that since JavaScript 1.5 identifiers are allowed to contain not just ASCII characters but also Unicode characters.
In this case many of these funny sequences are just identifiers. After exchanging these identifiers by simpler identifiers and removing unnecessary comments and parenthesis, the code looks as follows:
a = /`m´)ノ~┻━┻/['_']; o = b = _ = 3; c = d = b-b; e = d = o^_^o/o^_^o; e = { d: '_', a: ((a==3)+'_')[d], h: (a+'_')[o^_^o-d], i: ((b==3)+'_')[b] }; e[d] = ((a==3)+'_')[c^_^o]; e['c'] = (e+'_')[b+b-d]; e['o'] = (e+'_')[d]; f = e['c']+e['o']+(a+'_')[d]+((a==3)+'_')[b]+(e+'_')[b+b]+((b==3)+'_')[d]+((b==3)+'_')[b-d]+e['c']+(e+'_')[b+b]+e['o']+((b==3)+'_')[d]; e['_'] = (o^_^o)[f][f]; g = ((b==3)+'_')[d]+e.i+(e+'_')[b+b]+((b==3)+'_')[o^_^o-d]+((b==3)+'_')[d]+(a+'_')[d]; b += d; e[g] = '\\'; e.j = (e+b)[o^_^o-d]; obo = (a+'_')[c^_^o]; e[f] = '\"'; e['_'](e['_'](g+e[f]+e[g]+d+b+d+e[g]+d+(b+d)+b+e[g]+d+b+(b+d)+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+((o^_^o)+(o^_^o))+b+e[g]+(b+d)+(c^_^o)+e[g]+b+((o^_^o)-d)+e[g]+d+d+(c^_^o)+e[g]+d+b+(b+d)+e[g]+d+(b+d)+b+e[g]+d+(b+d)+b+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+b+(c^_^o)+e[g]+d+((o^_^o)-d)+(b+(o^_^o))+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+(b+d)+b+e[g]+d+b+b+e[g]+b+((o^_^o)-d)+e[g]+(b+d)+d+e[f])(d))('_');
Now we’re able to evaluate each statement at a time:
a = /`m´)ノ~┻━┻/['_']
evaluates to a = undefined
o = b = _ = 3
assigns o
, b
, and _
the integer 3
c = d = b-b
assigns c
and d
the integer 0
e = d = o^_^o/o^_^o
assigns e
and d
the integer 1
(o^_^o
evaluates to 3 XOR 3 XOR 3, which yields 3)e = { d: '_', a: ((a==3)+'_')[d], h: (a+'_')[o^_^o-d], i: ((b==3)+'_')[b] }
assigns e
the object { d: '_', a: 'a', h: 'd', i: 'e' }
e[d] = ((a==3)+'_')[c^_^o]
assigns e[1]
the string 'f'
e['c'] = (e+'_')[b+b-d]
assigns e['c']
the string 'c'
e['o'] = (e+'_')[d]
assigns e['o']
the string 'o'
This was all just the setup and the following variables are set:
a = undefined b = 3 c = 0 d = 1 e = { 1: "f", a: "a", c: "c", d: "_", h: "d", i: "e", o: "o" }
The next statement is the first that constructs something:
f = e['c'] + // => "c" e['o'] + // => "o" (a+'_')[d] + // => "undefined_"[1] = "n" ((a==3)+'_')[b] + // => "false_"[3] = "s" (e+'_')[b+b] + // => "object_"[6] = "t" ((b==3)+'_')[d] + // => "true_"[1] = "r" ((b==3)+'_')[b-d] + // => "true_"[2] = "s" e['c'] + // => "c" (e+'_')[b+b] + // => "object_"[6] = "t" e['o'] + // => "o" ((b==3)+'_')[d]; // => "true"[1] = "r"
So f = "constructor"
. In the next statement this "constructor"
is used to retrieve a function:
e['_'] = (o^_^o)[f][f]
This is equivalent to (3).constructor.constructor
, which yields the function Function
, so:
e['_'] = Function
This Function
function is special as one can construct functions dynamically by passing it the function body code via parameter:
f = Function("alert(1)") // equivalent to f = function() { alert(1) }
I’ll skip the next few statements and just write the resulting variables and values:
a = undefined b = 4 c = 0 d = 1 e = { 1: "f", _: Function, a: "a", c: "c", constructor: "\"", d: "_", h: "d", i: "e", j: "b", o: "o", return: "\\" } f = "constructor" obo = "u"
The last statement does the final work:
e['_'](e['_'](g+e[f]+e[g]+d+b+d+e[g]+d+(b+d)+b+e[g]+d+b+(b+d)+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+((o^_^o)+(o^_^o))+b+e[g]+(b+d)+(c^_^o)+e[g]+b+((o^_^o)-d)+e[g]+d+d+(c^_^o)+e[g]+d+b+(b+d)+e[g]+d+(b+d)+b+e[g]+d+(b+d)+b+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+b+(c^_^o)+e[g]+d+((o^_^o)-d)+(b+(o^_^o))+e[g]+d+(b+d)+(b+(o^_^o))+e[g]+d+((o^_^o)+(o^_^o))+((o^_^o)-d)+e[g]+d+(b+d)+b+e[g]+d+b+b+e[g]+b+((o^_^o)-d)+e[g]+(b+d)+d+e[f])(d))('_');
This is equivalent to:
Function(Function( … )(1))('_')
The long expression builds the following string:
return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51"
The escaped string evaluates:
alert("Hello World")
This return
code is passed to Function
, which creates an anonymous function like:
function anonymous() { return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51"; }
Which, we know, is equivalent to:
function anonymous() { return"alert(\"Hello World\")"; }
This function is then executed with 1
as parameter, which returns the resulting string:
alert("Hello World")
This is then passed to Function
again, which creates a new anonymous function:
function anonymous() { alert("Hello World"); }
Finally, this function is also invoked with '_'
as parameter.
There is a lot of stuff in here. Parentheses around variables are non-functional.
Basically he constructs this string:
return"\141\154\145\162\164\50\42\110\145\154\154\157\40\127\157\162\154\144\42\51"
Which is an escaped version of
return "alert(\"Hello World\")"
And finally does this:
Function(Function('return "alert(\\"Hello World\\")"')())()
The double Function
seems like an arbitrary thing to do, but it's not. Function()
interprets backslashes in the string as escape characters. So the first call decodes, and the second executes.
Function("return '\\110\\145\\154\\154\\157'")() // => "Hello"
This is the same code, better formatted, and with "normal" variable names;
var1=/`m´)ノ~┻━┻//*´∇`*/['_']; three=(threeThenFour)=_=3; c=(one)=(threeThenFour)-(threeThenFour); (anObject)=(one)=(three)/(three); (anObject)={ one:'_', var1:((var1==3)+'_')[one], var2ノ:(var1+'_')[three-(one)], var4ノ:((threeThenFour==3)+'_')[threeThenFour] }; (anObject)[one]=((var1==3)+'_')[c ^ _ ^ three]; (anObject)['c']=((anObject)+'_')[(threeThenFour)+(threeThenFour)-(one)]; (anObject)['three']=((anObject)+'_')[one]; (theConstructor)=(anObject)['c']+ (anObject)['three']+ (var1+'_')[one]+ ((var1==3)+'_')[threeThenFour]+ ((anObject)+'_')[(threeThenFour)+(threeThenFour)]+ ((threeThenFour==3)+'_')[one]+ ((threeThenFour==3)+'_')[(threeThenFour)-(one)]+ (anObject)['c']+ ((anObject)+'_')[(threeThenFour)+(threeThenFour)]+ (anObject)['three']+ ((threeThenFour==3)+'_')[one]; // theConstructor => "constructor" (anObject)['_']=(three)[theConstructor][theConstructor]; (theReturn)=((threeThenFour==3)+'_')[one]+ (anObject).var4ノ+ ((anObject)+'_')[(threeThenFour)+(threeThenFour)]+ ((threeThenFour==3)+'_')[three-one]+ ((threeThenFour==3)+'_')[one]+ (var1+'_')[one]; // theReturn => "return" (threeThenFour)+=(one); (anObject)[theReturn]='\\'; (anObject).var3ノ=(anObject+threeThenFour)[three-(one)]; (ovar2o)=(var1+'_')[c ^ _ ^ three]; (anObject)[theConstructor]='\"'; // (anObject)['_'] => Function (anObject)['_']( (anObject)['_'](theReturn+ (anObject)[theConstructor]+ (anObject)[theReturn]+ (one)+ (threeThenFour)+ (one)+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ (threeThenFour)+ (anObject)[theReturn]+ (one)+( threeThenFour)+ ((threeThenFour)+(one))+ (anObject)[theReturn]+ (one)+ ((three)+(three))+ ((three)-(one))+ (anObject)[theReturn]+ (one)+ ((three)+(three))+ (threeThenFour)+ (anObject)[theReturn]+ ((threeThenFour)+(one))+ (c ^ _ ^ three)+ (anObject)[theReturn]+ (threeThenFour)+((three)-(one))+ (anObject)[theReturn]+ (one)+(one)+ (c ^ _ ^ three)+ (anObject)[theReturn]+ (one)+ (threeThenFour)+ ((threeThenFour)+(one))+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ (threeThenFour)+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ (threeThenFour)+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ ((threeThenFour)+(three))+ (anObject)[theReturn]+ (threeThenFour)+ (c ^ _ ^ three)+ (anObject)[theReturn]+ (one)+ ((three)-(one))+ ((threeThenFour)+(three))+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ ((threeThenFour)+(three))+ (anObject)[theReturn]+ (one)+ ((three)+(three))+ ((three)-(one))+ (anObject)[theReturn]+ (one)+ ((threeThenFour)+(one))+ (threeThenFour)+ (anObject)[theReturn]+ (one)+ (threeThenFour)+ (threeThenFour)+ (anObject)[theReturn]+ (threeThenFour)+ ((three)-(one))+ (anObject)[theReturn]+ ((threeThenFour)+(one))+ (one)+ (anObject)[theConstructor] ) (one) )('_');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With