From 6f4f491002733025a3dd93e0bde13acc673839f8 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Tue, 21 Jun 2022 11:52:16 +0800 Subject: [PATCH] client: fix Android version --- client/builders.go | 6 ++-- client/decoders.go | 9 +++++- client/internal/auth/auth.go | 5 ++-- client/internal/auth/pow.go | 57 ++++++++++++++++++++++++++++++++++++ internal/tlv/t.go | 10 +++++++ 5 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 client/internal/auth/pow.go create mode 100644 internal/tlv/t.go diff --git a/client/builders.go b/client/builders.go index bce0218c..9704ca8b 100644 --- a/client/builders.go +++ b/client/builders.go @@ -269,12 +269,13 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt seq := c.nextSeq() req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt16(2) // sub command - w.WriteUInt16(4) + w.WriteUInt16(5) w.Write(tlv.T2(result, sign)) w.Write(tlv.T8(2052)) w.Write(tlv.T104(c.sig.T104)) w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap)) + w.Write(tlv.T(0x547, c.sig.T547)) })) req2 := network.Request{ @@ -343,12 +344,13 @@ func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) { seq := c.nextSeq() req := c.buildOicqRequestPacket(c.Uin, 0x0810, binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt16(2) - w.WriteUInt16(4) + w.WriteUInt16(5) w.Write(tlv.T193(ticket)) w.Write(tlv.T8(2052)) w.Write(tlv.T104(c.sig.T104)) w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap)) + w.Write(tlv.T(0x547, c.sig.T547)) })) req2 := network.Request{ diff --git a/client/decoders.go b/client/decoders.go index e8cb149c..51a63ccc 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -12,6 +12,7 @@ import ( "github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary/jce" + "github.com/Mrs4s/MiraiGo/client/internal/auth" "github.com/Mrs4s/MiraiGo/client/internal/network" "github.com/Mrs4s/MiraiGo/client/pb" "github.com/Mrs4s/MiraiGo/client/pb/cmd0x352" @@ -42,6 +43,11 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b h := md5.Sum(append(append(c.deviceInfo.Guid, c.sig.Dpwd...), c.sig.T402...)) c.sig.G = h[:] } + if m.Exists(0x546) { + c.debug("pow start") + c.sig.T547 = auth.CalcPow(m[0x546]) + c.debug("pow end") + } if t == 0 { // login success // if t150, ok := m[0x150]; ok { // c.t150 = t150 @@ -100,7 +106,8 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b c.sig.RandSeed = m[0x403] phone := func() string { r := binary.NewReader(m[0x178]) - return r.ReadStringLimit(int(r.ReadInt32())) + r.ReadStringShort() + return r.ReadStringShort() }() if t204, ok := m[0x204]; ok { // 同时支持扫码验证 ? return LoginResponse{ diff --git a/client/internal/auth/auth.go b/client/internal/auth/auth.go index 45e9954e..48c33757 100644 --- a/client/internal/auth/auth.go +++ b/client/internal/auth/auth.go @@ -32,8 +32,8 @@ func (i Protocol) Version() *AppVersion { case AndroidPhone: // Dumped by mirai from qq android v8.8.38 return &AppVersion{ ApkId: "com.tencent.mobileqq", - AppId: 537044845, - SubAppId: 537044845, + AppId: 537122601, + SubAppId: 537122601, SortVersionName: "8.8.95", BuildTime: 1654672174, ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D}, @@ -137,6 +137,7 @@ type SigInfo struct { G []byte T402 []byte RandSeed []byte // t403 + T547 []byte // rollbackSig []byte // t149 []byte // t150 []byte diff --git a/client/internal/auth/pow.go b/client/internal/auth/pow.go new file mode 100644 index 00000000..0e42e9c8 --- /dev/null +++ b/client/internal/auth/pow.go @@ -0,0 +1,57 @@ +package auth + +import ( + "bytes" + "crypto/sha256" + "math/big" + "time" + + "github.com/Mrs4s/MiraiGo/binary" +) + +func CalcPow(data []byte) []byte { + r := binary.NewReader(data) + a := r.ReadByte() + typ := r.ReadByte() + c := r.ReadByte() + ok := r.ReadByte() != 0 + e := r.ReadUInt16() + f := r.ReadUInt16() + src := r.ReadBytesShort() + tgt := r.ReadBytesShort() + cpy := r.ReadBytesShort() + + var dst []byte + var elp, cnt uint32 + if typ == 2 && len(tgt) == 32 { + start := time.Now() + tmp := new(big.Int).SetBytes(src) + hash := sha256.Sum256(tmp.Bytes()) + one := big.NewInt(1) + for !bytes.Equal(hash[:], tgt) { + tmp = tmp.Add(tmp, one) + hash = sha256.Sum256(tmp.Bytes()) + cnt++ + } + ok = true + dst = tmp.Bytes() + elp = uint32(time.Now().Sub(start).Milliseconds()) + } + + w := binary.SelectWriter() + w.WriteByte(a) + w.WriteByte(typ) + w.WriteByte(c) + w.WriteBool(ok) + w.WriteUInt16(e) + w.WriteUInt16(f) + w.WriteBytesShort(src) + w.WriteBytesShort(tgt) + w.WriteBytesShort(cpy) + if ok { + w.WriteBytesShort(dst) + w.WriteUInt32(elp) + w.WriteUInt32(cnt) + } + return w.Bytes() +} diff --git a/internal/tlv/t.go b/internal/tlv/t.go new file mode 100644 index 00000000..a6efe8f9 --- /dev/null +++ b/internal/tlv/t.go @@ -0,0 +1,10 @@ +package tlv + +import "github.com/Mrs4s/MiraiGo/binary" + +func T(tag uint16, value []byte) []byte { + return binary.NewWriterF(func(w *binary.Writer) { + w.WriteUInt16(tag) + w.WriteBytesShort(value) + }) +}