mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-03 18:47:41 +08:00
client: implement query personal sign
This commit is contained in:
parent
727686e453
commit
f56bcbe326
@ -17,8 +17,6 @@ type NetworkReader struct {
|
||||
conn net.Conn
|
||||
}
|
||||
|
||||
type TlvMap map[uint16][]byte
|
||||
|
||||
// --- ByteStream reader ---
|
||||
|
||||
func NewReader(data []byte) *Reader {
|
||||
@ -92,33 +90,6 @@ func (r *Reader) ReadAvailable() []byte {
|
||||
return r.ReadBytes(r.buf.Len())
|
||||
}
|
||||
|
||||
func (r *Reader) ReadTlvMap(tagSize int) (m TlvMap) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// TODO: error
|
||||
}
|
||||
}()
|
||||
m = make(map[uint16][]byte)
|
||||
for {
|
||||
if r.Len() < tagSize {
|
||||
return m
|
||||
}
|
||||
var k uint16
|
||||
switch tagSize {
|
||||
case 1:
|
||||
k = uint16(r.ReadByte())
|
||||
case 2:
|
||||
k = r.ReadUInt16()
|
||||
case 4:
|
||||
k = uint16(r.ReadInt32())
|
||||
}
|
||||
if k == 255 {
|
||||
return m
|
||||
}
|
||||
m[k] = r.ReadBytes(int(r.ReadUInt16()))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reader) Len() int {
|
||||
return r.buf.Len()
|
||||
}
|
||||
@ -127,11 +98,6 @@ func (r *Reader) Index() int64 {
|
||||
return r.buf.Size()
|
||||
}
|
||||
|
||||
func (tlv TlvMap) Exists(key uint16) bool {
|
||||
_, ok := tlv[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
// --- Network reader ---
|
||||
|
||||
func NewNetworkReader(conn net.Conn) *NetworkReader {
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"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/internal/tlv"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x6ff"
|
||||
@ -37,7 +38,10 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
||||
reader.ReadUInt16() // sub command
|
||||
t := reader.ReadByte()
|
||||
reader.ReadUInt16()
|
||||
m := reader.ReadTlvMap(2)
|
||||
m, err := tlv.NewDecoder(2, 2).DecodeRecordMap(reader.ReadAvailable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m.Exists(0x402) {
|
||||
c.sig.Dpwd = []byte(utils.RandomString(16))
|
||||
c.sig.T402 = m[0x402]
|
||||
@ -45,9 +49,7 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
||||
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 {
|
||||
@ -208,7 +210,10 @@ func decodeExchangeEmpResponse(c *QQClient, _ *network.IncomingPacketInfo, paylo
|
||||
cmd := reader.ReadUInt16()
|
||||
t := reader.ReadByte()
|
||||
reader.ReadUInt16()
|
||||
m := reader.ReadTlvMap(2)
|
||||
m, err := tlv.NewDecoder(2, 2).DecodeRecordMap(reader.ReadAvailable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t != 0 {
|
||||
return nil, errors.Errorf("exchange_emp failed: %v", t)
|
||||
}
|
||||
@ -248,7 +253,10 @@ func decodeTransEmpResponse(c *QQClient, _ *network.IncomingPacketInfo, payload
|
||||
}
|
||||
sig := body.ReadBytesShort()
|
||||
body.ReadUInt16()
|
||||
m := body.ReadTlvMap(2)
|
||||
m, err := tlv.NewDecoder(2, 2).DecodeRecordMap(reader.ReadAvailable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if m.Exists(0x17) {
|
||||
return &QRCodeLoginResponse{
|
||||
State: QRCodeImageFetch,
|
||||
@ -291,7 +299,10 @@ func decodeTransEmpResponse(c *QQClient, _ *network.IncomingPacketInfo, payload
|
||||
c.highwaySession.Uin = strconv.FormatInt(c.Uin, 10)
|
||||
body.ReadInt32() // sig create time
|
||||
body.ReadUInt16()
|
||||
m := body.ReadTlvMap(2)
|
||||
m, err := tlv.NewDecoder(2, 2).DecodeRecordMap(reader.ReadAvailable())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !m.Exists(0x18) || !m.Exists(0x1e) || !m.Exists(0x19) {
|
||||
return nil, errors.New("wtlogin.trans_emp sub cmd 0x12 error: tlv error")
|
||||
}
|
||||
@ -447,6 +458,15 @@ func decodeSummaryCardResponse(_ *QQClient, _ *network.IncomingPacketInfo, paylo
|
||||
info.VipLevel = fmt.Sprintf("svip%d", v3.Level)
|
||||
}
|
||||
}
|
||||
|
||||
richSign := rsp.ReadBytes(32)
|
||||
records, _ := tlv.NewDecoder(1, 1).Decode(richSign)
|
||||
for _, r := range records {
|
||||
if r.Tag == 3 {
|
||||
info.Sign = string(r.Value)
|
||||
}
|
||||
}
|
||||
|
||||
info.LoginDays = rsp.ReadInt64(36)
|
||||
services := rsp.ReadByteArrArr(46)
|
||||
readService := func(buf []byte) (*profilecard.BusiComm, []byte) {
|
||||
|
107
client/internal/tlv/decoder.go
Normal file
107
client/internal/tlv/decoder.go
Normal file
@ -0,0 +1,107 @@
|
||||
package tlv
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Record represents a Tag-Length-Value record.
|
||||
type Record struct {
|
||||
Tag int
|
||||
Length int
|
||||
Value []byte
|
||||
}
|
||||
|
||||
type RecordMap map[int][]byte
|
||||
|
||||
func (rm RecordMap) Exists(key int) bool {
|
||||
_, ok := rm[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
var (
|
||||
ErrMessageTooShort = errors.New("tlv: message too short")
|
||||
)
|
||||
|
||||
// Decoder is a configurable TLV decoder.
|
||||
type Decoder struct {
|
||||
tagSize uint8
|
||||
lenSize uint8
|
||||
headSize uint8
|
||||
}
|
||||
|
||||
func NewDecoder(tagSize, lenSize uint8) *Decoder {
|
||||
check := func(t string, s uint8) {
|
||||
switch s {
|
||||
case 1, 2, 4:
|
||||
// ok
|
||||
default:
|
||||
panic("invalid " + t)
|
||||
}
|
||||
}
|
||||
check("tag size", tagSize)
|
||||
check("len size", lenSize)
|
||||
|
||||
return &Decoder{tagSize: tagSize, lenSize: lenSize, headSize: tagSize + lenSize}
|
||||
}
|
||||
|
||||
func (d *Decoder) decodeRecord(data []byte) (r Record, err error) {
|
||||
tagSize := d.tagSize
|
||||
lenSize := d.lenSize
|
||||
headSize := int(tagSize + lenSize)
|
||||
if len(data) < headSize {
|
||||
err = ErrMessageTooShort
|
||||
return
|
||||
}
|
||||
|
||||
r.Tag = d.read(tagSize, data)
|
||||
r.Length = d.read(lenSize, data[tagSize:])
|
||||
|
||||
if len(data) < headSize+r.Length {
|
||||
err = ErrMessageTooShort
|
||||
return
|
||||
}
|
||||
r.Value = data[headSize : headSize+r.Length : headSize+r.Length]
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Decoder) read(size uint8, data []byte) int {
|
||||
switch size {
|
||||
case 1:
|
||||
return int(data[0])
|
||||
case 2:
|
||||
return int(binary.BigEndian.Uint16(data))
|
||||
case 4:
|
||||
return int(binary.BigEndian.Uint32(data))
|
||||
default:
|
||||
panic("invalid size")
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Decoder) Decode(data []byte) ([]Record, error) {
|
||||
var records []Record
|
||||
for len(data) > 0 {
|
||||
r, err := d.decodeRecord(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
records = append(records, r)
|
||||
data = data[int(d.headSize)+r.Length:]
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func (d *Decoder) DecodeRecordMap(data []byte) (RecordMap, error) {
|
||||
records, err := d.Decode(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rm := make(RecordMap, len(records))
|
||||
for _, record := range records {
|
||||
rm[record.Tag] = record.Value
|
||||
}
|
||||
|
||||
return rm, nil
|
||||
}
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/tlv"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
@ -25,9 +26,7 @@ func (c *QQClient) decodeT161(data []byte) {
|
||||
|
||||
func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
tea := binary.NewTeaCipher(ek)
|
||||
reader := binary.NewReader(tea.Decrypt(data))
|
||||
reader.ReadBytes(2)
|
||||
m := reader.ReadTlvMap(2)
|
||||
m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(tea.Decrypt(data)[2:])
|
||||
if t130, ok := m[0x130]; ok {
|
||||
c.decodeT130(t130)
|
||||
}
|
||||
@ -133,9 +132,7 @@ func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
// wtlogin.exchange_emp
|
||||
func (c *QQClient) decodeT119R(data []byte) {
|
||||
tea := binary.NewTeaCipher(c.deviceInfo.TgtgtKey)
|
||||
reader := binary.NewReader(tea.Decrypt(data))
|
||||
reader.ReadBytes(2)
|
||||
m := reader.ReadTlvMap(2)
|
||||
m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(tea.Decrypt(data)[2:])
|
||||
if t120, ok := m[0x120]; ok {
|
||||
c.sig.SKey = t120
|
||||
c.sig.SKeyExpiredTime = time.Now().Unix() + 21600
|
||||
@ -223,8 +220,7 @@ func readT512(data []byte) (psKeyMap map[string][]byte, pt4TokenMap map[string][
|
||||
}
|
||||
|
||||
func readT531(data []byte) (a1, noPicSig []byte) {
|
||||
reader := binary.NewReader(data)
|
||||
m := reader.ReadTlvMap(2)
|
||||
m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(data)
|
||||
if m.Exists(0x103) && m.Exists(0x16a) && m.Exists(0x113) && m.Exists(0x10c) {
|
||||
a1 = append(m[0x106], m[0x10c]...)
|
||||
noPicSig = m[0x16a]
|
||||
|
8
go.sum
8
go.sum
@ -7,6 +7,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak=
|
||||
github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -26,8 +31,9 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
Loading…
x
Reference in New Issue
Block a user