Can someone explain me how http://utf-8.jp/public/jjencode.html works and if is good to use it on my code? The first time I tried it I thought that I needed to have some kind of algorithm in my code to use it, but it works on every site. What is happening?
I already read the source code but I don’t understand it.
Advertisement
Answer
Here is the commented script http://corkami.googlecode.com/svn-history/r399/trunk/misc/jjencode.txt
// this is a commented source of a jjencode script // jjencode, http://utf-8.jp/public/jjencode.html // reference: Peter Ferrie, 2011, http://pferrie2.tripod.com/papers/jjencode.pdf // for reference, // alert("Hello, JavaScript" ) // is encoded as // $=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\"+$.__$+$.$$_+$._$_+$.__+"(\"\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+",\"+$.$__+$.___+"\"+$.__$+$.__$+$._$_+$.$_$_+"\"+$.__$+$.$$_+$.$$_+$.$_$_+"\"+$.__$+$._$_+$._$$+$.$$__+"\"+$.__$+$.$$_+$._$_+"\"+$.__$+$.$_$+$.__$+"\"+$.__$+$.$$_+$.___+$.__+"\"\"+$.$__+$.___+")"+""")())(); // preliminary points // (a + "") gives the string representation of a // [] = empty array. 0 by value, -1 with ~ => ~[] = -1 // as a string, ![] gives 'false' // {} = empty object. // as a string, {} gives '[object Object]' // if a is a x-long array, a[x] is 'undefined' as a string. same for absent properties. // "" is an empty string. !"" returns 'true' as it is indeed 'null' // now let's start with the actual code // creating $ variable with a value. $=~[]; // $ = -1 // defining properties of a $ object. $ = { ___:++$, // 0, $ = 0 $$$$:(![] + ””)[$], // 0th char of 'false', => 'f' __$:++$, // 1, $ = 1 now... $_$_:(![] + ””)[$], // 1st char of 'false' => 'a' _$_:++$, // 2... $_$$:({} + ””)[$], // 2nd char of '[object Object]' => 'b' $$_$:($[$] + ””)[$], // 2nd char of 'undefined' => 'd' _$$:++$, // 3... $$$_:(!”” + ””)[$], // 3rd char of 'true' => 'e' $__:++$, // 4 $_$:++$, // 5 $$__:({} + ””)[$], // 5th char of '[object Object]' => 'c' $$_:++$, // 6 $$$:++$, // 7 $___:++$, // 8 $__$:++$ // 9 }; // => in order, ___, __$, _$_, _$$, $__, $_$, $$_, $$$, $___, $__$, $_$_, $_$$, $$__, $$_$, $$$_, $$$$ are now equal to 0...F, // note they are just binary numbers with character substitution $.$_ = ($.$_ = $ + ””)[$.$_$] + // 5th character of '[object Object]' => $.$_ = 'c' ($._$ = $.$_[$.__$]) + // 1st character of ... => $._$ = 'o' ($.$$ = ($.$ + ””)[$.__$]) + // 1st char of 'undefined' => $.$$ = 'n' ((!$) + ””)[$._$$] + // 3rd char of 'false' => 's' // poor s, we don't save it... ($.__ = $.$_[$.$$_]) + // 6th char of '[object Object]' => $.__ = 't' ($.$ = (!”” + ””)[$.__$]) + // 1st char of 'true' => $.$ = 'r' ($._ = (!”” + ””)[$._$_]) + // 2nd char of 'true' => $._ = 'u' $.$_[$.$_$] + // 5th char of '[object Object]'] => 'c' // hey, we already have a c ! $.__ + // 't' $._$ + // 'o' $.$; // 'r' // => $.$_ = 'constructor' $.$$ = $.$ + // 'r' (!”” + ””)[$._$$] + // 'true'[3] => 'e' $.__ + // 't' $._ + // 'u' $.$ + // 'r' $.$$; // 'n' $.$ = ($.___)[$.$_][$.$_]; // (0)[constructor][constructor] // summary of $ at this point // $ = {} // $.___ = '0'; // $.__$ = '1'; // $._$_ = '2'; // $._$$ = '3'; // $.$__ = '4'; // $.$_$ = '5'; // $.$$_ = '6'; // $.$$$ = '7'; // $.$___ = '8'; // $.$__$ = '9'; // $.$_$_ = 'a'; // $.$_$$ = 'b'; // $.$$__ = 'c'; // $.$$_$ = 'd'; // $.$$$_ = 'e'; // $.$$$$ = 'f'; // $.$_ = 'c' // $._$ = 'o' // $.$$ = 'n' // $.__ = 't' // $.$ = 'r' // $._ = 'u' // $.$_ = 'constructor'; // $.$$ = 'return'; // $.$ = (0)[constructor][constructor] // and finally, the only line of call $.$( $.$( $.$$ + ””” + ENCODED + ””” )() ) (); // (0)[constructor][constructor]( (0)[constructor][constructor]( return + " + ENCODED + " )() )() // 'equivalent' to eval(eval(ENCODED)) // encoding // !"#$%&’()*+,-./:;<>=?@[]^_`{|}~ as is // 0123456789abcdeftou => as $ properties. Ex : 'babe' = $.$_$$ + $.$_$_ + $.$_$$ + $.$$$_ // other ascii chars: as xxx (octal) encoding. Ex: 'A' = char(65) = 101 = "\" + $.__$ + $.___ + $.__$ // unicode chars as u????. ex: 'sea', u6d77 as "\" + $._ + $.$$_ + $.$$_$ + $.$$$ + $.$$$ // so in the end, it's just defining a $ object and executing an eval on a string, that is built character by character. // to confirm, here is a small imperfect python decryption script // import sys // start = r'$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"""+' // end = r'+""")())();' // // with open(sys.argv[1], "rb") as f: // r = f.read() // // r = r.replace(start, "").replace(end, "") // print r // // subst = [ // ['$.$___','8'], // ['$.$__$','9'], // ['$.$_$_','a'], // ['$.$_$$','b'], // ['$.$$__','c'], // ['$.$$_$','d'], // ['$.$$$_','e'], // ['$.$$$$','f'], // ['$.___','0'], // ['$.__$','1'], // ['$._$_','2'], // ['$._$$','3'], // ['$.$__','4'], // ['$.$_$','5'], // ['$.$$_','6'], // ['$.$$$','7'], // ['$.$_', 'c'], // ['$._$', 'o'], // ['$.$$', 'n'], // ['$.__', 't'], // ['$.$', 'r'], // ['$._', 'u'], // [r'"\"' , '\'], // [""\\\\"", "\\"], // ["+", ""], // ] // // for s in subst: // r = r.replace(s[0], s[1]) // // r = r.replace("+", "") // print r // Ange Albertini, BSD Licence 2011