由于最近做的东西都是纯Javascript脚本的到网上下一些现成产品的代码,发现都有加密或混淆,因为很多加密其实是用Packer2的压缩实现的,就先讨论一下压缩吧,毕竟压缩后的代码至少可以让下载的速度快些吧。
目前JavaScript压缩的基本方法如下:
1、最常用的方法,将所有的注释去掉,然后将所有的回车去掉,最后把多余的空格也去掉。
2、高级点的方法,除了方法1的几个去除步骤外,加上了一个重命名变量的功能,把所有的变量名和方法名都变成由两三个字符组合的,达到进一步减肥的目的。
3、最后,用一些简单的压缩算法。
这里就不讨论方法1和方法2了。方法1过于简单;至于方法2,现在不少JavaScript代码保护软件的混淆就是这么做的,所以下次再探讨。
用与JavaScript的压缩算法和普通的压缩不同,不能使用太复杂的方法,毕竟解压的代码也是明码写在文件里的嘛。目前比较流行的是Packer2还有一个压缩效果很好的MemTronic's HTML JavaScript Cruncher-Compressor。个人认为Packer2的实现更好些,因为MemTronic's HTML JavaScript Cruncher-Compressor使用了ASCII码127之后的不可见字符,保存文件时弄错了编码,就前功尽弃。所以我们重点来讨论Packer2。
MemTronic's HTML JavaScript Cruncher-Compressor的实现我没有认真分析(代码好长,不是很想看),不过效果确实挺好的(不过你要是叫作者换成可见的字符,他就不一定有这个效果了),可惜保存到文件时比较麻烦,我复制到Microsoft Script Editor 7保存,有些字符就丢失了。用Unicode或者UTF8之类的编码保存,文件又会增大不少。
看到用不可见字符做分隔的方法,我之前也考虑用127之后的不可见字符来做个**进制,当初设想是当字典的索引成百上千后能省那么一点点,最后也是因为不可见字符的原因,放弃之。
Paker2的方法是首先用正则表达式将所有字符串取出,作为一个字典。然后将源代码中的字符串用字典中的索引来替换。最后在替换好的代码外加入一个Eval(……)的外壳,web页面在客户端运行时就能动态解压了。下面拿个具体的代码来看一下:
我自己简化后的解压部分代码如下:
{
e = e.replace( new RegExp( ' \\b\\w+\\b ' , ' g ' ), function ($ 0 )
{
return d[$ 0 ];
});
return e;
}( ' 0(\ ' 1 \ ' ); ' , ' alert|xxx ' .split( ' | ' ))));
晕倒,居然忘了说压缩,还是如同上面的那个方法,在正则表达式替换的时候来个回调,先判断取得的字符串是否存在字典表里,如果不存在就增加,否则就取已存在的字符串的位置索引,然后把位置索引return回去让正则表达式自己做替换,重复n次,再然后,就OK啦。
放眼望去,现在不少东西是用Packer2的方法来做“加密”,连MapBar的最新版本的核心代码都是用Parcker2来压缩的,不过MapBar比较狠,还用JSOB之类的东西混淆了一回。挺流行的JQuery也是使用这种方法来做压缩的。
作者: 陈鹏(偶是坏人)