反混淆后使用vscode打开,选择语言为javascript,这样就可以使用 IDE 的代码跳转功能(比如跳转到定义、跳转到引用)。
currentitems
首先搜索currentitems,能够找到let o = "https://api.weibotop.cn/currentitems"。
通过o,可以找到它的调用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
if (i != null) { e().get( o, { timeid: i, }, function (t) { let e = h(t); n(e); } ); } else { e().get(o, function (t) { let e = h(t); n(e); }); }
模块结构
先看一下函数e()是什么:
1 2
var t = i(755); var e = i.n(t);
再看一下函数i():
1 2 3 4 5 6 7 8 9 10 11 12
var e = {}; functioni(n) { var o = e[n]; if (o !== undefined) { return o.exports; } var r = (e[n] = { exports: {}, }); t[n].call(r.exports, r, r.exports, i); return r.exports; }
(() => { var t = { 734: function (t, e, i) { (function (t, e, i) { "use strict";
functionn(t) { if (t && typeof t == "object" && "default"in t) {
t[755]是这个函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
755: function (t, e) { var i; (function (e, i) { "use strict";
if (typeof t.exports == "object") { t.exports = e.document ? i(e, true) : function (t) { if (!t.document) { thrownewError("jQuery requires a window with a document"); } returni(t); }; } else { i(e); } })(typeofwindow != "undefined" ? window : this, function (n, o) {
到这已经很看出来,i(755)就是jQuery,上面的代码就变成了:
1 2 3 4
$.get("https://api.weibotop.cn/currentitems", function (t) { let e = h(t); n(e); });
解密
再找到函数h():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
functionh(t) { i = t = String(t); o = n.enc.Base64.parse(i); r = a; let e = n.AES.decrypt( { ciphertext: o, }, r, { mode: n.mode.ECB, padding: n.pad.Pkcs7, } ).toString(n.enc.Utf8); var i; var o; var r; returnJSON.parse(e); }
functiond(t, i = null) { functionn(e) { var i = { timeid: e[0], timestamp: e[1], }; t(i); } if ((i = l(i)) == null) { e().getJSON("https://api.weibotop.cn/getlatest", n); } else { e().getJSON( "https://api.weibotop.cn/getclosesttime", { timestamp: i, }, n ); } }
从这里可以看出,这两个 api 返回的是一个元组[timeid, timestamp]。比如["1151626","2024-05-08 16:32:03.0"]。
我们接着看函数l():
1 2 3 4 5 6 7 8 9 10 11 12
functionl(t) { if (t == null) { returnnull; } var e = t; var i = a; var o = n.AES.encrypt(e, i, { mode: n.mode.ECB, padding: n.pad.Pkcs7, }); return n.enc.Base64.stringify(o.ciphertext); }
var o = Crypto.AES.encrypt(plainText, a, { mode: Crypto.mode.ECB, padding: Crypto.pad.Pkcs7, }); const encryptedText = Crypto.enc.Base64.stringify(o.ciphertext);