cover

226流程与初始化分析

此文仅供学习交流,请勿用于非法用途。

整体流程

初始化

初始化由三部分组成: 

初次加载fireyejs时自执行i(49)(包括i(49)产生的异步线程)

awsc.js调用init函数

创建验证码dom时加载绑定事件

初始化后验证码加载完成,进入后续(检测事件/滑动/出值等)

检测事件

主要是鼠标点击、鼠标移动等事件

当鼠标在滑块位置按下时,会依次触发:fy.startRecord => MouseEvent.mousedown => FocusEvent.focus

出值

滑块到最右侧后,依次触发FyModule.getUidToken => FyModule.getFyToken

参数生成

i(49)

e = new we["Date"]();
Ro[4] = +Be;
Be = Ro[4];
Ie = void 0;
So = (ko = 0 | (So = (ye = Be) / (Be = 4294967296))) * Be;
Be = ye - So;
ye = void 0;
So = ko;
ko = [];
W = 255 & (ze = So >> 24);
V = 255 & (ze = So >> 16);
me = 255 & (ze = So >> 8);
ze = 255 & So;
ko.push(W, V, me, ze);
So = ye = ko;
ye = void 0;
ko = Be;
Be = [];
W = 255 & (ze = ko >> 24);
V = 255 & (ze = ko >> 16);
me = 255 & (ze = ko >> 8);
ze = 255 & ko;
Be.push(W, V, me, ze);
Be = ye = Be;
ye = So.concat(Be);
Ie = ye;
Ro[91] = Ie;
Makefile

始化时间戳,存放在a[4],后续会持续调用

同时对初始化时间戳进行各种计算,得到八位数组存放在a[91]中

e = Math["random"]
Be = Te();
Ie = Be["toString"](36);
Be = Ie["substring"](2);
Ie = Te();
Te = Ie["toString"](36);
Ie = Te["substring"](2);
Ro[64] = Be + Ie;
Makefile

两个随机字符串拼接,存在a[64]

a[8] a[11] a[19] a[27] a[30] a[35] a[45] a[50] a[51] a[71] a[79] a[90]的初始化为图中定值

selenium检测点,cdc_adoQpoasnfa76pfcZLmcfl_Symbol:

e = {};
V = Object;
$ = "cdc_adoQpoasnfa76pfcZLmcfl_Symbol";
me = "configurable";
ye["configurable"] = !1;
Pe = "enumerable";
ye["enumerable"] = !1;
me = ye;
V["defineProperty"](window, $, me);
Makefile

a[56]初始化为2

window.performance.getEntries判断,判断为True,进入一系列document操作后把100存入a[21]:

V = "c"调用i(9, "cn")

i的第一个参数为流程控制,后面的参数为相应流程用到的参数,i(9, "cn")操作主要分为两步:

第一步,初始化a[61]:

第二步:

e = "cn";
(io = [])[2] = ae;
io[0] = 1;
Le.push(io);
Je = void 0;
Qe = le;
mo = (po = re + ke) + (Qe = ae);
Qe = void 0;
po = mo;
mo = i(24, 2, po);
po = Qe = mo;
if (po) {
Qe = po.split(Ee);
mo = 2 != Qe.length;
if (mo) {
Je = void 0
} else {
Je = Qe
}
} else {
Je = void 0
}
Qe = Je;
Je = 0;
if (Qe) {
po = new le["Date"]();
mo = po["getTime"]();
po = (mo = 0 | (po = mo / 1e3)) - Qe[1];
mo = po <= (Co = 60 * (mo = 300));
if (mo) {
Je = 1e3 * (Co = 18e3 - po);
io[0] = 0;
io[1] = Qe[0];
(Co = ge[50])["cn"] = 1
}
}
Qe = i["bind"](0, 33, io);
if (Qe) {
setTimeout(Qe, Je)
}
}
Yo = U;
Si = 17952
} else {}
Makefile

其中:

i(24, 2, "lswucn")为从localStorage中取出lswucn的值

image-dzrw.png

a[50]原本为{},将"cn"键的值置为1

image-gcpt.png

过期后重设lswucn

注意a[61]也在此段初始化:

Le = a[61];
Le.push(io);
io[0] = 0;
io[1] = getLocalStorage("lswucn").split("@@")[0];
io[2] = "cn";
Lua

接着往下:

image-zahp.png

检测window.navigator.getBattery(获取用户电池设备信息),初始化a[9] = 2,getBattery是异步函数,结果回调如下:

image-lrfq.png

r为BatteryManager对象,level属性为电量(0为空,1为满),charging属性为是否充电(true/false)。初始化a[12] = 电量百分比,a[78] = 是否充电(是为1,否为0), a[9] = 1

继续走:

1image.png

初始化a[54] = 255

2image.png

判断平台是否arm

3image.png

初始化a[49] = -1,a[60] = -1

4image.png

检测navigator.storage.estimate(获取浏览器存储空间)

其中i(44, Be)为:

5image.png6image.png

usage为已用空间字节数,quota为可用空间总量,将a[49] a[60]对应初始化

继续主线程:

7image.png

a[57]初始化为空数组

8image.png

a[44]初始化为[2,2,2,2],a[2]初始化为-1,a[13] a[20] a[63] a[80] a[87] a[86] a[18] a[89] a[15] a[7]初始化为0

9image.png

a[53]初始化,一些环境检测后将结果各种计算

10image.png

a[5]初始化,检测"ontouchstart" in document,true为h5,false为pc web

11image.png

a[37]初始化,new RegExp("_n1t|_n1z")

12image.png

判断a[53]是否为1,如果为1则a[37] = new Date()

13image.png

a[36] a[94]都是new RegExp("_n1t|_n1z"),如果a[53] == 1,这两个都变为new Date()

14image.png

初始化a[13] = 255

B = !x[20];
if (B) {
    B = !x[5]
}
_ = B;
if (_) {
    _ = 1 === x[53]
}
Si = 15233;
B = _;
if (B) {
    B = me["origin"]
}
_ = B;
if (_) {
    _ = me["top"] == me
}
Si = 27522;
B = _;
if (B) {
    B = i["bind"]
}
_ = B;
Makefile

环境检测

15image.png

检测PointerEvent.getPredictedEvents方法,初始化a[13] = 254(TODO:不一定经过此分支,问题不大)

16image.png

i(1)为初始化

a[55] = (function anonymous() {var a=arguments;return this[a[1]]!==a[0]})
JavaScript

17image.png

接下来:

18image.png

检测performance.getEntriesByName方法,并取出document.currentScript.src(结果为js的地址:"https://g.alicdn.com/AWSC/fireyejs/1.226.0/fireyejs.js")

19image.png

获取performance.getEntriesByName()[0].decodedBodySize,如果其不等于0,则初始化a[40]为decodedBodySize ^ a[4](第一次加载时为0)

20image.png

初始化a[46] = 1

21image.png

环境检测

22image.png23image.png

初始化a[17] = document.createElement("canvas").getContext("webgl")

24image.png25image.png

V = document.createElement("canvas").getContext("webgl");
Bo = "WEBGL_debug_renderer_info";
me = V["getExtension"](Bo);
x = V["getParameter"](me["UNMASKED_VENDOR_WEBGL"]);
Ini

26image.png

获取webGL渲染器厂商(后面使用)

27image.png

初始化a[88] = []

28image.png

a[88][0] = 渲染器厂商

29image.png

a[24] = a[88].length - 1(添加Re前的长度),初始化时固定为0

V = document.createElement("canvas").getContext("webgl");
Bo = "WEBGL_debug_renderer_info";
me = V["getExtension"](Bo);
x = V["getParameter"](me["UNMASKED_RENDERER_WEBGL"]);
Ini

a[88]添加WebGL 渲染器的详细信息,a[67] = a[88].length - 1(添加Re前的长度),初始化时固定为1

a[28] a[3] a[81]初始化均为0

X = 38 === o;
we = "addEventListener";
Ro = "passive";
if (X) {
    Be = void 0;
    Te = void 0;
    Ie = g;
    ye = u;
    So = l;
    ko = r;
    ze = "attachEvent";
    if (ko[W = ze]) {
        ze = 0;
        V = So === Uo;
        if (V) {
            Pe = "onfocusin";
            ze = Pe
        } else {
            me = So === Po;
            if (me) {
                Pe = "onfocusout";
                ze = Pe
            } else {
                Pe = "on";
                ze = Pe + So
            }
        }
        ko["attachEvent"](ze, ye)
    } else {
        if (ko["addEventListener"]) {
            ze = !1;
            V = So === Lo;
            if (V) {
                me = "DeviceMotionEvent";
                if (ko["DeviceMotionEvent"]) {
                    ze = !0
                }
            } else {
                ze = !0
            }
            if (ze) {
                V = Ie;
                if (Te) {
                    me = "capture";
                    (V = {})[myHook("myHook2_22", me)] = Ie;
                    V[myHook("myHook_351", Ro)] = Be
                }
                ko["addEventListener"](So, ye, V)
            }
        }
    }
}
Makefile

window.attachEvent为ie兼容,可忽略上半部分代码

检测DeviceMotionEvent方法,并添加deviceorientation的事件监听

同样的,添加mousedown mouseup mousemove click keyup focus blur的事件监听方法

初始化me = [],检测图中各环境,将检测结果计算后放入me

判断是否是微信环境

me[1]的生成,判断是否阿里、qq浏览器

me[2] = 255 & a[0]

me[3] = 255 & a[42]

第一轮初始化都为0

me[4],非火狐浏览器固定为0(navigator.buildID,火狐专属)

me[5] me[6],meScriptEngineBuildVersion为ie专属,非ie则传两个0

me[7],同样ie专属

me[8] = 0

me[9] = 8

N值,一些环境检测

根据N值生成四位数组me[10] me[11] me[12] me[13]

一些环境检测

环境检测生成Ae

生成me[14] me[15] me[16] me[17]

初始化a[25] = me

注册方法到AWSC.js中,以供调用

globalOpt["loadTime"]为运行至此时间

此时,初始化的主线程i(49)结束,但初始化并未结束。后续是i(49)中产生的异步线程继续对a数组进行修改。

走了一边i(36)的异步线程:

将a[29]初始化为1

至此i(49)的初始化结束。

FyModule.init

登录页面(无感)

init由awsc.js传入参数,进入fireyejs的40 === o分支中

判断传入的map是否存在location和timeout字段,若不存在则默认设置为"cn"和2000

i(9, "cn")为判断a[61]最后一位是否为"cn",是的话不会过多处理a[61]

进入45 === o

判断当前时间与传入时间的时差是否在2000ms以内(正常一定在2000以内,单步调试会在2000以外,此时会报timeout错误),循环运行i(45, Ki, Zi, Ji)

商品页面(滑块)

初始化值e在nc.js中

与无感最大的不同的是init中少了个noProxy参数

在45 === o分支中会走到l(ge)部分后跳回awsc.js执行创建滑块dom等后续操作

DOM事件

createElement

14 === o分支,一系列dom操作后执行u(H),跳入13 === o分支(TODO: 偶尔跳至32分支)

createElement绑定13分支在此处

js内容固定为当前时间戳

13分支为修改a[21] = 2, a[72] = 1(32分支时a[21] = 104,a[72] = 1)

MouseEvent

下断点断鼠标事件

一些环境检测

if(a[88].indexOf(o["target"]["id"])!= -1){
    a[88].push(o["target"]["id"])
}
Less

a[88]添加mouveEvent.target.id

a[88]变化后,根据不同的mouse事件进入不同分支。

mousemove

isTrusted检测

a[31]等于mousemove的时间减a[4]

建一个新数组Xe,Xe[15] = 0,Xe[12] Xe[13]为a[91]与a[31]的各种计算,Xe[9] = mouseEvent.pageX

Xe[11]是mouseEvent.pageY,然后再把Xe[9]和Xe[11] ^= a[91][a[31]%7]

这部分后面会用到

Xe[8] Xe[14]的值,其中ve,he分别为document.body.scrollLeft,document.body.scrollTop,X为a[91][a[31]%7]

Xe[2] Xe[7] Xe[10]的值,其中ee,ne分别为document.body.clientLeft,document.body.clientTop,qe为a[4] + a[31]

一些环境检测,以及对js名称的检测

第一次鼠标事件时,初始化a[95] = []

a[95].push(Xe)

a[8] += 1

注意:

a[88].push(MouseEvent["target"]["id"])
CSS

其中id为bg-img(大图)、nc_1_n1z(滑块)等(具体见页面元素id)

mousedown

一些环境检测

a[97] = i(21),进入i(21)

可知a[97] = new window["AudioContext"]()

a[43] a[39]赋值

同样的isTrusted检测

a[28] += 1

MouseEvent.buttons(通常这个值为1,表示按的是鼠标左键)检测,若为0则a[41] += 1(a[41]初始为空而不是0)

如果MouseEvent.timeStamp>86400,则a[42] += 1(a[42]初始为空而不是0)

一些环境检测

其中:

Xe = MouseEvent["target"]["getBoundingClientRect"]()
ro = MouseEvent["pageX"]
$e = MouseEvent["pageY"]
Makefile

如果满足条件,则a[3] += 1(调试时均未跳到此处)

MouseEvent.which检测,并初始化数组ve = [0, 0, 1, 2]

Xe = [0, 0, 1, 2][MouseEvent.which]
Ini

ne = MouseEvent["target"]["nodeName"]["toUpperCase"]()
Ini

he = a[91][(new Date() - a[4]) % 7]
Ini

if (MouseEvent.type === "mouseup") {
    ee = 5
} else {
    ee = 3
}
Bash

初始化Ze = []

Ze[15] = ee

mousedown时固定Ze[15] = 4,a[59] = 0

Ze[12] Ze[9] Ze[11] Ze[1] Ze[13]的计算,其中:

lo = a[88].indexOf("nc_1_n1z")
ro = MouseEvent.pageX
$e = MouseEvent.pageY
Xe = [0, 0, 1, 2][MouseEvent.which]
X = new Date() - a[4]
he = a[91][X % 7]
Makefile

Ze[17] = he

a[95].push(Ze)

a[8] += 1

a[30].push(a[8] - 1)

mouseup(无感)

keyup(无感)

keydown(无感)

FocusEvent

对a的值无影响

PointerEvent

FyModule.startRecord

35 === o分支

a[59] = 1

a[45] = a[8] - 1

a[27]的变化如图

FyModule.getUidToken

划到最右端后,awsc.js执行fyObj.getUidToken(a),进入i(4, e):

i(24, 2, le)`为从localStorage中取出lswucn的值

然后进行:

return le.split("@@")[0]
Kotlin

即返回lswucn中@@之前的值

FyModule.getFyToken

太长,略

原创 226流程与初始化分析
226流程与初始化分析
本文是原创文章,采用 CC 4.0 协议,完整转载请注明来自 http://www.1997.pro/

评论
你无需删除空行,直接评论以获取最佳展示效果
你好啊!我是
yazong`s blog
引用到评论