现在的位置: 首页 > 综合 > 正文

这段代码在干什么?

2012年06月16日 ⁄ 综合 ⁄ 共 1984字 ⁄ 字号 评论关闭
分析别人的东西时,看到一段JS中的代码引起我的兴趣,代码如下:
eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||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}('1.3.0=1.2.0;',4,4,'Validator|THREECCRM|commonform|util'.split('|'),0,{}))

我正在分析的系统中有许多类似的代码,这是最短的一段。这段代码是在干什么?

把以上代码分解如下:

eval
(
 
function(p, a, c, k, e, d)
 
{
  e
=function(c)
    
{return c};
  
if(!''.replace(/^/, String))
  
{
   
while(c--)
    d[c]
=k[c]||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
 }

 (
'1.3.0=1.2.0;'44'Validator|THREECCRM|commonform|util'.split('|'), 0{})
)

整段代码是在构建一个JavaScript语句,最后让eval运行。构建语句所用的方法是用一个函数,该函数比较特别,是使用“立即定义、马上使用”的方式。
function (参数)
{
 函数体
}
(实际参数)
后面的代码很多情况下我都一直以为是多此一举,如:定义函数e直接返回参数c;判断空字符替换空字符后是否为空字符;把数组k赋给数组d;把e定义为常量'\w+',然后只在一个地方使用;把c设为1,然后进行一次循环;未使用的形参a,e,d。
总之我把代码可以省略到如下,得出的结果是一致的:

eval
(
 
function(p,k)
 
{
  d
=[function(c)
     
{return k[c]}];
  p
=p.replace(new RegExp('\\b\\w+\\b','g'), d[0]);
  
return p}

 (
'1.3.0=1.2.0;''Validator|THREECCRM|commonform|util'.split('|'))
)

现在大约可以理解,这段代码是把'1.3.0=1.2.0'用数组k[]替代,形成一个语句:
THREECCRM.util.Validator=THREECCRM.commonform.Validator;
然后执行。
d=[function(c){return k[c]}];这段代码我感觉像是返回k数组的指针。我试着用其它方式去取代这段代码,但都没成功。

取代1:
p=p.replace(new RegExp('\\b\\w+\\b','g'),k);
结果:
"Validator,THREECCRM,commonform,util.Validator,THREECCRM,commonform,util.Validator,THREECCRM,commonform,util=Validator,THREECCRM,commonform,util.Validator,THREECCRM,commonform,util.Validator,THREECCRM,commonform,util;"

取代2:
p=p.replace(new RegExp('\\b\\w+\\b','g'),'Validator|THREECCRM|commonform|util'.split('|'));
结果:
同上

取代3:
p=p.replace(new RegExp('\\b\\w+\\b','g'),k[0]);
结果:
"Validator.Validator.Validator=Validator.Validator.Validator;"

取代4:
p=p.replace(new RegExp('\\b\\w+\\b','g'),(k[0],k[1],k[2],k[3]));
结果:
"util.util.util=util.util.util;"

以后有时候再分析那些“多余”的代码究竟在什么时候产生作用的。

抱歉!评论已关闭.