[Tip-Javascript] Desempaquetando scripts

Atendiendo a un email que me llego, de parte de uno de mis lectores, he decidido hacer un post para darle seguimiento a su problema.

Resulta que hace tiempo yo puse una solucion para que si tenemos un script escrito en Javascript, lo pudieramos empaquetar, esta solucion consta de un programa, el cual mediante diversos mecanismos, comprime y por asi decirlo empaqueta nuestro codigo.

Hasta ahi todo bien, sin embargo que pasa si tenemos empaquetado nuestro codigo y deseamos hacer la inversa?, osea desempaquetar el codigo?.

Primero tenemos un programa que empaqueta codigo y tambien desempaqueta, pero solo desempaqueta el codigo, que le indicamos anteriormente que nos empaquete, este programa lo pueden localizar en la siguiente pagina web.

http://dean.edwards.name/packer/

Primero debemos bajar el codigo fuente de este programa (de preferencia en PHP), por que aun no se como programar bien en perl y quiza tengan problemas.

Si tienen dudas sobre la instalacion de apache o la configuracion de php pueden checar el manual que escribi anteriormente en el blog.

Manual de instalacion y configuracion de apache con windows

Ahora bien ya que hemos descargado nuestro codigo vamos a extraerlo y lo ponemos en nuestro servidor web, que por defualt seria Localhost

Si lo hemos hecho por default y lo descomprimimos directamente en raiz, podremos entrar usando la siguiente direccion: http://localhost/packer.php-1.0/.

Ahi veremos los siguiente archivos

Index of /packer.php-1.0

  • Parent Directory
  • class.JavaScriptPacker.php
  • class.JavaScriptPacker.php4
  • example-file.php
  • example-inline.php
  • readme.txt


abrimos el archivo example-inline.php y veremos una pagina donde podemos comprimir nuestro codigo javascript, podemos hacer la prueba con cualquier js que tengan a la mano.

Yo por ejemplo use el parte del codigo de la mini-libreria JXS, asi pues si tenemos el siguiente codigo

.

….
…….
…………….
Jxs=
{
_D: function (_i,_t,_d,_p,_ta)
{
if(typeof _ta!=”undefined” || _ta!=0)Jxs._T(_i,_ta);
var _id=_I(_i);
_id.onkeydown=function(e)
{
var _tcl=(typeof e==”undefined”)?window.event.keyCode:e.which;
switch(_t)
{
case “R”:
var _ind=_d.split(“,”);
var _exp=(_p==true)?”_tcl<_ind [0] || _tcl>_ind[1]”:”_tcl>_ind[0] && _tcl</_ind><_ind [1]”;
if(eval(_exp)){if(e)e.preventDefault(); return false;}
else{return true;}
break;

case “A”:
var _ind=_d.split(“,”);
var _ctrl=0;
var _tam=_ind.length;
var _exp=(_p==true)?”_ind[i]==_tcl”:”_ind[i]==_tcl”;
var _ret=(_p==true)?”!_ctrl”:”_ctrl”;
for(i = 0 ; i<_tam; i++)
{_ctrl+=(_ind[i]==_tcl)?1:0;}
if(eval(_ret)){if(e)e.preventDefault(); return false;}else{return true;}
break;

case “U”:
var _exp=(_p==true)?”_tcl!=_d”:”_tcl==_d”;
if(eval(_exp))
{if(e)e.preventDefault();return false;}
else{return true;}
break;

default:
var _exp=(_p==true)?”_tcl!=_d”:”_tcl==_d”;
if(eval(_exp))
{if(e)e.preventDefault(); return false;}
else{return true;}
break;
}
}
},
_T: function(_i,_ta)
{
var _id=_I(_i);
if(typeof _ta==”undefined” || _ta==0)
{return true;}
else
{
_id.maxLength=_ta;
_id.setAttribute(“size”,_ta);
return true;
}
},
_V:function(_t,_i,_e,_m)
{
var _id=_I(_i);
switch(_t)
{
case “txt”:
var _v=_V(_i);
var _l=(typeof _m != “undefined”)?’_v==”” || _v.length<_m’:’_v==””‘;
if(eval(_l))
{
alert(_e);
_F(_i);
return false;
}
else
{
return true;
}
break;
case “mail”:
var emailStr=_V(_i);
var emailPat=/^(.+)@(.+)$/
var specialChars=”\\(\\)<>@,;:\\\\\\\”\\.\\[\\]”;
var validChars=”\[^\\s” + specialChars + “\]”;
var quotedUser=”(\”[^\”]*\”)”;
var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
var atom=validChars + ‘+’;
var word=”(” + atom + “|” + quotedUser + “)”;
var userPat=new RegExp(“^” + word + “(\\.” + word + “)*$”)
var domainPat=new RegExp(“^” + atom + “(\\.” + atom +”)*$”)
var matchArray=emailStr.match(emailPat)
if (matchArray==null) {alert(_e);_F(_i);return false;}
var user=matchArray[1];
var domain=matchArray[2];
if (user.match(userPat)==null){alert(_e);_F(_i);return false;}
var atomPat=new RegExp(atom,”g”);
var domArr=domain.match(atomPat);
var len=domArr.length;
if (domArr[domArr.length-1].length<2 || domArr[domArr.length-1].length>3) {alert(_e);_F(_i);return false;}
if (len<2) {alert(_e);_F(_i);return false;}
break;

default:
var _v=_V(_i);
var _l=(typeof _m != “undefined”)?’_v==”” || _v.length<_m ‘:’_v==””‘;
if(eval(_l))
{
alert(_e);
_F(_i);
return false;
}
else
{
return true;
}
break;
}

}
}
etc
etc etc etc
……………….
…………………….
……………………..

Copiamos y pegamos el codigo y lo pegamos, despues le damos click en donde dice pack y listo con eso obtenemos nuestro codigo comprimido

Y queda asi

eval(function(p,a,c,k,e,d){e=function(c){return(c<a?”:e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!”.replace(/^/,String)){while(c–){d[e(c)]=k[c]||e(c)}k=[function(e){return d[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}(‘T={1b:C(6,B,l,o,c){7(y c!=”w”||c!=0)T.Q(6,c);4 q=J(6);q.1i=C(e){4 9=(y e==”w”)?1k.17.19:e.1c;N(B){z”R”:4 a=l.O(“,”);4 n=(o==8)?”9<a [0] || 9>a[1]”:”9>a[0] && 9</a><a [1]”;7(u(n)){7(e)e.E();5 b}k{5 8}j;z”A”:4 a=l.O(“,”);4 F=0;4 S=a.f;4 n=(o==8)?”a[i]==9″:”a[i]==9″;4 P=(o==8)?”!F”:”F”;1a(i=0;i<S;i++){F+=(a[i]==9)?1:0}7(u(P)){7(e)e.E();5 b}k{5 8}j;z”U”:4 n=(o==8)?”9!=l”:”9==l”;7(u(n)){7(e)e.E();5 b}k{5 8}j;15:4 n=(o==8)?”9!=l”:”9==l”;7(u(n)){7(e)e.E();5 b}k{5 8}j}}},Q:C(6,c){4 q=J(6);7(y c==”w”||c==0){5 8}k{q.1h=c;q.1f(“1g”,c);5 8}},G:C(B,6,m,x){4 q=J(6);N(B){z”18″:4 h=G(6);4 H=(y x!=”w”)?\’h==”” || h.f><x\’:\’h==””\’;7(u(H)){r(m);t(6);5 b}k{5 8}j;z”1d”:4 12=G(6);4 13=/^(.+)@(.+)$/4 16=”\\\\(\\\\)<>@,;:\\\\\\\\\\\\\\”\\\\.\\\\[\\\\]”;4 V=”\\[^\\\\s”+16+”\\]”;4 14=”(\\”[^\\”]*\\”)”;4 1e=/^\\[(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\]$/4 v=V+\’+\’;4 M=”(“+v+”|”+14+”)”;4 W=I L(“^”+M+”(\\\\.”+M+”)*$”)4 1j=I L(“^”+v+”(\\\\.”+v+”)*$”)4 D=12.K(13)7(D==Y){r(m);t(6);5 b}4 X=D[1];4 Z=D[2];7(X.K(W)==Y){r(m);t(6);5 b}4 11=I L(v,”g”);4 p=Z.K(11);4 10=p.f;7(p[p.f-1].f<2||p[p.f-1].f>3){r(m);t(6);5 b}7(10<2){r(m);t(6);5 b}j;15:4 h=G(6);4 H=(y x!=”w”)?\’h==”” || h.f<x \’:\’h==””\’;7(u(H)){r(m);t(6);5 b}k{5 8}j}}}’,62,83,’||||var|return|_i|if|true|_tcl|_ind|false|_ta|||length||_v||break|else|_d|_e|_exp|_p|domArr|_id|alert||_F|eval|atom|undefined|_m|typeof|case||_t|function|matchArray|preventDefault|_ctrl|_V|_l|new|_I|match|RegExp|word|switch|split|_ret|_T||_tam|Jxs||validChars|userPat|user|null|domain|len|atomPat|emailStr|emailPat|quotedUser|default|specialChars|event|txt|keyCode|for|_D|which|mail|ipDomainPat|setAttribute|size|maxLength|onkeydown|domainPat|window’.split(‘|’),0,{}))
>

Interesante verdad??, pero como lo descomprimimos???.

Facil, notaran que hay un boton que dice decode, lo presionamos y veremos nuestro codigo tal cual fue hecho, ahora bien como notaron el campo es de solo lectura, asiq ue de momento no podremos pegar ningun tipo de codigo dentro de ese cuadro.

Entonces vamos a modificarlo:

1.- Abrimos el archivo example-inline.php, con un editor de php(o Vim/bloc de notas)

2.- En la linea 78 , veremos el siguiente codigo

 <textarea id=”packed” class=”result” rows=”10″ cols=”80″ readonly=”readonly”>……..

3.- Ahora solo quitaremos el reaaonly=”readonly” para que podamos escribir cualquier cosa dentro del recuadro y nos quedara asi.

<textarea id=”packed” class=”result” rows=”10″ cols=”80″>……..

4.-Lo guardamos y listo recargamos la pagina del empaquetador en nuestro navegador, y veremos que ya podemos pegar nuestro codigo.

Y listo, yo hice unas pruebas con la libreria mootools y me dio excelentes resultados.

De tener un codigo asi[Es solo una parte]

eval(function(p,a,c,k,e,d){e=function(c){return(c<a ?”:e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!”.replace(/^/,String)){while(c–){d[e(c)]=k[c]||e(c)}k=[function(e){return d[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}(‘l 14=h(1t){l 3F=h(){k(9.1l&&U[0]!=\’5t\’)f 9.1l.2s(9,U);R f 9};P(l o 1f 9)3F[o]=9[o];3F.M=1t;f 3F};14.1A=h(){};14.M={J:h(1t){l 3l=Q 9(\’5t\’);l 5n=h(23,1j){k(!23.2s||!1j.2s)f L;f h(){9.1k=23;f 1j.2s(9,U)}};P(l o 1f 1t){l 23=3l[o];l 1j=1t[o];k(23&&23!=1j)1j=5n(23,1j)||1j;3l[o]=1j}f Q 14(3l)},1Y:h(1t){P(l o 1f 1t)9.M[o]=1t[o]}};1I.J=h(){l O=U;O=(O[1])?[O[0],O[1]]:[9,O[0]];P(l o 1f O[1])O[0][o]=O[1][o];f O[0]};1I.4A=h(){P(l i=0;i<u .V;i++)U[i].J=14.M.1Y};Q 1I.4A(4k,1h,3N,6e,14);k(4Y 2L==\’5q\’){l 2L=14.1A;2L.M={}}R{2L.M.4C=19}T.J=B.J=1I.J;l 70=T;h $n(K){k(K===1D||K===5q)f L;l n=4Y K;k(n==\’3L\’){k(K.4C)f\’W\’;k(K.1g)f\’1r\’;k(K.6V){1K(K.5r){12 1:f\’W\’;12 3:f K.6W.11(/\\S/)?\’6E\’:\’3X\’}}}f n};h $2Y(K){f!!(K||K===0)};h $6H(K,5E){f($n(K))?K:5E};h $5k(33,1S){f u.7K(u.5k()*(1S-33+1)+33)};h $4v(1o){7t(1o);7u(1o);f 1D};k(T.5a)T.2a=T[T.4D?\’7B\’:\’4j\’]=19;R k(B.5Q&&!B.7J&&!7E.7q)T.29=19;
………….
>

Nos queda algo como

var Class=function(properties){var klass=function(){if(this.initialize&&arguments[0]!=’noinit’)return this.initialize.apply(this,arguments);else return this};for(var property in this)klass[property]=this[property];klass.prototype=properties;return klass};Class.empty=function(){};Class.prototype={extend:function(properties){var pr0t0typ3=new this(‘noinit’);var parentize=function(previous,current){if(!previous.apply||!current.apply)return false;return function(){this.parent=previous;return current.apply(this,arguments)}};for(var property in properties){var previous=pr0t0typ3[property];var current=properties[property];if(previous&&previous!=current)current=parentize(previous,current)||current;pr0t0typ3[property]=current}return new Class(pr0t0typ3)},implement:function(properties){for(var property in properties)this.prototype[property]=properties[property]}};Object.extend=function(){var args=arguments;args=(args[1])?[args[0],args[1]]:[this,args[0]];for(var property in args[1])args[0][property]=args[1][property];return args[0]};Object.Native=function(){for(var i=0;i<arguments.length;i++)arguments[i].extend=Class.prototype.implement};new Object.Native(Function,Array,String,Number,Class);if(typeof HTMLElement==’undefined’){var HTMLElement=Class.empty;HTMLElement.prototype={}}else{HTMLElement.prototype.htmlElement=true}window.extend=document.extend=Object.extend;var Window=window;function $type(obj){if(obj===null||obj===undefined)return false;var type=typeof obj;if(type==’object’){if(obj.htmlElement)return’element’;if(obj.push)return’array’;if(obj.nodeName){switch(obj.nodeType){case 1:return’element’;case 3:return obj.nodeValue.test(/\S/)?’textnode’:’whitespace’}}}return type};function $chk(obj){return!!(obj||obj===0)};function $pick(obj,picked){return($type(obj))?obj:picked};
…………
>

Sin duda esta herramienta es de gran ayuda para que estudiemos como estan programadas las grandes librerias, y no solo eso si no ver como podemos implementarlas mejor y quizas hasta desarrollar algun tipo de plugin, en fin solo la imaginacion puede ser nuestro limite.

Un saludo especial a neustro amigo David, que sin sus dudas, este post no hubiera sido escrito, y te mando los scripts por mail, saludos.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *