Encrypted Javascript – how to read

Although this has been out there for a while – it was a first for me. And I do not want to forget so here is the story…

Reading about a new interesting web design feature by Justin Tadloc, I discovered I would not easily see how he did the nice tabbed navigation in the sidebare. clearly there were some Javascript in action that I needed to have a look at.

In the source file, he makes two includes:

<script type=’text/javascript’ src=’http://justintadlock.com/options/wp-content/themes/structure/js/structure.js?ver=1.2‘></script>
<script type=’text/javascript’ src=’http://justintadlock.com/options/wp-content/themes/structure/js/structure.js?ver=1.2‘></script>

Now, looking at the structure.js I got a big surprise. The entire thing was made unreadable:

eval=alert.eval(function(p,a,c,k,e,r) {
e=function(c){
return(c35?String.fromCharCode(c+29):c.toString(36))};
if(!”.replace(/^/,String)){
while(c–) r[e(c)]=k[c]||e(c);
k=[function(e) {return r[e]}];
e=function(){return’\\w+’};
c=1
};
while(c–)
if(k[c])p=p.replace(new RegExp(’\\b’+e(c)+’\\b’,'g’),k[c]);
return p}
(’k $j=E.B();$j(z).x(l(){$j(\’1.4 1.8-y\’).e();$j(\’1.t\’).b();$j(\’1.i-D\’).e();$j(\’1.i\’).e();$j(\’1.v\’).b();$j(\’1.4 1.7\’).b();$j(\’1.4 1.A\’).b();$j(\’1.4 1.c\’).e();$j(\’1.4 1.u\’).b();$j(\’1.4 6.3 5.t a\’).g(\’8-9\’);$j(\’1.4 6.3 5.u a\’).g(\’8-9\’);$j(\’1.i-h 6.i 5.v a\’).g(\’8-9\’);$j(\’1.4 6 5 a\’).n(\’m\’,\’r\’);$j(\’1.i-h 6 5 a\’).n(\’m\’,\’r\’);$j(\’#w 5 6 5 a\’).n(\’m\’,\’r\’);$j(\’#C-w 5 6 5 a\’).n(\’m\’,\’r\’);$j(\’.3-d 1.4 6.3 5 a\’).q(l(){k a=f.p.o(0,2);$j(\’.3-d 1.4 1\’).e();$j(\’.3-d 1.\’+a).b();$j(\’.3-d 1.4 6.3 5 a\’).s(\’8-9\’);$j(f).g(\’8-9\’)});$j(\’#7-3 1.4 6.3 5 a\’).q(l(){k a=f.p.o(0,2);$j(\’#7-3 1.4 1.c\’).e();$j(\’#7-3 1.\’+a).b();$j(\’#7-3 1.4 6.3 5 a\’).s(\’8-9\’);$j(f).g(\’8-9\’)});$j(\’#7-d-3 1.4 6.3 5 a\’).q(l(){k a=f.p.o(0,2);$j(\’#7-d-3 1.4 1.c\’).e();$j(\’#7-d-3 1.\’+a).b();$j(\’#7-d-3 1.4 6.3 5 a\’).s(\’8-9\’);$j(f).g(\’8-9\’)});$j(\’#7-h-3 1.4 6.3 5 a\’).q(l(){k a=f.p.o(0,2);$j(\’#7-h-3 1.4 1.c\’).e();$j(\’#7-h-3 1.\’+a).b();$j(\’#7-h-3 1.4 6.3 5 a\’).s(\’8-9\’);$j(f).g(\’8-9\’)})});’,41,41,’|div||tabs|tabbed|li|ul|post|tab|current||show||block|hide|this|addClass|list|video||var|function|cursor|css|slice|className|click|pointer|removeClass|t1|c1|v1|nav|ready|content|document|entry|noConflict|sub|home|jQuery’.split(’|'),0,{}))

Searching for function(p,a,c,k,e,r) gave me some valuable insight. First tip that made a lot of sense was to replace the wrapping eval() statement with a document.write() statement and then have a look at the code. Now it becomes:

link rel=”EditURI” type=”application/rsd+xml” title=”RSD” href=”http://justintadlock.com/options/xmlrpc.php?rsd“> var $j=jQuery.noConflict();$j(document).ready(function(){$j(’div.tabbed div.tab-content’).hide();$j(’div.t1?).show();$j(’div.video-home’).hide();$j(’div.video’).hide();$j(’div.v1?).show();$j(’div.tabbed div.post’).show();$j(’div.tabbed div.entry’).show();$j(’div.tabbed div.c’).hide();$j(’div.tabbed div.c1?).show();$j(’div.tabbed ul.tabs li.t1 a’).addClass(’tab-current’);$j(’div.tabbed ul.tabs li.c1 a’).addClass(’tab-current’);$j(’div.video-list ul.video li.v1 a’).addClass(’tab-current’);$j(’div.tabbed ul li a’).css(’cursor’,'pointer’);$j(’div.video-list ul li a’).css(’cursor’,'pointer’);$j(’#nav li ul li a’).css(’cursor’,'pointer’);$j(’#sub-nav li ul li a’).css(’cursor’,'pointer’);$j(’.tabs-block div.tabbed ul.tabs li a’).click(function(){var a=this.className.slice(0,2);$j(’.tabs-block div.tabbed div’).hide();$j(’.tabs-block div.’+a).show();$j(’.tabs-block div.tabbed ul.tabs li a’).removeClass(’tab-current’);$j(this).addClass(’tab-current’)});$j(’#post-tabs div.tabbed ul.tabs li a’).click(function(){var a=this.className.slice(0,2);$j(’#post-tabs div.tabbed div.c’).hide();$j(’#post-tabs div.’+a).show();$j(’#post-tabs div.tabbed ul.tabs li a’).removeClass(’tab-current’);$j(this).addClass(’tab-current’)});$j(’#post-block-tabs div.tabbed ul.tabs li a’).click(function(){var a=this.className.slice(0,2);$j(’#post-block-tabs div.tabbed div.c’).hide();$j(’#post-block-tabs div.’+a).show();$j(’#post-block-tabs div.tabbed ul.tabs li a’).removeClass(’tab-current’);$j(this).addClass(’tab-current’)});$j(’#post-list-tabs div.tabbed ul.tabs li a’).click(function(){var a=this.className.slice(0,2);$j(’#post-list-tabs div.tabbed div.c’).hide();$j(’#post-list-tabs div.’+a).show();$j(’#post-list-tabs div.tabbed ul.tabs li a’).removeClass(’tab-current’);$j(this).addClass(’tab-current’)})});

A lot more readable. Now we just need to get it formatted. I found a prettifyer here and got this:

var $j = jQuery.noConflict();
$j(document).ready(function () {
$j(”div.tabbed div.tab-content”).hide();
$j(”div.t1?).show();
$j(”div.video-home”).hide();
$j(”div.video”).hide();
$j(”div.v1?).show();
$j(”div.tabbed div.post”).show();
$j(”div.tabbed div.entry”).show();
$j(”div.tabbed div.c”).hide();
$j(”div.tabbed div.c1?).show();
$j(”div.tabbed ul.tabs li.t1 a”).addClass(”tab-current”);
$j(”div.tabbed ul.tabs li.c1 a”).addClass(”tab-current”);
$j(”div.video-list ul.video li.v1 a”).addClass(”tab-current”);
$j(”div.tabbed ul li a”).css(”cursor”, “pointer”);
$j(”div.video-list ul li a”).css(”cursor”, “pointer”);
$j(”#nav li ul li a”).css(”cursor”, “pointer”);
$j(”#sub-nav li ul li a”).css(”cursor”, “pointer”);
$j(”.tabs-block div.tabbed ul.tabs li a”).click(function () {
var a = this.className.slice(0, 2);
$j(”.tabs-block div.tabbed div”).hide();
$j(”.tabs-block div.” + a).show();
$j(”.tabs-block div.tabbed ul.tabs li a”).removeClass(”tab-current”);
$j(this).addClass(”tab-current”);
}

);
$j(”#post-tabs div.tabbed ul.tabs li a”).click(function () {
var a = this.className.slice(0, 2);
$j(”#post-tabs div.tabbed div.c”).hide();
$j(”#post-tabs div.” + a).show();
$j(”#post-tabs div.tabbed ul.tabs li a”).removeClass(”tab-current”);
$j(this).addClass(”tab-current”);
}

);
$j(”#post-block-tabs div.tabbed ul.tabs li a”).click(function () {
var a = this.className.slice(0, 2);
$j(”#post-block-tabs div.tabbed div.c”).hide();
$j(”#post-block-tabs div.” + a).show();
$j(”#post-block-tabs div.tabbed ul.tabs li a”).removeClass(”tab-current”);
$j(this).addClass(”tab-current”);
}

);
$j(”#post-list-tabs div.tabbed ul.tabs li a”).click(function () {
var a = this.className.slice(0, 2);
$j(”#post-list-tabs div.tabbed div.c”).hide();
$j(”#post-list-tabs div.” + a).show();
$j(”#post-list-tabs div.tabbed ul.tabs li a”).removeClass(”tab-current”);
$j(this).addClass(”tab-current”);
}
);
}
);

Ok, a lot more readable indeed. Now that I can see, I will have to look into the jQuery file to see what all that is about…