github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/tlv_decoders.go (about)

     1  package client
     2  
     3  import (
     4  	"crypto/md5"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/Mrs4s/MiraiGo/client/internal/tlv"
     9  	"github.com/Mrs4s/MiraiGo/utils"
    10  
    11  	"github.com/Mrs4s/MiraiGo/binary"
    12  )
    13  
    14  // --- tlv decoders for qq client ---
    15  
    16  /*
    17  func (c *QQClient) decodeT161(data []byte) {
    18  	reader := binary.NewReader(data)
    19  	reader.ReadBytes(2)
    20  	t := reader.ReadTlvMap(2)
    21  	if t172, ok := t[0x172]; ok {
    22  		c.rollbackSig = t172
    23  	}
    24  }
    25  */
    26  
    27  func (c *QQClient) decodeT119(data, ek []byte) {
    28  	tea := binary.NewTeaCipher(ek)
    29  	m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(tea.Decrypt(data)[2:])
    30  	if t130, ok := m[0x130]; ok {
    31  		c.decodeT130(t130)
    32  	}
    33  	if t113, ok := m[0x113]; ok {
    34  		c.decodeT113(t113)
    35  	}
    36  	/*
    37  		if t528, ok := m[0x528]; ok {
    38  			c.t528 = t528
    39  		}
    40  		if t530, ok := m[0x530]; ok {
    41  			c.t530 = t530
    42  		}
    43  	*/
    44  	if t108, ok := m[0x108]; ok {
    45  		c.sig.Ksid = t108
    46  	}
    47  
    48  	var (
    49  		// openId   []byte
    50  		// openKey  []byte
    51  		// payToken []byte
    52  		// pf       []byte
    53  		// pfkey    []byte
    54  		gender uint16 = 0
    55  		age    uint16 = 0
    56  		nick          = ""
    57  		// a1       []byte
    58  		// noPicSig []byte
    59  		// ctime           = time.Now().Unix()
    60  		// etime           = ctime + 2160000
    61  		psKeyMap    map[string][]byte
    62  		pt4TokenMap map[string][]byte
    63  	)
    64  
    65  	if t11a, ok := m[0x11a]; ok {
    66  		nick, age, gender = readT11A(t11a)
    67  	}
    68  	/*
    69  		if _, ok := m[0x125]; ok {
    70  			openId, openKey = readT125(t125)
    71  		}
    72  		if t186, ok := m[0x186]; ok {
    73  		 	c.decodeT186(t186)
    74  		}
    75  		if _, ok := m[0x199]; ok {
    76  			openId, payToken = readT199(t199)
    77  		}
    78  		if _, ok := m[0x200]; ok {
    79  			pf, pfkey = readT200(t200)
    80  		}
    81  		if _, ok := m[0x531]; ok {
    82  			a1, noPicSig = readT531(t531)
    83  		}
    84  		if _, ok := m[0x138]; ok {
    85  			readT138(t138) // chg time
    86  		}
    87  	*/
    88  	if t512, ok := m[0x512]; ok {
    89  		psKeyMap, pt4TokenMap = readT512(t512)
    90  	}
    91  	c.oicq.WtSessionTicketKey = utils.Select(m[0x134], c.oicq.WtSessionTicketKey)
    92  
    93  	// we don't use `c.sigInfo = &auth.SigInfo{...}` here,
    94  	// because we need keep other fields in `c.sigInfo`
    95  	s := c.sig
    96  	s.LoginBitmap = 0
    97  	s.SrmToken = utils.Select(m[0x16a], s.SrmToken)
    98  	s.T133 = utils.Select(m[0x133], s.T133)
    99  	s.EncryptedA1 = utils.Select(m[0x106], s.EncryptedA1)
   100  	s.TGT = m[0x10a]
   101  	s.TGTKey = m[0x10d]
   102  	s.UserStKey = m[0x10e]
   103  	s.UserStWebSig = m[0x103]
   104  	s.SKey = m[0x120]
   105  	s.SKeyExpiredTime = time.Now().Unix() + 21600
   106  	s.D2 = m[0x143]
   107  	s.D2Key = m[0x305]
   108  	s.DeviceToken = m[0x322]
   109  
   110  	s.PsKeyMap = psKeyMap
   111  	s.Pt4TokenMap = pt4TokenMap
   112  	if len(c.sig.EncryptedA1) > 51+16 {
   113  		data, cl := binary.OpenWriterF(func(w *binary.Writer) {
   114  			w.Write(c.PasswordMd5[:])
   115  			w.WriteUInt32(0) // []byte{0x00, 0x00, 0x00, 0x00}...
   116  			w.WriteUInt32(uint32(c.Uin))
   117  		})
   118  		key := md5.Sum(data)
   119  		cl()
   120  		decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sig.EncryptedA1)
   121  		if len(decrypted) > 51+16 {
   122  			dr := binary.NewReader(decrypted)
   123  			dr.ReadBytes(51)
   124  			c.Device().TgtgtKey = dr.ReadBytes(16)
   125  		}
   126  	}
   127  	c.Nickname = nick
   128  	c.Age = age
   129  	c.Gender = gender
   130  }
   131  
   132  // wtlogin.exchange_emp
   133  func (c *QQClient) decodeT119R(data []byte) {
   134  	tea := binary.NewTeaCipher(c.Device().TgtgtKey)
   135  	m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(tea.Decrypt(data)[2:])
   136  	if t120, ok := m[0x120]; ok {
   137  		c.sig.SKey = t120
   138  		c.sig.SKeyExpiredTime = time.Now().Unix() + 21600
   139  		c.debug("skey updated: %v", c.sig.SKey)
   140  	}
   141  	if t11a, ok := m[0x11a]; ok {
   142  		c.Nickname, c.Age, c.Gender = readT11A(t11a)
   143  		c.debug("account info updated: " + c.Nickname)
   144  	}
   145  }
   146  
   147  func (c *QQClient) decodeT130(data []byte) {
   148  	reader := binary.NewReader(data)
   149  	reader.ReadBytes(2)
   150  	// c.timeDiff = int64(reader.ReadInt32()) - time.Now().Unix()
   151  	// c.t149 = reader.ReadBytes(4)
   152  }
   153  
   154  func (c *QQClient) decodeT113(data []byte) {
   155  	reader := binary.NewReader(data)
   156  	uin := reader.ReadInt32() // ?
   157  	fmt.Println("got t113 uin:", uin)
   158  }
   159  
   160  /*
   161  func (c *QQClient) decodeT186(data []byte) {
   162  	// c.pwdFlag = data[1] == 1
   163  }
   164  */
   165  
   166  // --- tlv readers ---
   167  
   168  func readT125(data []byte) (openID, openKey []byte) {
   169  	reader := binary.NewReader(data)
   170  	openID = reader.ReadBytesShort()
   171  	openKey = reader.ReadBytesShort()
   172  	return
   173  }
   174  
   175  func readT11A(data []byte) (nick string, age, gender uint16) {
   176  	reader := binary.NewReader(data)
   177  	reader.ReadUInt16()
   178  	age = uint16(reader.ReadByte())
   179  	gender = uint16(reader.ReadByte())
   180  	nick = reader.ReadStringLimit(int(reader.ReadByte()) & 0xff)
   181  	return
   182  }
   183  
   184  func readT199(data []byte) (openID, payToken []byte) {
   185  	reader := binary.NewReader(data)
   186  	openID = reader.ReadBytesShort()
   187  	payToken = reader.ReadBytesShort()
   188  	return
   189  }
   190  
   191  func readT200(data []byte) (pf, pfKey []byte) {
   192  	reader := binary.NewReader(data)
   193  	pf = reader.ReadBytesShort()
   194  	pfKey = reader.ReadBytesShort()
   195  	return
   196  }
   197  
   198  func readT512(data []byte) (psKeyMap map[string][]byte, pt4TokenMap map[string][]byte) {
   199  	reader := binary.NewReader(data)
   200  	length := int(reader.ReadUInt16())
   201  
   202  	psKeyMap = make(map[string][]byte, length)
   203  	pt4TokenMap = make(map[string][]byte, length)
   204  
   205  	for i := 0; i < length; i++ {
   206  		domain := reader.ReadStringShort()
   207  		psKey := reader.ReadBytesShort()
   208  		pt4Token := reader.ReadBytesShort()
   209  
   210  		if len(psKey) > 0 {
   211  			psKeyMap[domain] = psKey
   212  		}
   213  
   214  		if len(pt4Token) > 0 {
   215  			pt4TokenMap[domain] = pt4Token
   216  		}
   217  	}
   218  
   219  	return
   220  }
   221  
   222  func readT531(data []byte) (a1, noPicSig []byte) {
   223  	m, _ := tlv.NewDecoder(2, 2).DecodeRecordMap(data)
   224  	if m.Exists(0x103) && m.Exists(0x16a) && m.Exists(0x113) && m.Exists(0x10c) {
   225  		a1 = append(m[0x106], m[0x10c]...)
   226  		noPicSig = m[0x16a]
   227  	}
   228  	return
   229  }