I would appreciate if someone could identify what tool or process may have been used to obfuscate two files.
It is actually code that we hired an HTML5 developer to create. On delivery, some of the .js code was obfuscated. I did specify that we would get the source code, but for various reasons, I don't want to force that, at least not right now. I don't need to edit the source code yet, but I want to know my options and perhaps simplify the situation.
Here are small excerpts from the two files
data.js (from the start of the file)
{"project": [null,null,[[0,true,false,false,false,false,false,false,false,false],[1,true,false,false,false,false,false,false,false,false],[2,true,false,false,false,false,false,false,false,false],[3,false,true,true,true,true,false,false,false,false],[4,true,false,false,false,false,false,false,false,false],[5,false,true,true,true,true,true,true,true,false],[6,false,true,true,true,true,true,true,true,false],[7,false,true,true,true,true,true,true,true,false],[8,true,false,false,false,false,false,false,false,false]],[["t0",5,false,[],0,0,null,[["Default",5,false,1,0,false,3756169185149289,[["imgs/bg-sheet0.png",45907,0,0,1105,500,1,0.5004525184631348,0.5,[],[],0]]]],[],false,false,5609930934870015,[],null],["t1",5,false,[],0,0,null,[["Default",30,false,1,0,false,6181700866648787,[["imgs/m-sheet0.png",3199641,1,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,340,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,679,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,1018,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,1357,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,1696,1,337,500,1,0.501483678817749,0.5,[],[],0],["imgs/m-sheet0.png",3199641,1,503,337,500,1,0.501483678817749,0.5,[],[],0],[.....
runtime.js (also from the start of the file)
'use strict';var ba,ca,da,ea,fa,ga,B,ha,ja,ka,la,ma,na,oa,pa,qa,ta,ua,va,wa,xa,ya,Aa,Ba,O,Da,Ea,Fa,Ga,Ha,R,Ia,Ja,Ka,La,Na,Oa,Pa,Qa,Ra,Sa,Ta,Ua,Va,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb,nb,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab,Bb,Cb,Db,Fb,Gb,Hb,Ib,Jb,Kb,Lb,Mb,Nb,Ob,Pb,Qb,Rb,Sb,Tb,Ub,Vb,Wb,Xb,Yb,Zb,$b,ac,bc,cc,dc,ec,fc,gc,hc,ic={},jc={};"function"!==typeof Object.getPrototypeOf&&(Object.getPrototypeOf="object"===typeof"test".__proto__?function(g){return g.__proto__}:function(g){return g.constructor.prototype});
(function(){function g(a,x,b,f){this.set(a,x,b,f)}function q(){this.xc=this.wc=this.zc=this.yc=this.Oc=this.Nc=this.gc=this.fc=0}function l(a,x,b,f){a<x?b<f?(y=a<b?a:b,p=x>f?x:f):(y=a<f?a:f,p=x>b?x:b):b<f?(y=x<b?x:b,p=a>f?a:f):(y=x<f?x:f,p=a>b?a:b)}function h(){this.items=this.ie=null;this.yi=0;I&&(this.ie=new Set);this.Gh=[];this.ef=!0}function e(a){P[w++]=a}function r(){this.R=this.jl=this.y=this.Rl=0}function c(a){this.qh=[];this.dp=this.fp=this.gp=this.ep=0;this.ej(a)}function b(a,x){this.Xl=a;this.Wl=x;this.cells={}}function t(a,x){this.Xl=;this.Wl=x;this.cells={}}function d(a,x,b){var f;return A.length?(f=A.pop(),f.Km=a,f.x=x,f.y=b,f):new ba(a,x,b)}function a(a,x,b){this.Km=a;this.x=x;this.y=b;this.Ab=new ca}function f(a,x,b){var f;return D.length?(f=D.pop(),f.Km=a,f.x=x,f.y=b,f):new da(a,x,b)}function m(a,x,b){this.Km=a;this.x=x;this.y=b;this.Ab=[];this.Ug=!0;this.fe=new ca;this.Lh=!1}function k(a,x){return a.Pd-x.Pd}ea=function(a){window.console&&window.console.log&&window.console.log(a)};
And from the end of the same file
h.zz=function(e){this.r=e};h.kz=function(e){this.Wh=e};h.sz=function(e){this.J=e};h.rz=function(e,g,c,b,l,d,a,f){this.r=e;this.J=g;this.Wh=c;h.Pt.apply(this,[b]);h.Tt.apply(this,[l]);h.Nt.apply(this,[d]);h.Yt.apply(this,[a]);this.Rb=f;this.zf()};q.eb={};q=q.eb;q.$y=function(e){e.u(this.L/(this.duration+this.na+this.Fa))};q.az=function(e){e.u(this.L)};q.Ps=function(e){e.u(this.duration)};q.Ey=function(e){e.u(this.na)};q.yy=function(e){e.u(this.Fa)};q.Gz=function(e){e.Nb(this.target)};q.Jz=function(e){e.u(this.value)};q.ag=function(e){e.Ea(this.ag?1:0)}})();functionc()return[tc,uc,wc,vc,sc,Z,zc,xc,yc,Ec,Ac,Fc,X.prototype.g.yo,zc.prototype.F.As,zc.prototype.g.Ns,zc.prototype.F.Ko,zc.prototype.F.Ho,zc.prototype.F.Io,zc.prototype.F.Jo,zc.prototype.F.ro,X.prototype.g.Dt,Z.prototype.F.Os,X.prototype.F.du,zc.prototype.F.Rt,Fc.prototype.F.Ut,Fc.prototype.F.Vt,Fc.prototype.F.Mo,Ac.prototype.F.$t,X.prototype.g.Ws,wc.prototype.g.Ys,Z.prototype.g.Ts,Z.prototype.F.Lt,X.prototype.g.cu,tc.prototype.F.Play,X.prototype.g.so,wc.prototype.F.Mt,wc.prototype.g.Dl,yc.prototype.g.Fl,sc.prototype.F.CallFunction,Z.prototype.F.Kt,X.prototype.F.Ot,X.prototype.F.Wt,X.prototype.g.Ks,Z.prototype.F.Zt,Z.prototype.F.St,Z.prototype.g.Xs,X.prototype.F.Gt,X.prototype.F.It,uc.prototype.F.Ss,X.prototype.F.Ms,Z.prototype.F.Qt,Z.prototype.eb.Hl,Ec.prototype.F.Et,Z.prototype.g.to,Ac.prototype.F.Ht,Z.prototype.g.Js,Fc.prototype.g.wo,Z.prototype.g.Hs,Z.prototype.g.Ls,X.prototype.F.Bs,X.prototype.F.au,Z.prototype.g.Is,sc.prototype.g.xj]};
There are many tools available to help deobfuscate code, plugins like javascript-deobfuscator and websites such as this and this can help in the process but sometimes if the obfuscation is incredibly complex or too deep some people have noted problems with performance etc.
As to what tool was used to obfuscate the code that list is also potentially very large as for many people obfuscation is common practice to protect the code as well as to reduce the memory requirement of a script. They are also widely available like this and this. It really depends on the level of obfuscation they wanted to reach.
here are some other popular options for obfuscation:
YUI Compressor
Google closure compiler
JSSCrambler
Do you have a step in your deployment process that minifies JS? Do you have any sort of preprocessor for your JavaScript that allows you to leave in comments and console.logs and then have them automatically stripped out? Is your JavaScript machine generated by GWT or Script#? Do you use ANT or another tool to automate deployment?
I see a lot of JavaScript that looks like it comes right out of the editor, complete with lots of white space and comments. How much of that is due to not caring about the state of the deployed code, and how much is due to the spirit of the open web?
I usually check it out with JSLint to make sure it is bug-free, then pack it/encode it with YUI compressor.
My steps include:
I write Javascript using TextMate with the Javascript Tools bundle installed. This JSLint's my files on every save and notifies me when errors occur.
I use Sprockets to automatically concatenate my various Javascript files.
I run the resulting concatenation through jsmin to generate a minified version.
I end up with a concatenated lib.js file and a minified lib.min.js file. One I use for development, one for production. TextMate commands help automate it all.
I'm still looking for a good solution to actually (unit) test my scripts.
Check out YUI Compressor its a console app that you can use to minify (strip out comments, whitespace etc..) and also obfuscate your javascript files.
JSMin it from Douglas Crockford. We've got it hooked up as a macro in Studio as well as a post build item for some of our larger projects
FWIW, here's an interesting mini-benchmark on various ways you can minimize your Javascript source:
http://www.ericmmartin.com/comparison-of-javascript-compression-methods/
In short:
gzip compression in HTTP protocol really makes a difference (although you need to pay a CPU cost at the server side)
minification (removal of whitespace/comments, change of variable names etc.) also helps, and if you want best result, use it together with gzip compression
js-based decompressors are most likely useless - while you might get smaller size, the CPU overhead on the client is significant.
For one of our products, we concatenate all Javascript files together (most files are used on most pages, so this makes sense for us) and use Javascript::Minifier. This has given us a pretty nice speed boost.
A lot of it is probably due to not caring about people that might be viewing your pages on slower machines with slower connections and assuming that everyone has a 50Mbps line and three Gigs of RAM.
We are minifying our (hand-written + plugins, jQuery, etc.) JS as a part of the build process in .NET environment. No preprocessor, this is something we should definitely be doing once time permits.
P.S. By the way, we're not using console.log, as this will break IE. Instead we have a simple wrapper function, something like:
function log(stuff) {
if (window.console && window.console.log) {
console.log(stuff);
}
};
I have a PHP script that does it on the server side and keeps a cache of whatever it pulls from the source folder(s).
One word- packer
Light a candle, whisper a prayer against IE6 errors, and click "go". Does that count? :)
I don't minify my own javascript code since text tends to gzip/compress well.
I would minify a very large (say > 100 kb) javascript library (but then again I probably would not want to be using such a large library (or just ship what i use)).
I tend to believe that a lot of the javascript-minification is (in reality) done to achieve some sort of (futile) obfuscation of javascript code instead of the proclaimed end-user performance gain.
There's also a .NET port of YUI Compressor which allows you to:-
intergrate the minification/file combining into Visual Studio post-build events
intergrate into a TFS Build (including CI)
if you wish to just use the dll's in your own code (eg. on the fly minification).
I thought I would share my approach to js deployments. Have a look at this blog post:
http://www.picnet.com.au/blogs/Guido/post/2009/12/10/Javascript-runtime-compilation-using-AspNet-and-Googles-Closure-Compiler.aspx
This also includes code to compile (using google's closure compiler) at runtime (when needed).
Thanks Guido