> 文档中心 > C#WinForm实现雷速网站比赛MQTT逆向采集

C#WinForm实现雷速网站比赛MQTT逆向采集

目录

前言

一、寻找数据

二、C#WinForm程序编写MQTT客户端

总结


前言

提示: 本文仅用于学习分享,禁止用于任何违法行为,如有侵权,请联系删除。 

目标网址:足球比分_足球即时比分_足球比分直播-雷速体育

 列表中某一场进行中的比赛

 我们点开某一场,直接F12打开开发者面板

 刷新页面选中ws消息,链接上附带的是这场比赛的ID,可以看到网站的即时数据通过 MQTT 进行传输的,我们点开某一条消息,发现消息只是部分关键数据进行了加密,如下:

本篇文章主要内容就是解密加密的数据,使用C#WinForm程序进行获取数据 !


一、寻找数据

我们打开调用mqtt调用的代码进行观察:

 从上图中,观察到一个类似initConnect的方法,从意思上分析认为是初始化连接,当然不知道看的同学可以通过分析链接地址一步一步去找,最终都能找到这个方法!

我们直接单击进入方法中,下断点,再次刷新页面:

 我们可以看到,这个实际上做了一个 MQTT 连接的操作,至此我们拿到了MQTT地址以及需要的参数,参数一共有3个,clientId,username,password

关于clientid,我们下入断点,控制台输出相关数据:

 可以清楚看到这个clientid生成过程就是固定字符串(Leisu_P_0_)+24位随机数,经过后期软件的测试,这个值可以不填!

关于usernamepassword,我们在这这里下入断点,username单步调试进入,password控制台输出:

我们可以看到 ,这里密码是空字符串,用户名是通过执行了一个方法返回的,我们单步一部一部跟进:

跟到最后你会发现,这里的username就是一个固定字符串,由返回的js产生,经过后期软件的测试,这个值我们可以填这里的固定值!

了解MQTT的同学会知道,MQTT是基于发布订阅这样的一个模式,不知道的去百度了解一下,我们继续往下调试:

 上图中,我们可以看到在连接发生后,主动去订阅了四个主题:

live/football/detail/3657453/top_v2、live/football/detail/3657453/data_v2、live/football/detail/3657453/bet365、chatroom_v2/R1_3657453

那么订阅了就要有接收处理,这个初始化的方法还没有结束,下面代码中有json序列化的,猜测是接受处理数据的方法,控制台打印输出:

 果不其然,这里就是数据接受处理的地方,我们在下面这个方法中下入断点:

 最后我们得看到了输出的数据,这里把字节转换成了字符串,但是我们看到在输出的数据中,有一部分数据不是明文的,我们继续往下调试,找到解密的调用点:

在我们调试到这个地方的时候,可以看到明文数据已经解析出来了:

这里调用了一个方法 $.rot ,而方法需要两个参数,第一个是返回的加密的base64数据,第二个是一个整数,这个整数为接受到数据的数组第二项,即 i[2] ,看过我上一篇文章【C#实现雷速网站逆向】非常熟悉,这里调用的方法跟之前分析出来的解密方法一致,这篇文章就不多做阐述。那现在我们就拿到了链接,参数,数据解密方法,我们直接用C#WinForm程序进行编写。

二、C#WinForm程序编写MQTT客户端

我们先看最后的软件效果:

首先新建一个WinForm程序,nuget安装CefSharp(用于执行js加密),MQTTnet(用于mqtt客户端):

1.初始化CefSharp

     var setting = new CefSettings();     // 设置语言     setting.Locale = "zh-CN";     //初始化配置     CefSharp.Cef.Initialize(setting, true);     //实例化浏览器对象     chromeBrowser = new ChromiumWebBrowser();     //浏览器添加到页面上     this.panel1.Controls.Add(chromeBrowser);     //平铺     chromeBrowser.Dock = DockStyle.Fill;     //打开空白页     chromeBrowser.LoadUrl("about:blank");

2.初始化MQTT

  //实例化mqtt工厂      var factory = new MqttFactory();      //创建mqtt实例      var mqttClient = factory.CreateMqttClient();      //初始化mqtt客户端配置      var options = new MqttClientOptionsBuilder().WithWebSocketServer("wss://ws-gateway.leisu.com:443/mqtt").WithCredentials("leisu_user_rJD5hF8jJ3vW", "").Build();      //绑定连接成功委托方法      mqttClient.ConnectedHandler = new MqttClientConnectedHandlerDelegate(OnSubscriberConnected);      //绑定断开连接委托方法      mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(OnSubscriberDisconnected);      //绑定接受消息委托方法      mqttClient.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnSubscriberMessageReceived);      //连接      await mqttClient.ConnectAsync(options, CancellationToken.None); // Since 3.0.5 with//订阅-聊天      await mqttClient.SubscribeAsync($"chatroom_v2/R1_{matchId}");      //订阅-比赛趋势      await mqttClient.SubscribeAsync($"live/football/detail/{matchId}/data_v2");      订阅-bet365指数      await mqttClient.SubscribeAsync($"live/football/detail/{matchId}/bet365");      订阅-比赛数据      await mqttClient.SubscribeAsync($"live/football/detail/{matchId}/top_v2");

3.处理订阅委托方法

  private async Task OnSubscriberMessageReceived(MqttApplicationMessageReceivedEventArgs obj) {     try     {  //接收到的Topic的消息  var topic = obj.ApplicationMessage.Topic;  //二进制转字符串  var str = Encoding.UTF8.GetString(obj.ApplicationMessage.Payload);  var json = Newtonsoft.Json.JsonConvert.DeserializeObject(str);  var num = json[2].ToString();  //拼接调用函数  var main = $"main('{json[1].ToString()}',{num})";  //调用js拼接  var js = jsStr.Replace("#Code#", "return " + main);  //执行js返回结果  var rel = await chromeBrowser.GetBrowser().MainFrame.EvaluateScriptAsync(js, null);  var msg = "";  #region 处理结果  if (rel.Success)  {      msg = Newtonsoft.Json.JsonConvert.SerializeObject(rel.Result);  }  else  {      msg = rel.Message;  }  #endregion  AppendText(topic + "【" + msg + "】");     }     catch (Exception ex)     {  AppendText(ex.ToString());  Console.WriteLine(ex.ToString());     } } private Task OnSubscriberDisconnected(MqttClientDisconnectedEventArgs obj) {     AppendText("连接断开");     return Task.FromResult(true); } private Task OnSubscriberConnected(MqttClientConnectedEventArgs obj) {     AppendText("连接成功");     return Task.FromResult(true); }

 4.最后附上调用js代码

(function () {    /*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */    !function (e, t) { "object" == typeof exports && "undefined" != typeof module ? t(exports) : "function" == typeof define && define.amd ? define(["exports"], t) : t((e = "undefined" != typeof globalThis ? globalThis : e || self).pako = {}) }(this, (function (e) { "use strict"; var t = (e, t, i, n) => { let a = 65535 & e | 0, r = e >>> 16 & 65535 | 0, o = 0; for (; 0 !== i;) { o = i > 2e3 ? 2e3 : i, i -= o; do { a = a + t[n++] | 0, r = r + a | 0 } while (--o); a %= 65521, r %= 65521 } return a | r < { let e, t = []; for (var i = 0; i < 256; i++) { e = i; for (var n = 0; n >> 1 : e >>> 1; t[i] = e } return t })()); var n = (e, t, n, a) => { const r = i, o = a + n; e ^= -1; for (let i = a; i >> 8 ^ r[255 & (e ^ t[i])]; return -1 ^ e }; var a = function (e, t) { let i, n, a, r, o, s, l, d, f, c, h, u, w, b, k, m, _, g, p, v, x, y, E, R; const A = e.state; i = e.next_in, E = e.input, n = i + (e.avail_in - 5), a = e.next_out, R = e.output, r = a - (t - e.avail_out), o = a + (e.avail_out - 257), s = A.dmax, l = A.wsize, d = A.whave, f = A.wnext, c = A.window, h = A.hold, u = A.bits, w = A.lencode, b = A.distcode, k = (1 << A.lenbits) - 1, m = (1 << A.distbits) - 1; e: do { u < 15 && (h += E[i++] << u, u += 8, h += E[i++] <>> 24, h >>>= g, u -= g, g = _ >>> 16 & 255, 0 === g) R[a++] = 65535 & _; else { if (!(16 & g)) { if (0 == (64 & g)) { _ = w[(65535 & _) + (h & (1 << g) - 1)]; continue t } if (32 & g) { A.mode = 12; break e } e.msg = "invalid literal/length code", A.mode = 30; break e } p = 65535 & _, g &= 15, g && (u < g && (h += E[i++] << u, u += 8), p += h & (1 <>>= g, u -= g), u < 15 && (h += E[i++] << u, u += 8, h += E[i++] <>> 24, h >>>= g, u -= g, g = _ >>> 16 & 255, !(16 & g)) { if (0 == (64 & g)) { _ = b[(65535 & _) + (h & (1 << g) - 1)]; continue i } e.msg = "invalid distance code", A.mode = 30; break e } if (v = 65535 & _, g &= 15, u < g && (h += E[i++] << u, u += 8, u < g && (h += E[i++] << u, u += 8)), v += h & (1 < s) { e.msg = "invalid distance too far back", A.mode = 30; break e } if (h >>>= g, u -= g, g = a - r, v > g) { if (g = v - g, g > d && A.sane) { e.msg = "invalid distance too far back", A.mode = 30; break e } if (x = 0, y = c, 0 === f) { if (x += l - g, g < p) { p -= g; do { R[a++] = c[x++] } while (--g); x = a - v, y = R } } else if (f < g) { if (x += l + f - g, g -= f, g < p) { p -= g; do { R[a++] = c[x++] } while (--g); if (x = 0, f < p) { g = f, p -= g; do { R[a++] = c[x++] } while (--g); x = a - v, y = R } } } else if (x += f - g, g 

2;)R[a++] = y[x++], R[a++] = y[x++], R[a++] = y[x++], p -= 3; p && (R[a++] = y[x++], p > 1 && (R[a++] = y[x++])) } else { x = a - v; do { R[a++] = R[x++], R[a++] = R[x++], R[a++] = R[x++], p -= 3 } while (p > 2); p && (R[a++] = R[x++], p > 1 && (R[a++] = R[x++])) } break } } break } } while (i < n && a > 3, i -= p, u -= p << 3, h &= (1 << u) - 1, e.next_in = i, e.next_out = a, e.avail_in = i < n ? n - i + 5 : 5 - (i - n), e.avail_out = a { const u = h.bits; let w, b, k, m, _, g, p = 0, v = 0, x = 0, y = 0, E = 0, R = 0, A = 0, Z = 0, S = 0, T = 0, O = null, U = 0; const D = new Uint16Array(16), I = new Uint16Array(16); let B, N, C, z = null, F = 0; for (p = 0; p <= r; p++)D[p] = 0; for (v = 0; v = 1 && 0 === D[y]; y--); if (E > y && (E = y), 0 === y) return a[f++] = 20971520, a[f++] = 20971520, h.bits = 1, 0; for (x = 1; x < y && 0 === D[x]; x++); for (E < x && (E = x), Z = 1, p = 1; p <= r; p++)if (Z <<= 1, Z -= D[p], Z 0 && (0 === e || 1 !== y)) return -1; for (I[1] = 0, p = 1; p < r; p++)I[p + 1] = I[p] + D[p]; for (v = 0; v < n; v++)0 !== t[i + v] && (c[I[t[i + v]]++] = v); if (0 === e ? (O = z = c, g = 19) : 1 === e ? (O = o, U -= 257, z = s, F -= 257, g = 256) : (O = l, z = d, g = -1), T = 0, v = 0, p = x, _ = f, R = E, A = 0, k = -1, S = 1 < 852 || 2 === e && S > 592) return 1; for (; ;) { B = p - A, c[v] g ? (N = z[F + c[v]], C = O[U + c[v]]) : (N = 96, C = 0), w = 1 << p - A, b = 1 <> A) + b] = B << 24 | N << 16 | C | 0 } while (0 !== b); for (w = 1 <

>= 1; if (0 !== w ? (T &= w - 1, T += w) : T = 0, v++ , 0 == --D[p]) { if (p === y) break; p = t[i + c[v]] } if (p > E && (T & m) !== k) { for (0 === A && (A = E), _ += x, R = p - A, Z = 1 << R; R + A < y && (Z -= D[R + A], !(Z <= 0));)R++ , Z <<= 1; if (S += 1 < 852 || 2 === e && S > 592) return 1; k = T & m, a[k] = E << 24 | R << 16 | _ - f | 0 } } return 0 !== T && (a[_ + T] = p - A << 24 | 64 < (e >>> 24 & 255) + (e >>> 8 & 65280) + ((65280 & e) << 8) + ((255 & e) < { if (!e || !e.state) return _; const t = e.state; return e.total_in = e.total_out = t.total = 0, e.msg = "", t.wrap && (e.adler = 1 & t.wrap), t.mode = 1, t.last = 0, t.havedict = 0, t.dmax = 32768, t.head = null, t.hold = 0, t.bits = 0, t.lencode = t.lendyn = new Int32Array(852), t.distcode = t.distdyn = new Int32Array(592), t.sane = 1, t.back = -1, b }, S = e => { if (!e || !e.state) return _; const t = e.state; return t.wsize = 0, t.whave = 0, t.wnext = 0, Z(e) }, T = (e, t) => { let i; if (!e || !e.state) return _; const n = e.state; return t > 4), t < 48 && (t &= 15)), t && (t 15) ? _ : (null !== n.window && n.wbits !== t && (n.window = null), n.wrap = i, n.wbits = t, S(e)) }, O = (e, t) => { if (!e) return _; const i = new A; e.state = i, i.window = null; const n = T(e, t); return n !== b && (e.state = null), n }; let U, D, I = !0; const B = e => { if (I) { U = new Int32Array(512), D = new Int32Array(32); let t = 0; for (; t < 144;)e.lens[t++] = 8; for (; t < 256;)e.lens[t++] = 9; for (; t < 280;)e.lens[t++] = 7; for (; t < 288;)e.lens[t++] = 8; for (f(1, e.lens, 0, 288, U, 0, e.work, { bits: 9 }), t = 0; t { let a; const r = e.state; return null === r.window && (r.wsize = 1 <= r.wsize ? (r.window.set(t.subarray(i - r.wsize, i), 0), r.wnext = 0, r.whave = r.wsize) : (a = r.wsize - r.wnext, a > n && (a = n), r.window.set(t.subarray(i - n, i - n + a), r.wnext), (n -= a) ? (r.window.set(t.subarray(i - n, i), 0), r.wnext = n, r.whave = r.wsize) : (r.wnext += a, r.wnext === r.wsize && (r.wnext = 0), r.whave O(e, 15), inflateInit2: O, inflate: (e, i) => { let r, o, s, l, d, c, A, Z, S, T, O, U, D, I, C, z, F, L, M, H, j, K, P = 0; const Y = new Uint8Array(4); let G, X; const W = new Uint8Array([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]); if (!e || !e.state || !e.output || !e.input && 0 !== e.avail_in) return _; r = e.state, r.mode === y && (r.mode = 13), d = e.next_out, s = e.output, A = e.avail_out, l = e.next_in, o = e.input, c = e.avail_in, Z = r.hold, S = r.bits, T = c, O = A, K = b; e: for (; ;)switch (r.mode) { case 1: if (0 === r.wrap) { r.mode = 13; break } for (; S < 16;) { if (0 === c) break e; c-- , Z += o[l++] <>> 8 & 255, r.check = n(r.check, Y, 2, 0), Z = 0, S = 0, r.mode = 2; break } if (r.flags = 0, r.head && (r.head.done = !1), !(1 & r.wrap) || (((255 & Z) <> 8)) % 31) { e.msg = "incorrect header check", r.mode = E; break } if ((15 & Z) !== x) { e.msg = "unknown compression method", r.mode = E; break } if (Z >>>= 4, S -= 4, j = 8 + (15 & Z), 0 === r.wbits) r.wbits = j; else if (j > r.wbits) { e.msg = "invalid window size", r.mode = E; break } r.dmax = 1 << r.wbits, e.adler = r.check = 1, r.mode = 512 & Z ? 10 : y, Z = 0, S = 0; break; case 2: for (; S < 16;) { if (0 === c) break e; c-- , Z += o[l++] <> 8 & 1), 512 & r.flags && (Y[0] = 255 & Z, Y[1] = Z >>> 8 & 255, r.check = n(r.check, Y, 2, 0)), Z = 0, S = 0, r.mode = 3; case 3: for (; S < 32;) { if (0 === c) break e; c-- , Z += o[l++] <>> 8 & 255, Y[2] = Z >>> 16 & 255, Y[3] = Z >>> 24 & 255, r.check = n(r.check, Y, 4, 0)), Z = 0, S = 0, r.mode = 4; case 4: for (; S < 16;) { if (0 === c) break e; c-- , Z += o[l++] <> 8), 512 & r.flags && (Y[0] = 255 & Z, Y[1] = Z >>> 8 & 255, r.check = n(r.check, Y, 2, 0)), Z = 0, S = 0, r.mode = 5; case 5: if (1024 & r.flags) { for (; S < 16;) { if (0 === c) break e; c-- , Z += o[l++] <>> 8 & 255, r.check = n(r.check, Y, 2, 0)), Z = 0, S = 0 } else r.head && (r.head.extra = null); r.mode = 6; case 6: if (1024 & r.flags && (U = r.length, U > c && (U = c), U && (r.head && (j = r.head.extra_len - r.length, r.head.extra || (r.head.extra = new Uint8Array(r.head.extra_len)), r.head.extra.set(o.subarray(l, l + U), j)), 512 & r.flags && (r.check = n(r.check, o, U, l)), c -= U, l += U, r.length -= U), r.length)) break e; r.length = 0, r.mode = 7; case 7: if (2048 & r.flags) { if (0 === c) break e; U = 0; do { j = o[l + U++], r.head && j && r.length < 65536 && (r.head.name += String.fromCharCode(j)) } while (j && U < c); if (512 & r.flags && (r.check = n(r.check, o, U, l)), c -= U, l += U, j) break e } else r.head && (r.head.name = null); r.length = 0, r.mode = 8; case 8: if (4096 & r.flags) { if (0 === c) break e; U = 0; do { j = o[l + U++], r.head && j && r.length < 65536 && (r.head.comment += String.fromCharCode(j)) } while (j && U < c); if (512 & r.flags && (r.check = n(r.check, o, U, l)), c -= U, l += U, j) break e } else r.head && (r.head.comment = null); r.mode = 9; case 9: if (512 & r.flags) { for (; S < 16;) { if (0 === c) break e; c-- , Z += o[l++] <> 9 & 1, r.head.done = !0), e.adler = r.check = 0, r.mode = y; break; case 10: for (; S < 32;) { if (0 === c) break e; c-- , Z += o[l++] <>>= 7 & S, S -= 7 & S, r.mode = 27; break } for (; S < 3;) { if (0 === c) break e; c-- , Z += o[l++] <>>= 1, S -= 1, 3 & Z) { case 0: r.mode = 14; break; case 1: if (B(r), r.mode = 20, i === w) { Z >>>= 2, S -= 2; break e } break; case 2: r.mode = 17; break; case 3: e.msg = "invalid block type", r.mode = E }Z >>>= 2, S -= 2; break; case 14: for (Z >>>= 7 & S, S -= 7 & S; S < 32;) { if (0 === c) break e; c-- , Z += o[l++] <>> 16 ^ 65535)) { e.msg = "invalid stored block lengths", r.mode = E; break } if (r.length = 65535 & Z, Z = 0, S = 0, r.mode = 15, i === w) break e; case 15: r.mode = 16; case 16: if (U = r.length, U) { if (U > c && (U = c), U > A && (U = A), 0 === U) break e; s.set(o.subarray(l, l + U), d), c -= U, l += U, A -= U, d += U, r.length -= U; break } r.mode = y; break; case 17: for (; S < 14;) { if (0 === c) break e; c-- , Z += o[l++] <>>= 5, S -= 5, r.ndist = 1 + (31 & Z), Z >>>= 5, S -= 5, r.ncode = 4 + (15 & Z), Z >>>= 4, S -= 4, r.nlen > 286 || r.ndist > 30) { e.msg = "too many length or distance symbols", r.mode = E; break } r.have = 0, r.mode = 18; case 18: for (; r.have < r.ncode;) { for (; S < 3;) { if (0 === c) break e; c-- , Z += o[l++] <>>= 3, S -= 3 } for (; r.have < 19;)r.lens[W[r.have++]] = 0; if (r.lencode = r.lendyn, r.lenbits = 7, G = { bits: r.lenbits }, K = f(0, r.lens, 0, 19, r.lencode, 0, r.work, G), r.lenbits = G.bits, K) { e.msg = "invalid code lengths set", r.mode = E; break } r.have = 0, r.mode = 19; case 19: for (; r.have < r.nlen + r.ndist;) { for (; P = r.lencode[Z & (1 <>> 24, z = P >>> 16 & 255, F = 65535 & P, !(C <= S);) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } if (F >>= C, S -= C, r.lens[r.have++] = F; else { if (16 === F) { for (X = C + 2; S < X;) { if (0 === c) break e; c-- , Z += o[l++] <>>= C, S -= C, 0 === r.have) { e.msg = "invalid bit length repeat", r.mode = E; break } j = r.lens[r.have - 1], U = 3 + (3 & Z), Z >>>= 2, S -= 2 } else if (17 === F) { for (X = C + 3; S < X;) { if (0 === c) break e; c-- , Z += o[l++] <>>= C, S -= C, j = 0, U = 3 + (7 & Z), Z >>>= 3, S -= 3 } else { for (X = C + 7; S < X;) { if (0 === c) break e; c-- , Z += o[l++] <>>= C, S -= C, j = 0, U = 11 + (127 & Z), Z >>>= 7, S -= 7 } if (r.have + U > r.nlen + r.ndist) { e.msg = "invalid bit length repeat", r.mode = E; break } for (; U--;)r.lens[r.have++] = j } } if (r.mode === E) break; if (0 === r.lens[256]) { e.msg = "invalid code -- missing end-of-block", r.mode = E; break } if (r.lenbits = 9, G = { bits: r.lenbits }, K = f(1, r.lens, 0, r.nlen, r.lencode, 0, r.work, G), r.lenbits = G.bits, K) { e.msg = "invalid literal/lengths set", r.mode = E; break } if (r.distbits = 6, r.distcode = r.distdyn, G = { bits: r.distbits }, K = f(2, r.lens, r.nlen, r.ndist, r.distcode, 0, r.work, G), r.distbits = G.bits, K) { e.msg = "invalid distances set", r.mode = E; break } if (r.mode = 20, i === w) break e; case 20: r.mode = 21; case 21: if (c >= 6 && A >= 258) { e.next_out = d, e.avail_out = A, e.next_in = l, e.avail_in = c, r.hold = Z, r.bits = S, a(e, O), d = e.next_out, s = e.output, A = e.avail_out, l = e.next_in, o = e.input, c = e.avail_in, Z = r.hold, S = r.bits, r.mode === y && (r.back = -1); break } for (r.back = 0; P = r.lencode[Z & (1 <>> 24, z = P >>> 16 & 255, F = 65535 & P, !(C <= S);) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } if (z && 0 == (240 & z)) { for (L = C, M = z, H = F; P = r.lencode[H + ((Z & (1 <> L)], C = P >>> 24, z = P >>> 16 & 255, F = 65535 & P, !(L + C <= S);) { if (0 === c) break e; c-- , Z += o[l++] <>>= L, S -= L, r.back += L } if (Z >>>= C, S -= C, r.back += C, r.length = F, 0 === z) { r.mode = 26; break } if (32 & z) { r.back = -1, r.mode = y; break } if (64 & z) { e.msg = "invalid literal/length code", r.mode = E; break } r.extra = 15 & z, r.mode = 22; case 22: if (r.extra) { for (X = r.extra; S < X;) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } r.length += Z & (1 <>>= r.extra, S -= r.extra, r.back += r.extra } r.was = r.length, r.mode = 23; case 23: for (; P = r.distcode[Z & (1 <>> 24, z = P >>> 16 & 255, F = 65535 & P, !(C <= S);) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } if (0 == (240 & z)) { for (L = C, M = z, H = F; P = r.distcode[H + ((Z & (1 <> L)], C = P >>> 24, z = P >>> 16 & 255, F = 65535 & P, !(L + C <= S);) { if (0 === c) break e; c-- , Z += o[l++] <>>= L, S -= L, r.back += L } if (Z >>>= C, S -= C, r.back += C, 64 & z) { e.msg = "invalid distance code", r.mode = E; break } r.offset = F, r.extra = 15 & z, r.mode = 24; case 24: if (r.extra) { for (X = r.extra; S < X;) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } r.offset += Z & (1 <>>= r.extra, S -= r.extra, r.back += r.extra } if (r.offset > r.dmax) { e.msg = "invalid distance too far back", r.mode = E; break } r.mode = 25; case 25: if (0 === A) break e; if (U = O - A, r.offset > U) { if (U = r.offset - U, U > r.whave && r.sane) { e.msg = "invalid distance too far back", r.mode = E; break } U > r.wnext ? (U -= r.wnext, D = r.wsize - U) : D = r.wnext - U, U > r.length && (U = r.length), I = r.window } else I = s, D = d - r.offset, U = r.length; U > A && (U = A), A -= U, r.length -= U; do { s[d++] = I[D++] } while (--U); 0 === r.length && (r.mode = 21); break; case 26: if (0 === A) break e; s[d++] = r.length, A-- , r.mode = 21; break; case 27: if (r.wrap) { for (; S < 32;) { if (0 === c) break e; c-- , Z |= o[l++] << S, S += 8 } if (O -= A, e.total_out += O, r.total += O, O && (e.adler = r.check = r.flags ? n(r.check, s, O, d - O) : t(r.check, s, O, d - O)), O = A, (r.flags ? Z : R(Z)) !== r.check) { e.msg = "incorrect data check", r.mode = E; break } Z = 0, S = 0 } r.mode = 28; case 28: if (r.wrap && r.flags) { for (; S < 32;) { if (0 === c) break e; c-- , Z += o[l++] << S, S += 8 } if (Z !== (4294967295 & r.total)) { e.msg = "incorrect length check", r.mode = E; break } Z = 0, S = 0 } r.mode = 29; case 29: K = k; break e; case E: K = g; break e; case 31: return p; case 32: default: return _ }return e.next_out = d, e.avail_out = A, e.next_in = l, e.avail_in = c, r.hold = Z, r.bits = S, (r.wsize || O !== e.avail_out && r.mode < E && (r.mode { if (!e || !e.state) return _; let t = e.state; return t.window && (t.window = null), e.state = null, b }, inflateGetHeader: (e, t) => { if (!e || !e.state) return _; const i = e.state; return 0 == (2 & i.wrap) ? _ : (i.head = t, t.done = !1, b) }, inflateSetDictionary: (e, i) => { const n = i.length; let a, r, o; return e && e.state ? (a = e.state, 0 !== a.wrap && 11 !== a.mode ? _ : 11 === a.mode && (r = 1, r = t(r, i, n, 0), r !== a.check) ? g : (o = N(e, i, n, n), o ? (a.mode = 31, p) : (a.havedict = 1, b))) : _ }, inflateInfo: "pako inflate (from Nodeca project)" }; const z = (e, t) => Object.prototype.hasOwnProperty.call(e, t); var F = function (e) { const t = Array.prototype.slice.call(arguments, 1); for (; t.length;) { const i = t.shift(); if (i) { if ("object" != typeof i) throw new TypeError(i + "must be non-object"); for (const t in i) z(i, t) && (e[t] = i[t]) } } return e }, L = e => { let t = 0; for (let i = 0, n = e.length; i < n; i++)t += e[i].length; const i = new Uint8Array(t); for (let t = 0, n = 0, a = e.length; t < a; t++) { let a = e[t]; i.set(a, n), n += a.length } return i }; let M = !0; try { String.fromCharCode.apply(null, new Uint8Array(1)) } catch (e) { M = !1 } const H = new Uint8Array(256); for (let e = 0; e = 252 ? 6 : e >= 248 ? 5 : e >= 240 ? 4 : e >= 224 ? 3 : e >= 192 ? 2 : 1; H[254] = H[254] = 1; var j = e => { if ("function" == typeof TextEncoder && TextEncoder.prototype.encode) return (new TextEncoder).encode(e); let t, i, n, a, r, o = e.length, s = 0; for (a = 0; a < o; a++)i = e.charCodeAt(a), 55296 == (64512 & i) && a + 1 < o && (n = e.charCodeAt(a + 1), 56320 == (64512 & n) && (i = 65536 + (i - 55296 << 10) + (n - 56320), a++)), s += i < 128 ? 1 : i < 2048 ? 2 : i < 65536 ? 3 : 4; for (t = new Uint8Array(s), r = 0, a = 0; r < s; a++)i = e.charCodeAt(a), 55296 == (64512 & i) && a + 1 < o && (n = e.charCodeAt(a + 1), 56320 == (64512 & n) && (i = 65536 + (i - 55296 << 10) + (n - 56320), a++)), i < 128 ? t[r++] = i : i >> 6, t[r++] = 128 | 63 & i) : i >> 12, t[r++] = 128 | i >>> 6 & 63, t[r++] = 128 | 63 & i) : (t[r++] = 240 | i >>> 18, t[r++] = 128 | i >>> 12 & 63, t[r++] = 128 | i >>> 6 & 63, t[r++] = 128 | 63 & i); return t }, K = (e, t) => { const i = t || e.length; if ("function" == typeof TextDecoder && TextDecoder.prototype.decode) return (new TextDecoder).decode(e.subarray(0, t)); let n, a; const r = new Array(2 * i); for (a = 0, n = 0; n < i;) { let t = e[n++]; if (t 4) r[a++] = 65533, n += o - 1; else { for (t &= 2 === o ? 31 : 3 === o ? 15 : 7; o > 1 && n < i;)t = t < 1 ? r[a++] = 65533 : t > 10 & 1023, r[a++] = 56320 | 1023 & t) } } return ((e, t) => { if (t < 65534 && e.subarray && M) return String.fromCharCode.apply(null, e.length === t ? e : e.subarray(0, t)); let i = ""; for (let n = 0; n { (t = t || e.length) > e.length && (t = e.length); let i = t - 1; for (; i >= 0 && 128 == (192 & e[i]);)i--; return i t ? i : t }, Y = { 2: "need dictionary", 1: "stream end", 0: "", "-1": "file error", "-2": "stream error", "-3": "data error", "-4": "insufficient memory", "-5": "buffer error", "-6": "incompatible version" }; var G = function () { this.input = null, this.next_in = 0, this.avail_in = 0, this.total_in = 0, this.output = null, this.next_out = 0, this.avail_out = 0, this.total_out = 0, this.msg = "", this.state = null, this.data_type = 2, this.adler = 0 }; var X = function () { this.text = 0, this.time = 0, this.xflags = 0, this.os = 0, this.extra = null, this.extra_len = 0, this.name = "", this.comment = "", this.hcrc = 0, this.done = !1 }; const W = Object.prototype.toString, { Z_NO_FLUSH: q, Z_FINISH: J, Z_OK: Q, Z_STREAM_END: V, Z_NEED_DICT: $, Z_STREAM_ERROR: ee, Z_DATA_ERROR: te, Z_MEM_ERROR: ie } = c; function ne(e) { this.options = F({ chunkSize: 65536, windowBits: 15, to: "" }, e || {}); const t = this.options; t.raw && t.windowBits >= 0 && t.windowBits = 0 && t.windowBits 15 && t.windowBits 0 && r === V && i.state.wrap > 0 && 0 !== e[i.next_in];)C.inflateReset(i), r = C.inflate(i, o); switch (r) { case ee: case te: case $: case ie: return this.onEnd(r), this.ended = !0, !1 }if (s = i.avail_out, i.next_out && (0 === i.avail_out || r === V)) if ("string" === this.options.to) { let e = P(i.output, i.next_out), t = i.next_out - e, a = K(i.output, e); i.next_out = t, i.avail_out = n - t, t && i.output.set(i.output.subarray(e, e + t), 0), this.onData(a) } else this.onData(i.output.length === i.next_out ? i.output : i.output.subarray(0, i.next_out)); if (r !== Q || 0 !== s) { if (r === V) return r = C.inflateEnd(this.strm), this.onEnd(r), this.ended = !0, !0; if (0 === i.avail_in) break } } return !0 }, ne.prototype.onData = function (e) { this.chunks.push(e) }, ne.prototype.onEnd = function (e) { e === Q && ("string" === this.options.to ? this.result = this.chunks.join("") : this.result = L(this.chunks)), this.chunks = [], this.err = e, this.msg = this.strm.msg }; var re = ne, oe = ae, se = function (e, t) { return (t = t || {}).raw = !0, ae(e, t) }, le = ae, de = c, fe = { Inflate: re, inflate: oe, inflateRaw: se, ungzip: le, constants: de }; e.Inflate = re, e.constants = de, e.default = fe, e.inflate = oe, e.inflateRaw = se, e.ungzip = le, Object.defineProperty(e, "__esModule", { value: !0 }) })); function roott(e, t) { for (var i = "", n = 0; n = 65 && a = 97 && a <= 122 && (o = (a - 97 - 1 * t + 26) % 26 + 97), i += String.fromCharCode(o) } return i } function pushmsg(e) { let t = ""; if ("undefined" == typeof window) try { t = nodeAtob(e) } catch (e) { } else t = atob(e); const i = t.split("").map(function (e) { return e.charCodeAt(0) }) , n = new Uint8Array(i) , a = window.pako.inflate(n); return t = function (e) { let t, i, n, a, o = ""; const s = e.length; for (t = 0; t > 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: o += String.fromCharCode(i); break; case 12: case 13: n = e[t++],o += String.fromCharCode((31 & i) << 6 | 63 & n); break; case 14: n = e[t++],a = e[t++],o += String.fromCharCode((15 & i) << 12 | (63 & n) << 6 | (63 & a) << 0) } return o }(new Uint16Array(a)), unescape(t) } function main(e,t) { var i = pushmsg(roott(e, t)); return JSON.parse(i); } #Code#})();

经过分析,订阅的四个主题分别代表为:

chatroom_v2/R1_{matchId} 订阅-聊天

live/football/detail/{matchId}/data_v2 订阅-比赛趋势

live/football/detail/{matchId}/bet365 订阅-bet365指数

live/football/detail/{matchId}/top_v2 订阅-比赛数据

最后附上懒人链接【C#WinForm雷速比赛MQTT逆向程序】


总结

文章到这里就结束了,在js逆向中千方百试,要合理运用以及推理分析需要不断的去尝试,好记性不如烂笔头。

美国云服务器