还原混淆的javascript代码

今天在浏览逍遥网(www.xoyo.com)的时候,在页面底部发现了网站的用户行为采集代码

<script src=”http://counter.kds.xoyo.com/kds2_record.js” type=”text/javascript” charset=”utf-8″></script>

打开“http://counter.kds.xoyo.com/kds2_record.js”后,发现下面这段代码:

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)]=k1||e(c)}k=[function(e){return d[e]}];e=function(){return’\\w+’};c=1};while(c–){if(k1){p=p.replace(new RegExp(‘\\b’+e(c)+’\\b’,'g’),k1)}}return p}(’3 1r=d C();3 y=d C;3 o=\’\';a Q(X){m 15.1s(15.1q()*X)+1}a 1i(){3 f=”-1″,n=l;6(n.A&&n.A.8){G(3 7=0;7<n.A.8;7++){6(n.A[7].1p.19(\’1e 1d\’)!=-1){f=n.A[7].1m.B(\’1e 1d \’)[1];1c}}}D 6(S.17){G(3 7=10;7>=2;7–){1n{3 1g=1o(“d 17(\’1b.1b.”+7+”\’);”);6(1g){f=7+\’.0\’;1c}}1t(e){}}}6(f==”-1″)m f;D m f.w(0,f.19(“.”)+2)}a 16(){3 F=”";3E=l.M.B(“;”);6(E.8<4)m”";G(3 i=4;i<E.8;i++){F+=E[i]+”,”}m F.w(0,F.8-2)}3 j=l.1u()?1:-1;3 5=d 1z();5[0]=l.1l;6(5[0]==”1A”)
{3 9=l.M;5[1]=9.w(9.P(” “)+1,9.8);5[0]=5[1].w(0,5[1].P(“/”));5[1]=9.w(9.P(“/”)+1,9.8)}D 6(5[0]==”1y 1x 1v”){5[1]=l.M.B(“;”)[1]}6(!J(\’I\’)){o=y.1w()+\’\'+Q(Z);H=1;z(\’I\’,o);z(\’O\’,H)}D{o=J(\’I\’);H=1B(J(\’O\’))+1;z(\’I\’,o);z(\’O\’,H)}a z(q,L)
{3 1h=d C();1h=d C(y.1k(),y.1j(),y.1E()+1);3 18=d C(1X,12,14);k.U=q+”=”+11(L)+”; Y=”+18.20()+”;”}a J(q){3 R=k.U.B(“; “);G(3 i=0;i<R.8;i++){3 T=R[i].B(“=”);6(q==T[0])m 1C(T[1])}}a 1T(q){k.U=q+”=”+11(L)+”; Y=1S, 14 1W 21 23:W:W 1Z;”}a 13(1f)
{3 N=”1Y://N.22.1U.1Q/1H.1I”;k.1G(“<1F 1D=\\”"+N+”?h=”+g(1R.1J.1K)+”&r=”+g(S.k.1P)+”&t=”+g(S.k.1O)+”&s=”+K.1a+”x”+K.V+”&c=”+K.1N+”&j=”+j+”&f=”+1i()+”&1L=”+g(16())
+”&p=”+1f+”&b=”+g(5[0])+”&v=”+g(5[1])+”&1M”+Q(Z)+”&u=”+o+”\\” 1a=\\”0\\” V=\\”0\\”>”)}13(1V)’,62,128,’|||var||brower|if|ii|length|browerInfo|function|||new|||encodeURIComponent||||
document|navigator|return||_kds2_u||sName||||||substring||_kds2_nt|SetCookie|plugins|split|Date|else|ua|plugin|
for|_kds2_v|_kds2_uName|GetCookie|screen|sValue|userAgent|counter|_kds2_times|lastIndexOf|rand|aCookie|window|
aCrumb|cookie|height|59|num|expires|999999999||escape||sendColection|31|Math|getPlugin|ActiveXObject|expiration|
indexOf|width|ShockwaveFlash|break|Flash|Shockwave|pid|fl|_kds2_tt|getFlash|getMonth|getFullYear|appName|description|
try|eval|name|random|pageOpen|floor|catch|javaEnabled|Explorer|getTime|Internet|Microsoft|Array|Netscape|
parseInt|unescape|src|getDate|img|write|ds2rd|php|location|href|pl|rd|colorDepth|title|referrer|com|top|Fri|
DelCookie|xoyo|_kds2_p|Dec|9999|http|GMT|toGMTString|1999|kds|’.split(‘|’),0,{}))

明显代码被混淆了,但是从最后那些规律的变量名来看,我们完全可以将其还原为原来的样子。这种加密只是看起来很乱,实际上还原的过程可能会简单的超乎你的想象。

我们发现最外面有一层eval(),eval函数接受一个字符串参数,并将字符串作为代码执行。那我们就新建一个HTML文件,将其中的eval替换成alert。因为eval括号里的那一串不管多么复杂,最终都要返回一个字符串,而这个字符串正是我们需要的。

新建一个文本文件,输入以下内容(方便起见,省略了HTML部分的基本结构,但是这段代码在实际执行中不会出现任何问题):

<script>
 alert(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||e(c)}k=[function(e){return d

[e]}];e=function(){return’\\w+’};c=1};while(c–){if(k){p=p.replace(new RegExp(‘\\b’+e(c)+’\\b’,'g’),k)}}return

p}(’3 1r=d C();3 y=d C;3 o=\’\';a Q(X){m 15.1s(15.1q()*X)+1}a 1i(){3 f=”-1″,n=l;6(n.A&&n.A.8){G(3 7=0;7<n.A.8;7++)

{6(n.A[7].1p.19(\’1e 1d\’)!=-1){f=n.A[7].1m.B(\’1e 1d \’)[1];1c}}}D 6(S.17){G(3 7=10;7>=2;7–){1n{3 1g=1o(“d 17

(\’1b.1b.”+7+”\’);”);6(1g){f=7+\’.0\’;1c}}1t(e){}}}6(f==”-1″)m f;D m f.w(0,f.19(“.”)+2)}a 16(){3 F=”";3 E=l.M.B

(“;”);6(E.8<4)m”";G(3 i=4;i<E.8;i++){F+=E[i]+”,”}m F.w(0,F.8-2)}3 j=l.1u()?1:-1;3 5=d 1z();5[0]=l.1l;6(5[0]==”1A”){3

9=l.M;5[1]=9.w(9.P(” “)+1,9.8);5[0]=5[1].w(0,5[1].P(“/”));5[1]=9.w(9.P(“/”)+1,9.8)}D 6(5[0]==”1y 1x 1v”){5[1]=l.M.B

(“;”)[1]}6(!J(\’I\’)){o=y.1w()+\’\'+Q(Z);H=1;z(\’I\’,o);z(\’O\’,H)}D{o=J(\’I\’);H=1B(J(\’O\’))+1;z(\’I\’,o);z(\’O

\’,H)}a z(q,L){3 1h=d C();1h=d C(y.1k(),y.1j(),y.1E()+1);3 18=d C(1X,12,14);k.U=q+”=”+11(L)+”; Y=”+18.20()+”;”}a J

(q){3 R=k.U.B(“; “);G(3 i=0;i<R.8;i++){3 T=R[i].B(“=”);6(q==T[0])m 1C(T[1])}}a 1T(q){k.U=q+”=”+11(L)+”; Y=1S, 14 1W

21 23:W:W 1Z;”}a 13(1f){3 N=”1Y://N.22.1U.1Q/1H.1I”;k.1G(“<1F 1D=\\”"+N+”?h=”+g(1R.1J.1K)+”&r=”+g(S.k.1P)+”&t=”+g

(S.k.1O)+”&s=”+K.1a+”x”+K.V+”&c=”+K.1N+”&j=”+j+”&f=”+1i()+”&1L=”+g(16())+”&p=”+1f+”&b=”+g(5[0])+”&v=”+g(5

[1])+”&1M”+Q(Z)+”&u=”+o+”\\” 1a=\\”0\\” V=\\”0\\”>”)}13(1V)’,62,128,’|||var||brower|if|ii|length|browerInfo|

function|||new|||encodeURIComponent||||document|navigator|return||_kds2_u||sName||||||substring||_kds2_nt|

SetCookie|plugins|split|Date|else|ua|plugin|for|_kds2_v|_kds2_uName|GetCookie|screen|sValue|userAgent|counter|

_kds2_times|lastIndexOf|rand|aCookie|window|aCrumb|cookie|height|59|num|expires|999999999||escape||sendColection|

31|Math|getPlugin|ActiveXObject|expiration|indexOf|width|ShockwaveFlash|break|Flash|Shockwave|pid|fl|_kds2_tt|

getFlash|getMonth|getFullYear|appName|description|try|eval|name|random|pageOpen|floor|catch|javaEnabled|Explorer|

getTime|Internet|Microsoft|Array|Netscape|parseInt|unescape|src|getDate|img|write|ds2rd|php|location|href|pl|rd|

colorDepth|title|referrer|com|top|Fri|DelCookie|xoyo|_kds2_p|Dec|9999|http|GMT|toGMTString|1999|kds|’.split(‘|’),0,

{}))
 </script>

在浏览器中打开,我们看到一个警告框,框内有以下内容:

var pageOpen=new Date();var _kds2_nt=new Date;var _kds2_u=”;function rand(num){return Math.floor(Math.random()*num)+1}function getFlash(){var f=”-1″,n=navigator;if(n.plugins&&n.plugins.length){for(var ii=0;ii<n.plugins.length;ii++){if(n.plugins[ii].name.indexOf(‘Shockwave Flash’)!=-1){f=n.plugins[ii].description.split(‘Shockwave Flash ‘)[1];break}}}else if(window.ActiveXObject){for(var ii=10;ii>=2;ii–){try{var fl=eval(“new ActiveXObject(‘ShockwaveFlash.ShockwaveFlash.”+ii+”‘);”);if(fl){f=ii+’.0′;break}}catch(e){}}}if(f==”-1″)return f;else return f.substring(0,f.indexOf(“.”)+2)}function getPlugin(){var plugin=”";var ua=navigator.userAgent.split(“;”);if(ua.length<4)return”";for(var i=4;i<ua.length;i++){plugin+=ua[i]+”,”}return plugin.substring(0,plugin.length-2)}var j=navigator.javaEnabled()?1:-1;var brower=new Array();brower[0]=navigator.appName;if(brower[0]==”Netscape”){var browerInfo=navigator.userAgent;brower[1]=browerInfo.substring(browerInfo.lastIndexOf(” “)+1,browerInfo.length);brower[0]=brower[1].substring(0,brower[1].lastIndexOf(“/”));brower[1]=browerInfo.
substring(browerInfo.lastIndexOf(“/”)+1,browerInfo.length)}else if(brower[0]==”Microsoft Internet Explorer”){brower[1]=navigator.userAgent.split(“;”)[1]}if(!GetCookie(‘_kds2_uName’)){_kds2_u=_kds2_nt.getTime()+”+rand(999999999);_kds2_v=1;SetCookie(‘_kds2_uName’,_kds2_u);SetCookie(‘_kds2_times’,_kds2_v)}
else{_kds2_u=GetCookie(‘_kds2_uName’);_kds2_v=parseInt(GetCookie(‘_kds2_times’))+1;SetCookie(‘_kds2_uName’,_kds2_u);
SetCookie(‘_kds2_times’,_kds2_v)}function SetCookie(sName,sValue){var _kds2_tt=new Date();_kds2_tt=new Date(_kds2_nt.getFullYear(),_kds2_nt.getMonth(),_kds2_nt.getDate()+1);var expiration=new Date(9999,12,31);document.cookie=sName+”=”+escape(sValue)+”; expires=”+expiration.toGMTString()+”;”}function GetCookie(sName)
{var aCookie=document.cookie.split(“; “);for(var i=0;i<aCookie.length;i++){var aCrumb=aCookie[i].split(“=”);if(sName==aCrumb[0])return unescape(aCrumb[1])}}function DelCookie(sName){document.cookie=sName+”=”+escape(sValue)+”; expires=Fri, 31 Dec 1999 23:59:59 GMT;”}function sendColection(pid){var counter=”http://counter.kds.xoyo.com/ds2rd.php”;document.write(“<img src=\”"+counter+”?h=”+encodeURIComponent(top.location.href)+”&r=”+encodeURIComponent(window.document.referrer)+”&t=”+encodeURIComponent
(window.document.title)+”&s=”+screen.width+”x”+screen.height+”&c=”+screen.colorDepth+”&j=”+j+”&f=”+getFlash()+”&pl=”
+encodeURIComponent(getPlugin())+”&p=”+pid+”&b=”+encodeURIComponent(brower[0])+”&v=”+encodeURIComponent(brower[1])+”&rd”
+rand(999999999)+”&u=”+_kds2_u+”\” width=\”0\” height=\”0\”>”)}sendColection(_kds2_p)

我们看到代码已经被还原,变量名等都是正确的,但是由于没有合理的缩进,阅读起来十分困难,这个问题我们使用Einar Lielmanis的“Online javascript beautifier”来解决。将上面还原后的代码粘贴到文本框中,单击“Beautify javascript”,我们得到了以下的结果:

var pageOpen = new Date();
var _kds2_nt = new Date;
var _kds2_u = '';
function rand(num) {
    return Math.floor(Math.random() * num) + 1
}
function getFlash() {
    var f = "-1",
        n = navigator;
    if (n.plugins && n.plugins.length) {
        for (var ii = 0; ii < n.plugins.length; ii++) {
            if (n.plugins[ii].name.indexOf('Shockwave Flash') != -1) {
                f = n.plugins[ii].description.split('Shockwave Flash ')[1];
                break
            }
        }
    } else if (window.ActiveXObject) {
        for (var ii = 10; ii >= 2; ii--) {
            try {
                var fl = eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash." + ii + "');");
                if (fl) {
                    f = ii + '.0';
                    break
                }
            } catch (e) {}
        }
    }
    if (f == "-1") return f;
    else return f.substring(0, f.indexOf(".") + 2)
}
function getPlugin() {
    var plugin = "";
    var ua = navigator.userAgent.split(";");
    if (ua.length < 4) return "";
    for (var i = 4; i < ua.length; i++) {
        plugin += ua[i] + ","
    }
    return plugin.substring(0, plugin.length - 2)
}
var j = navigator.javaEnabled() ? 1 : -1;
var brower = new Array();
brower[0] = navigator.appName;
if (brower[0] == "Netscape") {
    var browerInfo = navigator.userAgent;
    brower[1] = browerInfo.substring(browerInfo.lastIndexOf(" ") + 1, browerInfo.length);
    brower[0] = brower[1].substring(0, brower[1].lastIndexOf("/"));
    brower[1] = browerInfo.substring(browerInfo.lastIndexOf("/") + 1, browerInfo.length)
} else if (brower[0] == "Microsoft Internet Explorer") {
    brower[1] = navigator.userAgent.split(";")[1]
}
if (!GetCookie('_kds2_uName')) {
    _kds2_u = _kds2_nt.getTime() + '' + rand(999999999);
    _kds2_v = 1;
    SetCookie('_kds2_uName', _kds2_u);
    SetCookie('_kds2_times', _kds2_v)
} else {
    _kds2_u = GetCookie('_kds2_uName');
    _kds2_v = parseInt(GetCookie('_kds2_times')) + 1;
    SetCookie('_kds2_uName', _kds2_u);
    SetCookie('_kds2_times', _kds2_v)
}
function SetCookie(sName, sValue) {
    var _kds2_tt = new Date();
    _kds2_tt = new Date(_kds2_nt.getFullYear(), _kds2_nt.getMonth(), _kds2_nt.getDate() + 1);
    var expiration = new Date(9999, 12, 31);
    document.cookie = sName + "=" + escape(sValue) + "; expires=" + expiration.toGMTString() + ";"
}
function GetCookie(sName) {
    var aCookie = document.cookie.split("; ");
    for (var i = 0; i < aCookie.length; i++) {
        var aCrumb = aCookie[i].split("=");
        if (sName == aCrumb[0]) return unescape(aCrumb[1])
    }
}
function DelCookie(sName) {
    document.cookie = sName + "=" + escape(sValue) + "; expires=Fri, 31 Dec 1999 23:59:59 GMT;"
}
function sendColection(pid) {
    var counter = "http://counter.kds.xoyo.com/ds2rd.php";
    document.write("")
}
sendColection(_kds2_p)

至此,代码内容一目了然,代码混淆成功还原!

Original resource:Click here

8 thoughts on “还原混淆的javascript代码”

  1. 博主,使用chrome16显示错误,代码显示全跑到边框外面去了,赶紧修复下吧。。。

    [回复]

    普若木特 回复:

    @风再起时, 你是用啥显示代码的啊 ➡

    [回复]

    风再起时 回复:

    @sp, SyntaxHighlighter Evolved
    http://wordpress.org/extend/plugins/syntaxhighlighter/

    [回复]

    普若木特 回复:

    我也用的是这个啊,有的代码还是不行

    [回复]

    风再起时 回复:

    @sp, 规范后的代码正常,前面的全部显示出格了,FF3.6也是,可能是因为前面的代码本来就是迷乱的。

    [回复]

    风再起时 回复:

    @sp, 你再仔细看看,我觉得你用的插件和我给的连接里面的不一样,很类似,你现在用这个我以前用过。不一样的~~ :!!!:

    [回复]

发表评论

电子邮件地址不会被公开。 必填项已用*标注