actionlog_js_ua.js混淆编程形式与执行主流程
actionlog_js_ua.js混淆编程形式与执行主流程
ua.js中mousedown和mousemove事件自定义函数功能解析
ua.js中JSocket.getlso和JSocket.setlso代码分析
ua.js中arguments.callee.caller的应用
淘宝的ua.js文件对于我而言一直是神一般的存在,近期心存敬畏的学习了这个文件。从本文开始,我将记录一系列在学习过程中的粗识浅见,本文记录ua.js混淆编程的形式和执行主流程,欢迎围观。可惜在淘宝最新版本中登录时已经找不到这个文件了,但是UA还在,类似的功能应该也还在。
ua文件的第一道障碍就是各种混淆编程,我学习的actionlog_js_ua.js文件是2015.10.30抓取的文件,感兴趣的同学可以到这里下载。我曾经在乌云上看到某位高手说可以用正则来将该混淆文件清晰化。这着实让我崇拜不已,可是作为菜鸟,我都是纯手工操作,程序看到哪里,就反混淆到哪里。方法也是极其低端,新建一个html文件,让其执行混淆的js代码并将结果输出。
切入正题,下面让我们来初步见识一下ua.js文件的混淆编程的类型,再来看看actionlog_js_ua.js中主动执行的函数,我习惯称之为该文件的主流程。
1.ua.js混淆编程类型
1.1 常数写成复杂计算式
以ua.js中函数l5为例,用计算式(0x3fe
* 0466 & 79) + 6来替代10,用(0x7
* 015 + 8) + ((0x3fe | 0475) % 73)替代100。纵观文件的全局,存在大量类似的处理。
1 2 3 4 5 6 7 8 9 10 11 12 |
l5 = function (xy) { if (xy < (0x3fe * 0466 & 79) + 6) {//if(xy < 10) xy = n5n + py + xy; } else if (xy < (0x7 * 015 + 8) + ((0x3fe | 0475) % 73)) {//(xy < 100) xy = n5n + xy; } return xy; }; |
1.2 多个变量来表示同一个对象或函数
在ua.js文件中,upc/ere/or/w/vx等等变量均等表示window对象;jj/eb/k1/m2等等变量均指向同一个函数eb,eb函数形式如下,该函数也将大量的常数写成计算式。该函数可以根据传入的参数将混乱的字符串还原为我们能看懂的函数名,该函数的调用在ua.js文件中处处可见,承担着大量的混淆代码的任务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
eb = function (vr, fv, dy) { var u = fv + dy; var x0 = ""; var p = ""; vr = vr.substr((0x3f3 * 0621 & 85), vr.length - (0x3e8 % 0637 & 87)); var ze = vr.length; for (var dl = (0x3e8 % 0324 & 71); dl < ze; ++dl) { if (dl % u == u - (0x3f3 * 0673 & 61)) { x0 = vr.substr(ze - dl - (0x3e8 % 0513 & 89), u); x0 = x0.split("").reverse().join(""); x0 = x0.substr(((0x3f3 | 01134) % 93), fv); p = p + x0; } } var fo = ze % u; if (fo != (0x3e8 % 0315 & 65)) { x0 = vr.substr((0x3e8 * 0225 & 55), fo); x0 = x0.split("").reverse().join(""); x0 = x0.substr(((0x3e8 | 0727) % 93), fv); p = p + x0; } return p; }; |
1.3 混乱常用函数名
1 |
l6 = navigator[eb('umrioftSalpl', 3, 1)] || navigator[jj('UFtneogArResuI', 3, 1)]; <span style="font-size:7.5pt;font-family:""><span style="font-size:14px;font-family:Microsoft YaHei;"><span style="font-size:14px;font-family:Microsoft YaHei;">//</span></span></span> |
在以上代码中,看到第一行,我无论如何也想不到它等同于l6 = navigator[“userAgent”] || navigator[“platform”]; 好奇的同学可以验证一下。这就是上面提到的eb函数混淆的效果,在ua.s文件中,有80%以上的函数名均由该函数来混淆。
除了上述三点外,ua.js文件中还有各种各样的混淆视听的方式,例如所有的函数名都是没有实际意义的,例如设置一些永远都不会执行的代码,该文件中updateUA代码是不会执行的。
2. actionlog_js_ua.js执行主流程
在ua.js文件中,会主动执行的代码除了定义各类变量之外,还有函数jwhs和hp6。
jwhs函数旨在实现不依赖jquery,在DOM加载完成后执行指定函数,反混淆后其代码如下:
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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
jwhs = (function () { var qo84 = [], y2w0 = false, yb = null, a3d = function (fn, args) { try { fn["apply"](this, args || []); } catch (err) { if (yb) { yb["call"](this,err); } } }, ready = function () { y2w0 = true; qo84 = []; }; //错误处理函数 this["setOnError"] = function(fn) { yb = fn; return this; }; //添加DOM加载完成后需要执行的代码或函数 this["add"] = function (fn, args) { if (y2w0) {//dom加载完成, ready()执行完成后,此函数会执行 a3d(fn, args); } else { //将待执行的函数加入到qo84中 qo84[qo84["length"]] = {fn : fn, args : args}; } return this; }; // For all browsers except IE if(window["addEventListener"]) { //当DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。 window["document"]["addEventListener"]('DOMContentLoaded', function () { ready(); }, false); } else { (function () { //check IE's proprietary DOM members ////window.document.uniqueID,每一次调用都会返回一个新的uniqueID,IE only //window.document.uniqueID && window.document.expando //expando: 用于设置或获取表明是否可对象内创建任意变量的值 //uniqueID:属性获取服务器控件的唯一的、以分层形式限定的标识符 if(!window["document"]["uniqueID"] && window["document"]["expando"]) { return; } //window.document.createElement('document:ready'); var wki = window["document"]["createElement"]('document:ready'); try { //doScroll()来判断DOM树是否完成,原理是IE下只有当DOM树构建完成后才能doScroll //see if it throws errors until after ondocumentready wki["doScroll"].("left"); ready(); } catch (err) { setTimeout(arguments["callee"]); } })(); } return this; })(); |
hp6在文件最后被调用,其调用部分代码如下:
1 2 3 4 5 6 7 8 9 10 |
var vf = ((0x3e8 | 01503) % 59);//0 while (!vf) { if (vf + (0x3f3 * 0673 & 91)) { hp6(); vf = vf + ((0x3f3 | 01717) % 73); continue; } this.UAOpt = rt; } |
作为ua.js文件的主动执行函数,hp6函数肩负重担,负责实现如下功能:从当前网页中获取信息,为mousedown, keydown, mousemove, blur, focus, load, beforeunload, unload,reload事件分配自定义的处理函数,将load处理函数添加到jwhs中作为DOM加载完成后执行的函数等等功能。其反混淆后的代码如下,其中配有部分注释。
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 |
hp6 = function () { window["acjs"] = 1; //wo()函数:将UA_Opt的各变量值分别赋值给tty的相应变量 //若变量UA_Opt未定义,或者UA_Opt[Flag]值不为数值则返回1 //可以正常赋值完成时返回0 if (0 != wo()) { return; }; //////为键盘事件,鼠标事件,load,unload等等事件分配处理函数,与prjn类似 t6k(ere); UA_Opt["attachEvents"] = t6k; //pgn 将UA_Opt的各变量值分别赋值给tty的相应变量 ivsz = tty; // load事件的处理函数 UA_Opt["reload"] = pgn; if(UA_Opt["UMID"]){ UA_Opt["setUM"] = ey03; //在window.document.getElementsByTagName("HEAD")[item](0)中添加script元素 //添加内容的src为:mbd.src = "//" + ivsz[ResHost]+ "/um.js"; m7(); } }; |
淘宝有些地方还用的这个ua.js,反正烂七八糟的,恩。。。。(⊙v⊙)嗯感谢楼主的分享
这个actionjs的项目开始两年就是我写的(包括js混淆、加密算法、服务端),不过我现在已经出来创业了https://hekr.me,我看你的网站里有写到图片研究的文章,想跟你聊聊,我的微信 ahong2002xd