jjencode decoder (jjdecode)
So I’ve had a look at jjencode some time ago and today I decided to do a decoder for the bloody thing. Instead of creating an entire parser for JS I decided to trust the code a bit by evaling the code prior to the encoded part and thereby letting the browsers JS engine build up the scope for me to use afterwards.
If you have no clue what jjencode is then you can read this: http://pferrie2.tripod.com/papers/jjencode.pdf and this: http://utf-8.jp/public/20090710/jjencode.pps. And you can try it here: http://utf-8.jp/public/jjencode.html. Basicly it encoded your code into symbols only. alert(0) would be be encoded into this (with parameter g set to “_”):
1: _=~[];
2: _={___:++_,$$$$:(![]+"")[_],__$:++_,$_$_:(![]+"")[_],_$_:++_,$_$$:({}+"")[_],$$_$:(_[_]+"")[_],_$$:++_,$$$_:(!""+"")[_],$__:++_,$_$:++_,$$__:({}+"")[_],$$_:++_,$$$:++_,$___:++_,$__$:++_};
3: _.$_=(_.$_=_+"")[_.$_$]+(_._$=_.$_[_.__$])+(_.$$=(_.$+"")[_.__$])+((!_)+"")[_._$$]+(_.__=_.$_[_.$$_])+(_.$=(!""+"")[_.__$])+(_._=(!""+"")[_._$_])+_.$_[_.$_$]+_.__+_._$+_.$;
4: _.$$=_.$+(!""+"")[_._$$]+_.__+_._+_.$+_.$$;
5: _.$=(_.___)[_.$_][_.$_];
6: _.$(_.$(_.$$+"\""+_.$_$_+(![]+"")[_._$_]+_.$$$_+"\\"+_.__$+_.$$_+_._$_+_.__+"("+_.___+")"+"\"")())();
I’m aware that could lead to some code execution in the decoding part but if that code is incoded it needs the full scope inorder to eval it. All non-encoded code I would be able to filter of by myself. A code which could trigger a code execution at accident at this time would be:
1: _=~[];
2: alert(0);
3: _={___:++_,$$$$:(![]+"")[_],__$:++_,$_$_:(![]+"")[_],_$_:++_,$_$$:({}+"")[_],$$_$:(_[_]+"")[_],_$$:++_,$$$_:(!""+"")[_],$__:++_,$_$:++_,$$__:({}+"")[_],$$_:++_,$$$:++_,$___:++_,$__$:++_};
4: _.$_=(_.$_=_+"")[_.$_$]+(_._$=_.$_[_.__$])+(_.$$=(_.$+"")[_.__$])+((!_)+"")[_._$$]+(_.__=_.$_[_.$$_])+(_.$=(!""+"")[_.__$])+(_._=(!""+"")[_._$_])+_.$_[_.$_$]+_.__+_._$+_.$;
5: _.$$=_.$+(!""+"")[_._$$]+_.__+_._+_.$+_.$$;
6: _.$=(_.___)[_.$_][_.$_];
7: _.$(_.$(_.$$+"\""+_.$_$_+(![]+"")[_._$_]+_.$$$_+"\\"+_.__$+_.$$_+_._$_+_.__+"("+_.___+")"+"\"")())();
The alert(0) in the second line would be fired off, but then again. It’s quite easy to spot in this example. If I get some more time, I’ll go the long was in decoding this the proper way.
In the decoder I start by finding the variable name of the main object (in the encoder that’s the paramter g) hereafter I start splitting the encoded code up at all semi-colons (;) with a RegEx. Here’s the two RegExs, first the one for parameter g and then the one for splitting up the lines (text is my input of encoded code).
1: var g = text.match(/([^=])=~\[\];/)[1];
2: var lines = text.match(/([^;]*);/g);
With g and the lines in hand I do a loop on the lines checking for the execution part of jjencode. If it’s not found I’ll eval the line, otherwise I’ll set the variable lookAhead to true and thereby concatinating the rest of the encoded lines before pulling out the encoded code out of the execution part and running eval on the thing for it to return it’s content. More explaning comes later on. Here’s the if from the loop, I’ll just run it through.
1: if ( ! lines[i].match(/_.\$\(_.\$\(/) && ! lookAhead) {
2: eval(lines[i]);
3: } else {
4: lookAhead = true;
5: finalLine = finalLine + lines[i];
6:
7: if (i == lines.length - 1) {
8: // _.\$\((.*)(\)\(\))
9: var re = new RegExp(g + '.\\$\\((.*)(\\)\\(\\))');
10: var reString = finalLine.match(re);
11: output = eval(reString[1]);
12: }
13: }
Line 1 if of course the check whether the execution part of jjencode is to be found in the line. If not I’ll eval the code at line 2. Inside the else I’ll start the lookAhead since the execution part was found, I’ll concat the line to the finalLine variable. When there is no more lines to concat it will trigger the if sentence at line 7. The RegEx at line 9 vill take the return code inside the execution part and take it out to eval it and return lastly.
You can try the thing here: http://e-x-e.dk/labs/jjdecode/index.php, go have some fun and let me know if you do something smiliar. Remeber to have your console open when fooling around with this. The decoder function can be found here: http://e-x-e.dk/labs/jjdecode/assets/decoder.js and the encoder here: http://e-x-e.dk/labs/jjdecode/assets/encoder.js (the encoder is from http://utf-8.jp/public/jjencode.html).
