banner
约 3,000 字
10 分钟

【JS逆向练习】抖音a_bogus-1.0.1.19-fix.01-jsvmp纯算还原分析2025-04-04

无标签

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!

算法流程分析#

1、请求参数+dhzx,标准sm3加密两次,生成32位数组
2、dhzx,标准sm3加密两次,生成32位数组
3、user-agent,魔改RC4加密,将RC4加密结果fromCharCode转字符串,再用魔改base64加密
4、根据浏览器属性,生成41位数组。
5、根据时间戳,生成4位数组。
6、通过随机数加一些操作,生成前4位数组。再通过随机数加一些操作,生成后4位数组。和前面的生成规则不一样
7、将第6步的两个数组concat成一个8位数组
8、将第7步的8位数组结合1、2、3、4、5步生成的数组,异或生成一个1位数的数组
9、将1、2、3、4、5步生成的数组,结合随机数时间戳等一些操作,生成一个50位数组。
10、通过随机数加一系列操作,生成4位数组,将数组formCharCode转字符串。
11、将第9步的50位数组+第4步的41位数组+第5步的4位数组+第8步的1位数组生成96位数组
12、上一步的96位数组,对3取余,每3个一组,用生成随机数开始,经过一些操作,生成4位数组。然后放到新数组里面,循环。也就是说96/3=32,96+32结果是128位的。如果数组长度%3有余数,比如是95位的,95%3=2,结果就是93+31+2=126位的。多出来的2位,不需要任何操作直接放到新数组里。
13、用第7步生成的8位数组concat上一步的128位数组,形成136位数组。
14、魔改rc4加密136位数组,将加密结果formCharCode转字符串。拼接第10步的4位数组转字符串。然后魔改base64加密字符串,最后得到ab参数。

总结:总体来说过程比较多,业余时间我是搞了很久才还原完。

二级评论接口验证展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

分析准备:#

  • 找到jsvmp加密入口

在这里插入图片描述
在这里插入图片描述

怎么找到入口不演示了,主要是d()原本这里是ifelse混淆了,非常不方便阅读。所以我这里ast还原了下。

在这里插入图片描述
在这里插入图片描述
blog image
blog image

刷新验证了下,还原的没啥问题,无报错, 断点 __ 也能正常执行。

  • ast还原后的d()函数完整代码

JavaScript
  function d() {
                    for (; ; ) {
                        var t = o[a++];
                        switch (t) {
                        case 0:
                            var r = o[a++];
                            p -= r;
                            var e = v.slice(p + 1, p + r + 1)
                              , n = v[p--]
                              , d = v[p--];
                            if ("function" != typeof n)
                                return f = 3,
                                void (l = new TypeError(typeof n + " is not a function"));
                            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);
                                v[++p] = m;
                            }
                            break;
                        case 1:
                            var w = v[p--];
                            v[p] = v[p] <= w;
                            break;
                        case 2:
                            w = v[p--],
                            v[p] = v[p] > w;
                            break;
                        case 3:
                            var x = o[a++]
                              , S = v[p--]
                              , P = [];
                            for (var j in S)
                                P.push(j);
                            s[x] = [P, S];
                            break;
                        case 4:
                            x = o[a++];
                            var O = v[p--]
                            R = v[p--];
                            P = s[x],
                            j = void 0;
                            do {
                                j = P[0].shift();
                            } while (j !== undefined && !(j in P[1]));
                            if (j !== undefined) {
                                R[O] = j;
                                v[++p] = true;
                            } else {
                                v[++p] = false;
                            }
                            break;
                        case 5:
                            x = o[a++];
                            var A = Z[x]
                              , E = b(A, i);
                            v[++p] = E,
                            v[++p] = A;
                            break;
                        case 6:
                            w = v[p--],
                            v[p] = v[p] !== w;
                            break;
                        case 7:
                            v[++p] = {};
                            break;
                        case 8:
                            var k = v[p--];
                            v[p] = v[p][k];
                            break;
                        case 9:
                            v[++p] = !0;
                            break;
                        case 10:
                            v[p] = void 0;
                            break;
                        case 11:
                            (E = v[p--],
                            v[p] %= E);
                            break;
                        case 12:
                            (w = v[p--],
                            v[p] = v[p] & w);
                            break;
                        case 13:
                            S = v[p--],
                            v[p] = v[p]instanceof S;
                            break;
                        case 14:
                            E = v[p--];
                            var T = v[p--];
                            (S = v[p--])[T] = E;
                            break;
                        case 15:
                            x = o[a++],
                            E = v[p--];
                            var C = Z[x];
                            if (i && !(C in globalThis))
                                return f = 3,
                            globalThis[C] = E;
                            break;
                        case 16:
                            var L = v[p--];
                            (S = v[p--])[L] = v[p];
                            break;
                        case 17:
                            var U = o[a++];
                            v[p] ? --p : a += U;
                            break;
                        case 18:
                            E = v[p],
                            v[++p] = E;
                            break;
                        case 19:
                            w = v[p--],
                            v[p] = v[p] >>> w;
                            break;
                        case 20:
                            x = o[a++],
                            E = v[p--],
                            (S = v[p--])[Z[x]] = E;
                            break;
                        case 21:
                            E = v[p--],
                            v[p] -= E;
                            break;
                        case 22:
                            if (0 !== f)
                                return;
                            break;
                        case 23:
                            U = o[a++],
                            E = v[p--],
                            v[p] === E && (--p,
                            a += U);
                            break;
                        case 24:
                            v[p] = typeof v[p];
                            break;
                        case 25:
                            var I = v[p--];
                            E = delete (S = v[p--])[I],
                            v[++p] = E;
                            break;
                        case 26:
                            --p;
                            break;
                        case 27:
                            v[++p] = !1;
                            break;
                        case 28:
                            v[++p] = NaN;
                            break;
                        case 29:
                            v[p] = !v[p];
                            break;
                        case 30:
                            x = o[a++];
                            v[p] = v[p][Z[x]];
                            break;
                        case 31:
                            U = o[a++];
                            if (v[p])
                                a += U;
                            else
                                --p;
                            break;
                        case 32:
                            w = v[p--];
                            v[p] = v[p] < w;
                            break;
                        case 33:
                            v[++p] = void 0;
                            break;
                        case 34:
                            v[++p] = c;
                            break;
                        case 35:
                            w = v[p--];
                            v[p] = v[p] >> w;
                            break;
                        case 36:
                            var temp = v[p];
                            v[p] = +v[p];
                            break;
                        case 37:
                            v[p] = ~v[p];
                            break;
                        case 38:
                            v[++p] = o[a++];
                            break;
                        case 39:
                            var F = o[a++];
                            v[p = p - F + 1] = v.slice(p, p + F);
                            break;
                        case 40:
                            var M = v[p--];
                            E = ++(S = v[p--])[M],
                            v[++p] = E;
                            break;
                        case 41:
                            U = o[a++],
                            v[p--] || (a += U);
                            break;
                        case 42:
                            (E = v[p--],
                            v[p] /= E)
                            break;
                        case 43:
                            v[p] = -v[p];
                            break;
                        case 44:
                            var B = v[p--];
                            E = --(S = v[p--])[B],
                            v[++p] = E;
                            break;
                        case 45:
                            (E = v[p--],
                            v[p] *= E);
                            break;
                        case 46:
                            (x = o[a++],
                            v[++p] = +Z[x]);
                            break;
                        case 47:
                            x = o[a++];
                            var Q = v[p--];
                            Object.defineProperty(v[p], Z[x], {
                                get: Q,
                                enumerable: !0,
                                configurable: !0
                            });
                            break;
                        case 48:
                            x = o[a++];
                            var H = v[p--];
                            Object.defineProperty(v[p], Z[x], {
                                set: H,
                                enumerable: !0,
                                configurable: !0
                            });
                            break;
                        case 49:
                            return f = 3,
                            void (l = v[p--]);
                            break;
                        case 50:
                            var q = v[p--];
                            E = (S = v[p--])[q]++,
                            v[++p] = E;
                            break;
                        case 51:
                            w = v[p--],
                            v[p] = v[p] | w;
                            break;
                        case 52:
                            return U = o[a++],
                            f = 1,
                            void (l = a + U);
                            break;
                        case 53:
                            U = o[a++],
                            a += U;
                            break;
                        case 54:
                            var N = o[a++];
                            for (x = o[a++],
                            U = s; N > 0; )
                                U = U[0],
                                --N;
                            U[x] = v[p--];
                            break;
                        case 55:
                            (S = v[p--],
                            v[p] = v[p]in S)
                            break;
                        case 56:
                            (w = v[p--],
                            v[p] = v[p] << w);
                            break;
                        case 57:
                            (w = v[p--],
                            v[p] = v[p] === w)
                            break;
                        case 58:
                            (w = v[p--],
                            v[p] = v[p] == w);
                            break;
                        case 59:
                            r = o[a++];
                            for (var G = [void 0]; r > 0; )
                                G[r--] = v[p--];
                            var z = v[p--];
                            m = new (Function.bind.apply(z, G))(),
                            v[++p] = m;
                            break;
                        case 60:
                            x = o[a++];
                            var Y = Z[x];
                            if (!(Y in globalThis))
                                return f = 3,
                                void (l = new ReferenceError(Y + " is not defined"));
                            E = globalThis[Y],
                            v[++p] = E;
                            break;
                        case 61:
                            for (N = o[a++],
                            x = o[a++],
                            U = s; N > 0; )
                                U = U[0],
                                --N;
                            v[++p] = U,
                            v[++p] = x;
                            break;
                        case 62:
                            w = v[p--],
                            v[p] = v[p] != w;
                            break;
                        case 63:
                            E = D(o[a++], s),
                            v[++p] = E;
                            break;
                        case 64:
                            w = v[p--],
                            v[p] = v[p] >= w;
                            break;
                        case 65:
                            v[++p] = 1 / 0;
                            break;
                        case 66:
                            var J = v[p--];
                            E = (S = v[p--])[J]--,
                            v[++p] = E;
                            break;
                        case 67:
                            x = o[a++],
                            E = v[p--],
                            Object.defineProperty(v[p], Z[x], {
                                value: E,
                                writable: !0,
                                configurable: !0,
                                enumerable: !0
                            })
                            break;
                        case 68:
                            E = v[p--],
                            v[p] += E;
                            break;
                        case 69:
                            x = o[a++];
                            var X = Z[x];
                            E = typeof globalThis[X],
                            v[++p] = E;
                            break;
                        case 70:
                            w = v[p--],
                            v[p] = v[p] ^ w;
                            break;
                        case 71:
                            U = o[a++],
                            v[p--] && (a += U);
                            break;
                        case 72:
                            x = o[a++];
                            var W = Z[x];
                            W in globalThis || (globalThis[W] = void 0);
                            break;
                        case 73:
                            x = o[a++],
                            v[++p] = Z[x];
                            break;
                        case 74:
                            for (N = o[a++],x = o[a++], U = s; N > 0; )
                                U = U[0],--N;
                            E = U[x],
                            v[++p] = E;
                            break;
                        case 75:
                            v[++p] = null;
                            break;
                        default:
                            return f = 2,
                            void (l = v[p--]);
                        }
                    }
                }
  • 插桩

插桩也不演示了,我是用的插桩框架。只推荐一些插桩位置吧,指令0、5、8、11、12、14、15、19、20、21、26、30、35、36、37、39、42、45、51、54、56、57、58、60、64、68、71、73、74 关键指令,0:函数调用,74:从作用域取值。其它的都是压栈、出栈、全局变量加载还有+=/*^等操作符指令,自行分析吧。

日志分析#

整个过程就是按照开头的分析过程,由上至下的。

  • 1、请求参数标准SM3加密2次,dhzx标准SM3加密2次

在这里插入图片描述
在这里插入图片描述
  • 2、ua获取并trim去掉空格,放到作用域U里

在这里插入图片描述
在这里插入图片描述

[0.00390625,1,12]是RC4加密的key,不同环境不一样,我试过[0.00390625,1,8],[0.00390625,1,0]都有。根据自己来的。

在这里插入图片描述
在这里插入图片描述

rc4加密完,就开始base64加密

在这里插入图片描述
在这里插入图片描述

base64加密完,开始sm3加密。

  • 3、浏览器属性获取,生成41位数组

在这里插入图片描述
在这里插入图片描述

开始生成

在这里插入图片描述
在这里插入图片描述

生成结束

在这里插入图片描述
在这里插入图片描述
  • 4、时间戳生成4位数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • 5、8位数组生成,前4位数组生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 6、8位数组生成,后4位数组生成

在这里插入图片描述
在这里插入图片描述
  • 7、拼接成8位数组,开始生成1位数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • 8、50位数组生成

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • 9、拼接成96位数组

在这里插入图片描述
在这里插入图片描述

可以到首先是[1,12]开头的50位数组 concat[49,55开头的根据浏览器属性生成的41位数组 concat4位的 时间戳 __ 数组 concat最后的1位数组。 刚好50+41+4+1=96长度

  • 10、生成4位数组

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
  • 11、96位数组生成128位数组

在这里插入图片描述
在这里插入图片描述

每3个数一组进行操作,生成4位后push新数组

在这里插入图片描述
在这里插入图片描述
  • 12、8位数组拼接128位数组,得到136位数组

在这里插入图片描述
在这里插入图片描述
  • 13、开始对136位数组rc4加密的准备

首先转成 字符串

在这里插入图片描述
在这里插入图片描述

然后初始化256位的数组

在这里插入图片描述
在这里插入图片描述

rc4结果拼接4位的数组生成前缀,然后开始base64

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

base64加密完成,最终输出内容就是ab参数了。

END