Discuz教程网

Javascript代码压缩、加密算法的破解分析及工具实现

[复制链接]
authicon dly 发表于 2011-5-1 14:01:40 | 显示全部楼层 |阅读模式
现在网上很多Javascript都进行了压缩,同时代码变得不可直接阅读,也相当于一种简单的加密了,本文对其中一种典型的算法进行分析,介绍如何解密代码以及重新实现的压缩工具算法。
典型代码如下:
  1. eval(function(E,I,A,D,J,K,L,H){function C(A){return A<62?String.fromCharCode(A+=A<26?65:A<52?71:-4):A<63?'_':A<64?'$':C(A>>6)+C(A&63)}while(A>0)K[C(D--)]=I[--A];function N(A){return K[A]==L[A]?A:K[A]}if(''.replace(/^/,String)){var M=E.match(J),B=M[0],F=E.split(J),G=0;if(E.indexOf(F[0]))F=[''].concat(F);do{H[A++]=F[G++];H[A++]=N(B)}while(B=M[G]);H[A++]=F[G]||'';return H.join('')}return E.replace(J,N)}('Bl Bm=Bn;Bo(Bl Bp=Bq;Bp<Bn;Bp++){    Br.Bs(Bm+Bp+"<Bt>");}','var|index|100|for|a|0|document|write|br'.split('|'),9,109,/[\w\$]+/g, {}, {}, []))
复制代码

一、代码解密
对于这类压缩的代码,无非是把js程序采用某种算法进行压缩,然后自行用提供的函数还原,采用eval(SCRIPT)的方式执行来完成调用,那么还原的方法就很简单了,那前面的eval(和后面的)去掉,然后显示出来就完成了,例如下面的页面就可以实现代码的还原:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  2. <HTML>
  3. <HEAD>
  4.     <TITLE> 代码还原 </TITLE>
  5.     <META NAME="Generator" CONTENT="EditPlus">
  6.     <META NAME="Author" CONTENT="">
  7.     <META NAME="Keywords" CONTENT="">
  8.     <META NAME="Description" CONTENT="">
  9. </HEAD>

  10. <BODY>
  11. <TEXTAREA NAME="tx1" ROWS="10" COLS="100"></TEXTAREA>
  12. <SCRIPT LANGUAGE="JavaScript">
  13. document.all.tx1.value =function(E,I,A,D,J,K,L,H){function C(A){return A<62?String.fromCharCode(A+=A<26?65:A<52?71:-4):A<63?'_':A<64?'$':C(A>>6)+C(A&63)}while(A>0)K[C(D--)]=I[--A];function N(A){return K[A]==L[A]?A:K[A]}if(''.replace(/^/,String)){var M=E.match(J),B=M[0],F=E.split(J),G=0;if(E.indexOf(F[0]))F=[''].concat(F);do{H[A++]=F[G++];H[A++]=N(B)}while(B=M[G]);H[A++]=F[G]||'';return H.join('')}return E.replace(J,N)}('Bl Bm=Bn;Bo(Bl Bp=Bq;Bp<Bn;Bp++){    Br.Bs(Bm+Bp+"<Bt>");}','var|index|100|for|a|0|document|write|br'.split('|'),9,109,/[\w\$]+/g, {}, {}, [])
  14. </SCRIPT>
  15. </BODY>
  16. </HTML>
复制代码

通过上面方式运行,就可以在文本框中看到代码了,实际的代码是:
var index=100;for(var a=0;a<100;a++){ document.write(index+a+"<br>");}
很简单,不是吗
二、算法研究
由于代码全部在一行中,不便于阅读,可以通过格式化软件格式化,本文这里使用Intellij IDEA格式化,代码如下

  1. eval(function(E, I, A, D, J, K, L, H) {
  2.      function C(A) {
  3.          return A < 62 ? String.fromCharCode(A += A < 26 ? 65 : A < 52 ? 71 : -4) : A < 63 ? '_' : A < 64 ? '$' : C(A >> 6) + C(A & 63)
  4.     }
  5.      while (A > 0)K[C(D--)] = I[--A];
  6.      function N(A) {
  7.          return K[A] == L[A] ? A : K[A]
  8.      }
  9.      if (''.replace(/^/, String)) {
  10.         var M = E.match(J),B = M[0],F = E.split(J),G = 0;
  11.         if (E.indexOf(F[0]))F = [''].concat(F);
  12.         do{
  13.             H[A++] = F[G++];
  14.             H[A++] = N(B)
  15.         } while (B = M[G]);
  16.         H[A++] = F[G] || '';
  17.         return H.join('')
  18.     }
  19.     return E.replace(J, N)
  20. }('Bl Bm=Bn;Bo(Bl Bp=Bq;Bp<Bn;Bp++){    Br.Bs(Bm+Bp+"<Bt>");}','var|index|100|for|a|0|document|write|br'.split('|'), 9, 109, /[\w\$]+/g, {}, {}, []))
复制代码


Step 1:首先我们可以看出这是一个函数定义与调用合并在一起的,因此可以如下分解:(不再考虑eval)

  1. //E:加密压缩后的script信息
  2. //I:字符串数组,可以理解为解密需要字典
  3. //A:int 9
  4. //D:int 109
  5. //J:regexpr 正则表达式
  6. //K:object
  7. //L:object
  8. //H:array
  9. function decode(E, I, A, D, J, K, L, H) {
  10.     function C(A) {
  11.         return A < 62 ? String.fromCharCode(A += A < 26 ? 65 : A < 52 ? 71 : -4) : A < 63 ? '_' : A < 64 ? '$' : C(A >> 6) + C(A & 63)
  12.     }
  13.     while (A > 0)K[C(D--)] = I[--A];
  14.     function N(A) {
  15.         return K[A] == L[A] ? A : K[A]
  16.     }
  17.     if (''.replace(/^/, String)) {
  18.         var M = E.match(J),B = M[0],F = E.split(J),G = 0;
  19.         if (E.indexOf(F[0]))F = [''].concat(F);
  20.         do{
  21.             H[A++] = F[G++];
  22.             H[A++] = N(B)
  23.         } while (B = M[G]);
  24.         H[A++] = F[G] || '';
  25.         return H.join('')
  26.     }
  27.     return E.replace(J, N)
  28. }
  29. var decode_str=decode('Bl Bm=Bn;Bo(Bl Bp=Bq;Bp<Bn;Bp++){    Br.Bs(Bm+Bp+"<Bt>");}','var|index|100|for|a|0|document|write|br'.split('|'), 9, 109, /[\w\$]+/g, {}, {}, []));
复制代码


Step 2:其中对于函数function C(A)采用多重3元表达式处理的方式,可以用if/else如下分解

  1. function C(A){
  2.    var res;
  3.    if (A < 62) {
  4.         var r = null;
  5.         if (A < 26) r = 65; //'A'-'Z'
  6.        else {
  7.            if (A < 52) r = 71;  //'z'=122 控制以下
  8.             else r = -4;
  9.         }
  10.         res = String.fromCharCode(A + r);
  11.     }
  12.     else {
  13.        if (A < 63) res = '_'; //即A=62
  14.         else {
  15.             if (A < 64) res = '$';//即A=63
  16.             else res = C(A >> 6) + C(A & 63); //如果A>63,进行64进制的高低位分解为2部分
  17.         }
  18.     }
  19.    return res;
  20. }
复制代码

更加深刻的理解上面算法,就是一个仿base64编码变换的算法,可以参见文章:Base64相关
变换的码表是将0-63的数字变换为
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$
对应序列位置的字母。
Step 3:代码while (A > 0)K[C(D--)] = I[--A];的分析
实际上这里就是将字典内容与序号值进行对照,记录到Object对象中,运算顺序如下表:

  1. D=109,A=9,K["Bt"]=br
  2. D=108,A=8,K["Bs"]=write
  3. D=107,A=7,K["Br"]=document
  4. D=106,A=6,K["Bq"]=0
  5. D=105,A=5,K["Bp"]=a
  6. D=104,A=4,K["Bo"]=for
  7. D=103,A=3,K["Bn"]=100
  8. D=102,A=2,K["Bm"]=index
  9. D=101,A=1,K["Bl"]=var
复制代码


Step 4:代码if (''.replace(/^/, String)) 分析
看起来很高深的一个代码,你想空字符串无论怎么替换,还是空字符串,在javascript中,空字符串=false,非空字符串=true
所以这个if语句怎么都不会执行,这里是一个混淆视听的代码,呵呵,你如果想,也可以写上更多乱七八糟的代码来达到同样效果。
Step5:关键代码return E.replace(J, N),这里用到了函数N:

  1. function N(A) {
  2. return K[A] == L[A] ? A : K[A]
  3. }
复制代码

注意L对象从来没有赋值,所以L[A]返回的应该是undefined,所以可以翻译为

  1. function N(A) {
  2. return K[A] == undefined ? A : K[A]
  3. }
复制代码

这下看起来就很好理解,关键代码就下面这些
  1. function decode(E, I, A, D, J, K, L, H) {
  2. function C(A) {
  3. return A < 62 ? String.fromCharCode(A += A < 26 ? 65 : A < 52 ? 71 : -4) : A < 63 ? '_' : A < 64 ? '$' : C(A >> 6) + C(A & 63)
  4. }
  5. while (A > 0)K[C(D--)] = I[--A];
  6. function N(A) {
  7. return K[A] == undefined ? A : K[A]
  8. }
  9. return E.replace(J, N)
  10. }
复制代码

综上分析,该算法的原理就是从脚本文件中提取单词,存入字典表中,这里使用|分割的字符串,然后将单词对应的序号(仿base64编码值)写入原来代码的地方,
就构成了该算法的核心了,所以实现该压缩算法的代码也不难了





上一篇:PHP正则表达式基本函数 修饰符 元字符和需转义字符
下一篇:x1.5竞拍插件的問題
authicon shakesxia 发表于 2011-5-8 15:59:30 | 显示全部楼层
不错不错,我喜欢
authicon 21585151 发表于 2011-5-9 11:59:41 | 显示全部楼层
楼主威武
authicon Pianissimo 发表于 2011-5-11 03:59:39 | 显示全部楼层
这个不错呀
authicon 陶衣小可 发表于 2011-5-11 11:59:39 | 显示全部楼层
哈哈  收了你
authicon mjz 发表于 2011-5-12 16:59:53 | 显示全部楼层
不错不错,我喜欢
authicon 21585151 发表于 2011-5-13 08:59:44 | 显示全部楼层
哦哦,发财了啊,看到好东西啦
authicon 馥郁渊汀 发表于 2011-5-14 19:59:44 | 显示全部楼层
继续来索要
authicon 卡卡猫 发表于 2011-6-17 15:59:54 | 显示全部楼层
真的有意思!
authicon 蓝天blue 发表于 2011-6-18 08:59:53 | 显示全部楼层
有意思~顶顶 ,继续顶顶。继续顶哦
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-6-18 19:29

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表