mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
feat: token login.
This commit is contained in:
parent
ede433b4f6
commit
369e834557
@ -1,6 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@ -352,6 +353,53 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
func (c *QQClient) buildRequestChangeSigPacket() (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) {
|
||||
w.WriteUInt16(11)
|
||||
w.WriteUInt16(17)
|
||||
|
||||
w.Write(tlv.T100(c.version.SSOVersion, 100, c.version.MainSigMap))
|
||||
w.Write(tlv.T10A(c.sigInfo.tgt))
|
||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||
w.Write(tlv.T108(SystemDeviceInfo.IMEI))
|
||||
h := md5.Sum(c.sigInfo.d2Key)
|
||||
w.Write(tlv.T144(
|
||||
SystemDeviceInfo.AndroidId,
|
||||
SystemDeviceInfo.GenDeviceInfoData(),
|
||||
SystemDeviceInfo.OSType,
|
||||
SystemDeviceInfo.Version.Release,
|
||||
SystemDeviceInfo.SimInfo,
|
||||
SystemDeviceInfo.APN,
|
||||
false, true, false, tlv.GuidFlag(),
|
||||
SystemDeviceInfo.Model,
|
||||
SystemDeviceInfo.Guid,
|
||||
SystemDeviceInfo.Brand,
|
||||
h[:],
|
||||
))
|
||||
w.Write(tlv.T143(c.sigInfo.d2))
|
||||
w.Write(tlv.T142(c.version.ApkId))
|
||||
w.Write(tlv.T154(seq))
|
||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||
w.Write(tlv.T141(SystemDeviceInfo.SimInfo, SystemDeviceInfo.APN))
|
||||
w.Write(tlv.T8(2052))
|
||||
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
|
||||
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
|
||||
w.Write(tlv.T187(SystemDeviceInfo.MacAddress))
|
||||
w.Write(tlv.T188(SystemDeviceInfo.AndroidId))
|
||||
w.Write(tlv.T194(SystemDeviceInfo.IMSIMd5))
|
||||
w.Write(tlv.T511([]string{
|
||||
"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
|
||||
"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
|
||||
"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
|
||||
}))
|
||||
//w.Write(tlv.T202(SystemDeviceInfo.WifiBSSID, SystemDeviceInfo.WifiSSID))
|
||||
})
|
||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.exchange_emp", SystemDeviceInfo.IMEI, c.sigInfo.tgt, c.OutGoingPacketSessionId, req, c.ksid)
|
||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// StatSvc.register
|
||||
func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
|
@ -263,6 +263,38 @@ func (c *QQClient) Login() (*LoginResponse, error) {
|
||||
return &l, nil
|
||||
}
|
||||
|
||||
func (c *QQClient) TokenLogin(token []byte) error {
|
||||
if c.Online {
|
||||
return ErrAlreadyOnline
|
||||
}
|
||||
if c.Conn == nil {
|
||||
err := c.connect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
go c.netLoop()
|
||||
}
|
||||
{
|
||||
r := binary.NewReader(token)
|
||||
c.Uin = r.ReadInt64()
|
||||
c.sigInfo.d2 = r.ReadBytesShort()
|
||||
c.sigInfo.d2Key = r.ReadBytesShort()
|
||||
c.sigInfo.tgt = r.ReadBytesShort()
|
||||
c.sigInfo.srmToken = r.ReadBytesShort()
|
||||
c.sigInfo.t133 = r.ReadBytesShort()
|
||||
c.sigInfo.encryptedA1 = r.ReadBytesShort()
|
||||
c.sigInfo.wtSessionTicketKey = r.ReadBytesShort()
|
||||
c.OutGoingPacketSessionId = r.ReadBytesShort()
|
||||
SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||
}
|
||||
_, err := c.sendAndWait(c.buildRequestChangeSigPacket())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.init()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *QQClient) FetchQRCode() (*QRCodeLoginResponse, error) {
|
||||
if c.Online {
|
||||
return nil, ErrAlreadyOnline
|
||||
@ -384,6 +416,21 @@ func (c *QQClient) init() {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *QQClient) GenToken() []byte {
|
||||
return binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt64(uint64(c.Uin))
|
||||
w.WriteBytesShort(c.sigInfo.d2)
|
||||
w.WriteBytesShort(c.sigInfo.d2Key)
|
||||
w.WriteBytesShort(c.sigInfo.tgt)
|
||||
w.WriteBytesShort(c.sigInfo.srmToken)
|
||||
w.WriteBytesShort(c.sigInfo.t133)
|
||||
w.WriteBytesShort(c.sigInfo.encryptedA1)
|
||||
w.WriteBytesShort(c.sigInfo.wtSessionTicketKey)
|
||||
w.WriteBytesShort(c.OutGoingPacketSessionId)
|
||||
w.WriteBytesShort(SystemDeviceInfo.TgtgtKey)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
|
||||
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
|
||||
if err != nil {
|
||||
|
@ -53,7 +53,7 @@ func decodeLoginResponse(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
|
||||
if m.Exists(0x403) {
|
||||
c.randSeed = m[0x403]
|
||||
}
|
||||
c.decodeT119(m[0x119])
|
||||
c.decodeT119(m[0x119], SystemDeviceInfo.TgtgtKey)
|
||||
return LoginResponse{
|
||||
Success: true,
|
||||
}, nil
|
||||
@ -204,11 +204,15 @@ func decodeExchangeEmpResponse(c *QQClient, _ *incomingPacketInfo, payload []byt
|
||||
m := reader.ReadTlvMap(2)
|
||||
if t != 0 {
|
||||
c.Error("exchange_emp error: %v", t)
|
||||
return nil, nil
|
||||
return nil, errors.New("exchange_emp failed")
|
||||
}
|
||||
if cmd == 15 { // TODO: 免密登录
|
||||
if cmd == 15 {
|
||||
c.decodeT119R(m[0x119])
|
||||
}
|
||||
if cmd == 11 {
|
||||
h := md5.Sum(c.sigInfo.d2Key)
|
||||
c.decodeT119(m[0x119], h[:])
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package client
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
"time"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
@ -19,8 +20,8 @@ func (c *QQClient) decodeT161(data []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *QQClient) decodeT119(data []byte) {
|
||||
tea := binary.NewTeaCipher(SystemDeviceInfo.TgtgtKey)
|
||||
func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
tea := binary.NewTeaCipher(ek)
|
||||
reader := binary.NewReader(tea.Decrypt(data))
|
||||
reader.ReadBytes(2)
|
||||
m := reader.ReadTlvMap(2)
|
||||
@ -85,9 +86,9 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
|
||||
c.sigInfo = &loginSigInfo{
|
||||
loginBitmap: 0,
|
||||
srmToken: m[0x16a],
|
||||
t133: m[0x133],
|
||||
encryptedA1: m[0x106],
|
||||
srmToken: utils.Select(m[0x16a], c.sigInfo.srmToken),
|
||||
t133: utils.Select(m[0x133], c.sigInfo.t133),
|
||||
encryptedA1: utils.Select(m[0x106], c.sigInfo.encryptedA1),
|
||||
tgt: m[0x10a],
|
||||
tgtKey: m[0x10d],
|
||||
userStKey: m[0x10e],
|
||||
@ -96,12 +97,13 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
sKeyExpiredTime: time.Now().Unix() + 21600,
|
||||
d2: m[0x143],
|
||||
d2Key: m[0x305],
|
||||
wtSessionTicketKey: m[0x134],
|
||||
wtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.wtSessionTicketKey),
|
||||
deviceToken: m[0x322],
|
||||
|
||||
psKeyMap: psKeyMap,
|
||||
pt4TokenMap: pt4TokenMap,
|
||||
}
|
||||
if len(c.PasswordMd5[:]) > 0 {
|
||||
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
||||
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.encryptedA1)
|
||||
if len(decrypted) > 51+16 {
|
||||
@ -109,6 +111,7 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
dr.ReadBytes(51)
|
||||
SystemDeviceInfo.TgtgtKey = dr.ReadBytes(16)
|
||||
}
|
||||
}
|
||||
c.Nickname = nick
|
||||
c.Age = age
|
||||
c.Gender = gender
|
||||
|
@ -56,3 +56,12 @@ func MultiReadSeeker(r ...io.ReadSeeker) io.ReadSeeker {
|
||||
readers: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Select 如果A为nil 将会返回 B 否则返回A
|
||||
// 对应 ?? 语法
|
||||
func Select(a, b []byte) []byte {
|
||||
if a == nil {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user