ua.js中网络超时检测函数 wql 功能分析
actionlog_js_ua.js混淆编程形式与执行主流程
ua.js中mousedown和mousemove事件自定义函数功能解析
ua.js中JSocket.getlso和JSocket.setlso代码分析
ua.js中arguments.callee.caller的应用
wql是ua.js中网络超时检测函数。在load事件自定义处理函数中获取各种固定信息生成UA时,每一次调用vq4,随即都会调用wql,wql的唯一参数与vq4的第一个参数相同,今天我们来分析该网络超时检测函数wql实现的原理。
我大致总结了ua.js文件中调用vq4与wql时相对应的内容,这里我将wql函数的唯一参数称为信息特征值,该特征值从1~20(14~16,18除外)均对应一条生成UA或与服务器交互的信息。其中wql(“19”)对于我而言是一个谜,该函数调用vq4时的其他参数是四个随机数,这些随机数与给UA_opt[“LogVal”]赋值的函数xy,mousemove处理函数qe,keydown处理函数u4,以及与ua.js调用时间相关的函数tpy有关,但具体的关系我还没有看懂。
wql函数代码解析
我们先来看wql函数反混淆且简化之后的代码,由代码来推测其在UA生成过程中扮演的角色。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
wql = function (tw) { var dqto = new or["Date"]()["getTime"](); z7u["push"](aytz(dqto)); if (z7u["length"] > 1) { var jw9 = dqto - tno(z7u[z7u["length"] - 2]); if(jw9 > 5000){ f(["to", [jw9, dqto, tw]]); gby(); } } return true; }; f = function (d) { su(wjt(ovh("" + arguments["callee"]), "" + arguments["callee"])); var rz6i = 20; vq4([20,d]); }; |
函数wql的执行逻辑如下:
1. 获取函数调用时刻(精确到ms),存入变量临时dqto,dqto存入数组z7u。在整个ua.js文件中,数组z7u仅在此处赋值,仅在load事件处理函数中被赋初值(空)。
2. 判断z7u中元素的个数,若个数大于1,则进入第3步,否则函数结束。
3. 在函数wql中,涉及到两个函数aytz和tnz,这两个函数互为反函数,也就是说dqto=tno(aytz(dqto))。知道这一点后,我们就能理解语句函数wql中变量jw9的意义:本次调用wql与上一次调用wql之间的时间间隔。若最近两次调用wql之间的时间间隔大于5s,则进入第4步,否则函数结束。
4.调用函数f和gby。函数f中会以特征值20来调用vq4,关于函数vq4的说明请参考上一篇文章。那么函数wql中调用的gby的作用是什么呢?
网络超时处理函数gby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
gby = function () { if (owg) { prjn(upc); if (typeof UA_Opt == 'object') { UA_Opt["reload"] = function () {}; } throw "Q_Q"; } }; prjn = function (b0z) { var zp6 = new or["Object"]; zp6["mousedown"] = bc; zp6["keydown"] = u4; zp6["mousemove"] = qe; zp6["focus"] = yl; zp6["blur"] = yl; zp6["load"] = n8x; zp6["beforeunload"] = cr64; zp6["unload"] = cr64; var vo = b0z["document"]; var s6xc = function (e, bgo) { if (e == 'focus') { if (bgo["detachEvent"]) { bgo["detachEvent"]("onfocusin", zp6[e], false); } else if (bgo["removeEventListener"]) { bgo["removeEventListener"](e, zp6[e], true); } } else if (e == 'blur') { if (bgo["detachEvent"]) { bgo["detachEvent"]("onfocusout", zp6[e], false); } else if (bgo["removeEventListener"]) { bgo["removeEventListener"](e, zp6[e], true); } } else { if (bgo["detachEvent"]) { bgo["detachEvent"]("on" + e, zp6[e], false); } else if (bgo["removeEventListener"]) { bgo["removeEventListener"](e, zp6[e], false); } } }; var gpm = function (e) { s6xc(e, vo); }; var ga01 = function (e) { s6xc(e, b0z); }; if (ivsz["EnableMCLog"]) { gpm("mousedown"); } if (ivsz["EnableKSLog"]) { gpm("keydown"); } if (ivsz["EnableMPLog"]) { gpm("mousemove"); } if (ivsz["FocusInfo"]) { gpm("focus"); } if ((ivsz["SendMethod"] & 2) > 0) { if (typeof b0z["onbeforeunload"] != 'undefined') { ga01("beforeunload"); } if (typeof b0z["onunload"] != 'undefined') { ga01("unload"); } } };//prjn |
结合上述代码,很容易发现函数gby是用来解除绑定各种事件与其自定义处理函数的。另外gby函数中还有一句代码if (typeof UA_Opt == ‘object’) {UA_Opt[“reload”] = function () {};},这一句代码用于解除reload事件与原处理函数的绑定,最后会抛出异常。
综上分析,个人认为函数wql的作用是:检测两次wql调用之间的时间间隔,若该时间大于5s时,那么ua.js将认为函数执行出错,会触发reload事件,所有的变量均会被清空并重新赋值。所以wql其实相当于是一个网络超时检测函数,而gby则是故障处理函数(包含网络超时):解除各事件与自定义函数的绑定,然后抛出异常。