某音a_bogus纯算法192位研究分析
纯算法思路
一句话讲清全流程:
根据url参数,多次SM3加密得到初始数组,将其中某些元素添加至后续的环境信息数组中,此环境数组包括对ua的RC4加密随后再次SM3加密得到的数组中的元素,之后拿着此数组再根据随机数做另一次转换运算,得到一百四十位左右的新数组,再之后拿着这个新数组转成明文后,再次运算得到个新明文字符串,最后根据这个字符串经魔改base64编码后得到最终a_bogus
区别于补环境的方式,如果要想将a_bogus本地纯算法实现,大量调试、叉桩日志分析是少不了的
而要想好好调试,最好把流程能简化的简化,混淆能解的解掉,不然鼠标或键盘按那么多次,最终就走了数千乃至数万个流程中的其中一步,那真是…
看看解混淆前的
一堆if 和 三元
要想进到某单个流程,鼠标得点多少次,而且还有多重嵌套三元这种…可读性很低的存在,
还有就是那个自增和自减,有试过,浏览器调试时,一不小心给它自增了,后面的走向大概率会偏离主轨道
索性…
解混淆
三元 转 if ,if 转switch,自增自减操作转换,++p的改为 p+=1,p; p++的改为p,p+= 1;
转换后的代码:
function d() {for (; ; ) {var t = o[a];a += 1;switch (t) {case 0:var r = o[a];a += 1;p -= r;var e = v.slice(p + 1, p + r + 1);var n = v[p];p -= 1;var d = v[p];p -= 1;if ("function" != typeof n) {f = 3;l = new TypeError(typeof n + " is not a function");return;}var y = V.get(n);if (y) {h.push([o, i, u, s, c, a, f, l]);g(y[0], d, e, y[1]);} else {var m = n.apply(d, e);p += 1;v[p] = m;}break;case 1:var w = v[p];p -= 1;v[p] = v[p] <= w;break;case 2:w = v[p];p -= 1;v[p] = v[p] > w;break;case 3:var x = o[a];a += 1;var S = v[p];p -= 1;var P = [];for (var j in S) {P.push(j);}s[x] = [P, S];break;case 4:x = o[a];a += 1;var O = v[p];p -= 1;var R = v[p];p -= 1;P = s[x];j = void 0;do {j = P[0].shift();} while (void 0 !== j && !(j in P[1]));if (void 0 !== j) {R[O] = j;p += 1;v[p] = !0;} else {p += 1;v[p] = !1;}break;case 5:x = o[a];a += 1;var A = Z[x];var E = b(A, i);p += 1;v[p] = E;p += 1;v[p] = A;break;case 6:w = v[p];p -= 1;v[p] = v[p] !== w;break;case 7:p += 1;v[p] = {};break;case 8:var k = v[p];p -= 1;v[p] = v[p][k];break;case 9:p += 1;v[p] = !0;break;case 10:v[p] = void 0;break;case 11:E = v[p];p -= 1;v[p] %= E;break;case 12:w = v[p];p -= 1;v[p] = v[p] & w;break;case 13:S = v[p];p -= 1;v[p] = v[p]instanceof S;break;case 14:E = v[p];p -= 1;var T = v[p];p -= 1;S = v[p];p -= 1;S[T] = E;break;case 15:x = o[a];a += 1;E = v[p];p -= 1;var C = Z[x];if (i && !(C in globalThis)) {f = 3;l = new ReferenceError(C + " is not defined");return;}globalThis[C] = E;break;case 16:var L = v[p];p -= 1;S = v[p];p -= 1;S[L] = v[p];break;case 17:var U = o[a];a += 1;if (v[p]) {p -= 1;} else {a += U;}break;case 18:E = v[p];p += 1;v[p] = E;break;case 19:w = v[p];p -= 1;v[p] = v[p] >>> w;break;case 20:x = o[a];a += 1;E = v[p];p -= 1;S = v[p];p -= 1;S[Z[x]] = E;break;case 21:E = v[p];p -= 1;v[p] -= E;break;case 22:if (0 !== f) {return;}break;case 23:U = o[a];a += 1;E = v[p];p -= 1;if (v[p] === E) {p -= 1;a += U;}break;case 24:v[p] = typeof v[p];break;case 25:var I = v[p];p -= 1;S = v[p];p -= 1;E = delete S[I];p += 1;v[p] = E;break;case 26:p -= 1;break;case 27:p += 1;v[p] = !1;break;case 28:p += 1;v[p] = NaN;break;case 29:v[p] = !v[p];break;case 30:x = o[a];a += 1;v[p] = v[p][Z[x]];break;case 31:U = o[a];a += 1;if (v[p]) {a += U;} else {p -= 1;}break;case 32:w = v[p];p -= 1;v[p] = v[p] < w;break;case 33:p += 1;v[p] = void 0;break;case 34:p += 1;v[p] = c;break;case 35:w = v[p];p -= 1;v[p] = v[p] >> w;break;case 36:v[p] = +v[p];break;case 37:v[p] = ~v[p];break;case 38:p += 1;v[p] = o[a];a += 1;break;case 39:var F = o[a];a += 1;p = p - F + 1;v[p] = v.slice(p, p + F);break;case 40:var M = v[p];p -= 1;S = v[p];p -= 1;S[M] += 1;E = S[M];p += 1;v[p] = E;break;case 41:U = o[a];a += 1;var tempVal = v[p];p -= 1;if (!tempVal) {a += U;}break;case 42:E = v[p];p -= 1;v[p] /= E;break;case 43:v[p] = -v[p];break;case 44:var B = v[p];p -= 1;S = v[p];p -= 1;S[B] -= 1;E = S[B];p += 1;v[p] = E;break;case 45:E = v[p];p -= 1;v[p] *= E;break;case 46:x = o[a];a += 1;p += 1;v[p] = +Z[x];break;case 47:x = o[a];a += 1;var Q = v[p];p -= 1;Object.defineProperty(v[p], Z[x], {get: Q,enumerable: !0,configurable: !0});break;case 48:x = o[a];a += 1;var H = v[p];p -= 1;Object.defineProperty(v[p], Z[x], {set: H,enumerable: !0,configurable: !0});break;case 49:f = 3;l = v[p];p -= 1;return;case 50:var q = v[p];p -= 1;S = v[p];p -= 1;E = S[q];S[q] += 1;p += 1;v[p] = E;break;case 51:w = v[p];p -= 1;v[p] = v[p] | w;break;case 52:U = o[a];a += 1;f = 1;l = a + U;return;case 53:U = o[a];a += 1;a += U;break;case 54:var N = o[a];a += 1;x = o[a];a += 1;U = s;for (; N > 0; ) {U = U[0];N -= 1;}U[x] = v[p];p -= 1;break;case 55:S = v[p];p -= 1;v[p] = v[p]in S;break;case 56:w = v[p];p -= 1;v[p] = v[p] << w;break;case 57:w = v[p];p -= 1;v[p] = v[p] === w;break;case 58:w = v[p];p -= 1;v[p] = v[p] == w;break;case 59:r = o[a];a += 1;var G = [void 0];for (; r > 0; ) {G[r] = v[p];p -= 1;r -= 1;}var z = v[p];p -= 1;m = new (Function.bind.apply(z, G))();p += 1;v[p] = m;break;case 60:x = o[a];a += 1;var Y = Z[x];if (!(Y in globalThis)) {f = 3;l = new ReferenceError(Y + " is not defined");return;}E = globalThis[Y];p += 1;v[p] = E;break;case 61:N = o[a];a += 1;x = o[a];a += 1;U = s;for (; N > 0; ) {U = U[0];N -= 1;}p += 1;v[p] = U;p += 1;v[p] = x;break;case 62:w = v[p];p -= 1;v[p] = v[p] != w;break;case 63:E = D(o[a], s);a += 1;p += 1;v[p] = E;break;case 64:w = v[p];p -= 1;v[p] = v[p] >= w;break;case 65:p += 1;v[p] = 1 / 0;break;case 66:var J = v[p];p -= 1;S = v[p];p -= 1;E = S[J];S[J] -= 1;p += 1;v[p] = E;break;case 67:x = o[a];a += 1;E = v[p];p -= 1;Object.defineProperty(v[p], Z[x], {value: E,writable: !0,configurable: !0,enumerable: !0});break;case 68:E = v[p];p -= 1;v[p] += E;break;case 69:x = o[a];a += 1;var X = Z[x];E = typeof globalThis[X];p += 1;v[p] = E;break;case 70:w = v[p];p -= 1;v[p] = v[p] ^ w;break;case 71:U = o[a];a += 1;var tempBool = v[p];p -= 1;if (tempBool) {a += U;}break;case 72:x = o[a];a += 1;var W = Z[x];if (!(W in globalThis)) {globalThis[W] = void 0;}break;case 73:x = o[a];a += 1;p += 1;v[p] = Z[x];break;case 74:N = o[a];a += 1;x = o[a];a += 1;U = s;for (; N > 0; ) {U = U[0];N -= 1;}E = U[x];p += 1;v[p] = E;break;case 75:p += 1;v[p] = null;break;default:f = 2;l = v[p];p -= 1;return;}}
}
之后调试起来就很方便了,详细分析日志和纯算法会在星球(https://t.zsxq.com/GEIze)里分享,仅供学习参考。