1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

refactor: move Device&loginSigInfo to internal/auth

This commit is contained in:
wdvxdr 2021-12-18 15:36:52 +08:00
parent 6b5ba9f9c4
commit 950567e4b7
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
13 changed files with 491 additions and 449 deletions

View File

@ -8,6 +8,7 @@ import (
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/binary/jce"
"github.com/Mrs4s/MiraiGo/client/internal/auth"
"github.com/Mrs4s/MiraiGo/client/internal/codec" "github.com/Mrs4s/MiraiGo/client/internal/codec"
"github.com/Mrs4s/MiraiGo/client/pb" "github.com/Mrs4s/MiraiGo/client/pb"
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352" "github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
@ -111,7 +112,7 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
} }
func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) { func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
watch := genVersionInfo(AndroidWatch) watch := auth.AndroidWatch.Version()
seq := c.nextSeq() seq := c.nextSeq()
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) { req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
w.WriteHex(`0001110000001000000072000000`) // trans header w.WriteHex(`0001110000001000000072000000`) // trans header
@ -138,7 +139,7 @@ func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
} }
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) { func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
watch := genVersionInfo(AndroidWatch) watch := auth.AndroidWatch.Version()
seq := c.nextSeq() seq := c.nextSeq()
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) { req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
w.WriteHex(`0000620000001000000072000000`) // trans header w.WriteHex(`0000620000001000000072000000`) // trans header
@ -313,7 +314,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress)) w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress))
wb, cl := binary.OpenWriterF(func(bw *binary.Writer) { wb, cl := binary.OpenWriterF(func(bw *binary.Writer) {
bw.WriteUInt16(0x106) bw.WriteUInt16(0x106)
bw.WriteBytesShort(c.sigInfo.encryptedA1) bw.WriteBytesShort(c.sigInfo.EncryptedA1)
}) })
w.Write(wb) w.Write(wb)
cl() cl()
@ -336,7 +337,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
)) ))
w.Write(tlv.T142(c.version.ApkId)) w.Write(tlv.T142(c.version.ApkId))
w.Write(tlv.T145(c.deviceInfo.Guid)) w.Write(tlv.T145(c.deviceInfo.Guid))
w.Write(tlv.T16A(c.sigInfo.srmToken)) w.Write(tlv.T16A(c.sigInfo.SrmToken))
w.Write(tlv.T154(seq)) w.Write(tlv.T154(seq))
w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN)) w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN))
w.Write(tlv.T8(2052)) w.Write(tlv.T8(2052))
@ -362,8 +363,8 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
oicq := codec.OICQ{ oicq := codec.OICQ{
Uin: uint32(c.Uin), Uin: uint32(c.Uin),
Command: 0x810, Command: 0x810,
EncryptMethod: crypto.NewEncryptSession(c.sigInfo.t133), EncryptMethod: crypto.NewEncryptSession(c.sigInfo.T133),
Key: c.sigInfo.wtSessionTicketKey, Key: c.sigInfo.WtSessionTicketKey,
Body: req, Body: req,
} }
@ -388,10 +389,10 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
w.WriteUInt16(17) w.WriteUInt16(17)
w.Write(tlv.T100(c.version.SSOVersion, 100, mainSigMap)) w.Write(tlv.T100(c.version.SSOVersion, 100, mainSigMap))
w.Write(tlv.T10A(c.sigInfo.tgt)) w.Write(tlv.T10A(c.sigInfo.TGT))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap)) w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T108(c.ksid)) w.Write(tlv.T108(c.ksid))
h := md5.Sum(c.sigInfo.d2Key) h := md5.Sum(c.sigInfo.D2Key)
w.Write(tlv.T144( w.Write(tlv.T144(
c.deviceInfo.AndroidId, c.deviceInfo.AndroidId,
c.deviceInfo.GenDeviceInfoData(), c.deviceInfo.GenDeviceInfoData(),
@ -405,7 +406,7 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
c.deviceInfo.Brand, c.deviceInfo.Brand,
h[:], h[:],
)) ))
w.Write(tlv.T143(c.sigInfo.d2)) w.Write(tlv.T143(c.sigInfo.D2))
w.Write(tlv.T142(c.version.ApkId)) w.Write(tlv.T142(c.version.ApkId))
w.Write(tlv.T154(seq)) w.Write(tlv.T154(seq))
w.Write(tlv.T18(16, uint32(c.Uin))) w.Write(tlv.T18(16, uint32(c.Uin)))
@ -423,7 +424,7 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
})) }))
// w.Write(tlv.T202(c.deviceInfo.WifiBSSID, c.deviceInfo.WifiSSID)) // w.Write(tlv.T202(c.deviceInfo.WifiBSSID, c.deviceInfo.WifiSSID))
})) }))
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.exchange_emp", c.deviceInfo.IMEI, c.sigInfo.tgt, c.OutGoingPacketSessionId, req, c.ksid) sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.exchange_emp", c.deviceInfo.IMEI, c.sigInfo.TGT, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes) packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
return seq, packet return seq, packet
} }
@ -438,7 +439,7 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
Status: 11, Status: 11,
KickPC: 0, KickPC: 0,
KickWeak: 0, KickWeak: 0,
IOSVersion: int64(c.deviceInfo.Version.Sdk), IOSVersion: int64(c.deviceInfo.Version.SDK),
NetType: 1, NetType: 1,
RegType: 0, RegType: 0,
Guid: c.deviceInfo.Guid, Guid: c.deviceInfo.Guid,
@ -471,8 +472,8 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
Context: make(map[string]string), Context: make(map[string]string),
Status: make(map[string]string), Status: make(map[string]string),
} }
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "StatSvc.register", c.deviceInfo.IMEI, c.sigInfo.tgt, c.OutGoingPacketSessionId, pkt.ToBytes(), c.ksid) sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "StatSvc.register", c.deviceInfo.IMEI, c.sigInfo.TGT, c.OutGoingPacketSessionId, pkt.ToBytes(), c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 1, c.sigInfo.d2Key, sso, c.sigInfo.d2) packet := packets.BuildLoginPacket(c.Uin, 1, c.sigInfo.D2Key, sso, c.sigInfo.D2)
return seq, packet return seq, packet
} }
@ -485,7 +486,7 @@ func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte
KickPC: 0, KickPC: 0,
KickWeak: 0, KickWeak: 0,
Timestamp: time.Now().Unix(), Timestamp: time.Now().Unix(),
IOSVersion: int64(c.deviceInfo.Version.Sdk), IOSVersion: int64(c.deviceInfo.Version.SDK),
NetType: 1, NetType: 1,
RegType: 0, RegType: 0,
Guid: c.deviceInfo.Guid, Guid: c.deviceInfo.Guid,
@ -1069,7 +1070,7 @@ func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
body := &qweb.QWebReq{ body := &qweb.QWebReq{
Seq: proto.Int64(1), Seq: proto.Int64(1),
Qua: proto.String("V1_AND_SQ_8.4.8_1492_YYB_D"), Qua: proto.String("V1_AND_SQ_8.4.8_1492_YYB_D"),
DeviceInfo: proto.String(c.getWebDeviceInfo()), Device: proto.String(c.getWebDeviceInfo()),
BusiBuff: b, BusiBuff: b,
TraceId: proto.String(fmt.Sprintf("%v_%v_%v", c.Uin, time.Now().Format("0102150405"), rand.Int63())), TraceId: proto.String(fmt.Sprintf("%v_%v_%v", c.Uin, time.Now().Format("0102150405"), rand.Int63())),
} }

View File

@ -41,7 +41,7 @@ const (
func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) { func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *incomingPacketInfo) {
c.syncCookie = rsp.SyncCookie c.syncCookie = rsp.SyncCookie
c.pubAccountCookie = rsp.PubAccountCookie c.pubAccountCookie = rsp.PubAccountCookie
c.msgCtrlBuf = rsp.MsgCtrlBuf // c.msgCtrlBuf = rsp.MsgCtrlBuf
if rsp.UinPairMsgs == nil { if rsp.UinPairMsgs == nil {
return return
} }

View File

@ -15,6 +15,7 @@ import (
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/binary/jce"
"github.com/Mrs4s/MiraiGo/client/internal/auth"
"github.com/Mrs4s/MiraiGo/client/internal/highway" "github.com/Mrs4s/MiraiGo/client/internal/highway"
"github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/internal/crypto" "github.com/Mrs4s/MiraiGo/internal/crypto"
@ -58,36 +59,36 @@ type QQClient struct {
servers []*net.TCPAddr servers []*net.TCPAddr
currServerIndex int currServerIndex int
retryTimes int retryTimes int
version *versionInfo version *auth.AppVersion
deviceInfo *DeviceInfo deviceInfo *auth.Device
alive bool alive bool
ecdh *crypto.EncryptECDH ecdh *crypto.EncryptECDH
// tlv cache // tlv cache
t104 []byte t104 []byte
t174 []byte t174 []byte
g []byte g []byte
t402 []byte t402 []byte
t150 []byte randSeed []byte // t403
t149 []byte // rollbackSig []byte
t528 []byte // t149 []byte
t530 []byte // t150 []byte
randSeed []byte // t403 // t528 []byte
rollbackSig []byte // t530 []byte
// sync info // sync info
syncCookie []byte syncCookie []byte
pubAccountCookie []byte pubAccountCookie []byte
msgCtrlBuf []byte
ksid []byte ksid []byte
// msgCtrlBuf []byte
// session info // session info
qwebSeq atomic.Int64 qwebSeq atomic.Int64
sigInfo *loginSigInfo sigInfo *auth.SigInfo
highwaySession *highway.Session highwaySession *highway.Session
dpwd []byte dpwd []byte
timeDiff int64 // pwdFlag bool
pwdFlag bool // timeDiff int64
// address // address
otherSrvAddrs []string otherSrvAddrs []string
@ -110,27 +111,6 @@ type QQClient struct {
groupListLock sync.Mutex groupListLock sync.Mutex
} }
type loginSigInfo struct {
loginBitmap uint64
tgt []byte
tgtKey []byte
srmToken []byte // study room manager | 0x16a
t133 []byte
encryptedA1 []byte
userStKey []byte
userStWebSig []byte
sKey []byte
sKeyExpiredTime int64
d2 []byte
d2Key []byte
wtSessionTicketKey []byte
deviceToken []byte
psKeyMap map[string][]byte
pt4TokenMap map[string][]byte
}
type QiDianAccountInfo struct { type QiDianAccountInfo struct {
MasterUin int64 MasterUin int64
ExtName string ExtName string
@ -201,7 +181,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
RandomKey: make([]byte, 16), RandomKey: make([]byte, 16),
OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B}, OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B},
TCP: &utils.TCPListener{}, TCP: &utils.TCPListener{},
sigInfo: &loginSigInfo{}, sigInfo: &auth.SigInfo{},
eventHandlers: &eventHandlers{}, eventHandlers: &eventHandlers{},
msgSvcCache: utils.NewCache(time.Second * 15), msgSvcCache: utils.NewCache(time.Second * 15),
transCache: utils.NewCache(time.Second * 15), transCache: utils.NewCache(time.Second * 15),
@ -274,8 +254,8 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
return cli return cli
} }
func (c *QQClient) UseDevice(info *DeviceInfo) { func (c *QQClient) UseDevice(info *auth.Device) {
c.version = genVersionInfo(info.Protocol) c.version = info.Protocol.Version()
c.highwaySession.AppID = int32(c.version.AppId) c.highwaySession.AppID = int32(c.version.AppId)
c.ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI)) c.ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
c.deviceInfo = info c.deviceInfo = info
@ -320,13 +300,13 @@ func (c *QQClient) TokenLogin(token []byte) error {
{ {
r := binary.NewReader(token) r := binary.NewReader(token)
c.Uin = r.ReadInt64() c.Uin = r.ReadInt64()
c.sigInfo.d2 = r.ReadBytesShort() c.sigInfo.D2 = r.ReadBytesShort()
c.sigInfo.d2Key = r.ReadBytesShort() c.sigInfo.D2Key = r.ReadBytesShort()
c.sigInfo.tgt = r.ReadBytesShort() c.sigInfo.TGT = r.ReadBytesShort()
c.sigInfo.srmToken = r.ReadBytesShort() c.sigInfo.SrmToken = r.ReadBytesShort()
c.sigInfo.t133 = r.ReadBytesShort() c.sigInfo.T133 = r.ReadBytesShort()
c.sigInfo.encryptedA1 = r.ReadBytesShort() c.sigInfo.EncryptedA1 = r.ReadBytesShort()
c.sigInfo.wtSessionTicketKey = r.ReadBytesShort() c.sigInfo.WtSessionTicketKey = r.ReadBytesShort()
c.OutGoingPacketSessionId = r.ReadBytesShort() c.OutGoingPacketSessionId = r.ReadBytesShort()
// SystemDeviceInfo.TgtgtKey = r.ReadBytesShort() // SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
c.deviceInfo.TgtgtKey = r.ReadBytesShort() c.deviceInfo.TgtgtKey = r.ReadBytesShort()
@ -455,7 +435,7 @@ func (c *QQClient) init(tokenLogin bool) error {
go c.doHeartbeat() go c.doHeartbeat()
} }
_ = c.RefreshStatus() _ = c.RefreshStatus()
if c.version.Protocol == QiDian { if c.version.Protocol == auth.QiDian {
_, _ = c.sendAndWait(c.buildLoginExtraPacket()) // 小登录 _, _ = c.sendAndWait(c.buildLoginExtraPacket()) // 小登录
_, _ = c.sendAndWait(c.buildConnKeyRequestPacket()) // big data key 如果等待 config push 的话时间来不及 _, _ = c.sendAndWait(c.buildConnKeyRequestPacket()) // big data key 如果等待 config push 的话时间来不及
} }
@ -468,13 +448,13 @@ func (c *QQClient) init(tokenLogin bool) error {
func (c *QQClient) GenToken() []byte { func (c *QQClient) GenToken() []byte {
return binary.NewWriterF(func(w *binary.Writer) { return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt64(uint64(c.Uin)) w.WriteUInt64(uint64(c.Uin))
w.WriteBytesShort(c.sigInfo.d2) w.WriteBytesShort(c.sigInfo.D2)
w.WriteBytesShort(c.sigInfo.d2Key) w.WriteBytesShort(c.sigInfo.D2Key)
w.WriteBytesShort(c.sigInfo.tgt) w.WriteBytesShort(c.sigInfo.TGT)
w.WriteBytesShort(c.sigInfo.srmToken) w.WriteBytesShort(c.sigInfo.SrmToken)
w.WriteBytesShort(c.sigInfo.t133) w.WriteBytesShort(c.sigInfo.T133)
w.WriteBytesShort(c.sigInfo.encryptedA1) w.WriteBytesShort(c.sigInfo.EncryptedA1)
w.WriteBytesShort(c.sigInfo.wtSessionTicketKey) w.WriteBytesShort(c.sigInfo.WtSessionTicketKey)
w.WriteBytesShort(c.OutGoingPacketSessionId) w.WriteBytesShort(c.OutGoingPacketSessionId)
w.WriteBytesShort(c.deviceInfo.TgtgtKey) w.WriteBytesShort(c.deviceInfo.TgtgtKey)
}) })
@ -525,7 +505,7 @@ func (c *QQClient) ReloadFriendList() error {
// 当使用普通QQ时: 请求好友列表 // 当使用普通QQ时: 请求好友列表
// 当使用企点QQ时: 请求外部联系人列表 // 当使用企点QQ时: 请求外部联系人列表
func (c *QQClient) GetFriendList() (*FriendListResponse, error) { func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
if c.version.Protocol == QiDian { if c.version.Protocol == auth.QiDian {
rsp, err := c.getQiDianAddressDetailList() rsp, err := c.getQiDianAddressDetailList()
if err != nil { if err != nil {
return nil, err return nil, err
@ -700,11 +680,11 @@ func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
} }
func (c *QQClient) getSKey() string { func (c *QQClient) getSKey() string {
if c.sigInfo.sKeyExpiredTime < time.Now().Unix() && len(c.g) > 0 { if c.sigInfo.SKeyExpiredTime < time.Now().Unix() && len(c.g) > 0 {
c.Debug("skey expired. refresh...") c.Debug("skey expired. refresh...")
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket()) _, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
} }
return string(c.sigInfo.sKey) return string(c.sigInfo.SKey)
} }
func (c *QQClient) getCookies() string { func (c *QQClient) getCookies() string {
@ -714,7 +694,7 @@ func (c *QQClient) getCookies() string {
func (c *QQClient) getCookiesWithDomain(domain string) string { func (c *QQClient) getCookiesWithDomain(domain string) string {
cookie := c.getCookies() cookie := c.getCookies()
if psKey, ok := c.sigInfo.psKeyMap[domain]; ok { if psKey, ok := c.sigInfo.PsKeyMap[domain]; ok {
return fmt.Sprintf("%s p_uin=o%d; p_skey=%s;", cookie, c.Uin, psKey) return fmt.Sprintf("%s p_uin=o%d; p_skey=%s;", cookie, c.Uin, psKey)
} else { } else {
return cookie return cookie

View File

@ -44,9 +44,9 @@ func decodeLoginResponse(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
c.g = h[:] c.g = h[:]
} }
if t == 0 { // login success if t == 0 { // login success
if t150, ok := m[0x150]; ok { // if t150, ok := m[0x150]; ok {
c.t150 = t150 // c.t150 = t150
} // }
if t161, ok := m[0x161]; ok { if t161, ok := m[0x161]; ok {
c.decodeT161(t161) c.decodeT161(t161)
} }
@ -209,7 +209,7 @@ func decodeExchangeEmpResponse(c *QQClient, _ *incomingPacketInfo, payload []byt
c.decodeT119R(m[0x119]) c.decodeT119R(m[0x119])
} }
if cmd == 11 { if cmd == 11 {
h := md5.Sum(c.sigInfo.d2Key) h := md5.Sum(c.sigInfo.D2Key)
c.decodeT119(m[0x119], h[:]) c.decodeT119(m[0x119], h[:])
} }
return nil, nil return nil, nil

View File

@ -4,6 +4,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/binary/jce"
"github.com/Mrs4s/MiraiGo/client/internal/auth"
"github.com/Mrs4s/MiraiGo/message" "github.com/Mrs4s/MiraiGo/message"
) )
@ -22,7 +23,7 @@ type (
UserOnlineStatus int UserOnlineStatus int
ClientProtocol int ClientProtocol = auth.Protocol
LoginResponse struct { LoginResponse struct {
Success bool Success bool
@ -343,12 +344,12 @@ const (
Administrator MemberPermission = 2 Administrator MemberPermission = 2
Member MemberPermission = 3 Member MemberPermission = 3
Unset ClientProtocol = 0 Unset = auth.Unset
AndroidPhone ClientProtocol = 1 AndroidPhone = auth.AndroidPhone
AndroidWatch ClientProtocol = 2 AndroidWatch = auth.AndroidWatch
MacOS ClientProtocol = 3 MacOS = auth.MacOS
QiDian ClientProtocol = 4 QiDian = auth.QiDian
IPad ClientProtocol = 5 IPad = auth.IPad
) )
func (r *UserJoinGroupRequest) Accept() { func (r *UserJoinGroupRequest) Accept() {

View File

@ -3,7 +3,6 @@ package client
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"encoding/json"
"fmt" "fmt"
"math/rand" "math/rand"
"net" "net"
@ -16,7 +15,7 @@ import (
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/binary/jce" "github.com/Mrs4s/MiraiGo/binary/jce"
devinfo "github.com/Mrs4s/MiraiGo/client/pb" "github.com/Mrs4s/MiraiGo/client/internal/auth"
"github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/client/pb/oidb" "github.com/Mrs4s/MiraiGo/client/pb/oidb"
"github.com/Mrs4s/MiraiGo/internal/proto" "github.com/Mrs4s/MiraiGo/internal/proto"
@ -25,97 +24,13 @@ import (
) )
type ( type (
DeviceInfo struct { DeviceInfo = auth.Device
Display []byte Version = auth.OSVersion
Product []byte
Device []byte
Board []byte
Brand []byte
Model []byte
Bootloader []byte
FingerPrint []byte
BootId []byte
ProcVersion []byte
BaseBand []byte
SimInfo []byte
OSType []byte
MacAddress []byte
IpAddress []byte
WifiBSSID []byte
WifiSSID []byte
IMSIMd5 []byte
IMEI string
AndroidId []byte
APN []byte
VendorName []byte
VendorOSName []byte
Guid []byte
TgtgtKey []byte
Protocol ClientProtocol
Version *Version
}
Version struct {
Incremental []byte
Release []byte
CodeName []byte
Sdk uint32
}
DeviceInfoFile struct {
Display string `json:"display"`
Product string `json:"product"`
Device string `json:"device"`
Board string `json:"board"`
Model string `json:"model"`
FingerPrint string `json:"finger_print"`
BootId string `json:"boot_id"`
ProcVersion string `json:"proc_version"`
Protocol int `json:"protocol"` // 0: Pad 1: Phone 2: Watch
IMEI string `json:"imei"`
Brand string `json:"brand"`
Bootloader string `json:"bootloader"`
BaseBand string `json:"base_band"`
Version *VersionFile `json:"version"`
SimInfo string `json:"sim_info"`
OsType string `json:"os_type"`
MacAddress string `json:"mac_address"`
IpAddress []int32 `json:"ip_address"`
WifiBSSID string `json:"wifi_bssid"`
WifiSSID string `json:"wifi_ssid"`
ImsiMd5 string `json:"imsi_md5"`
AndroidId string `json:"android_id"`
Apn string `json:"apn"`
VendorName string `json:"vendor_name"`
VendorOSName string `json:"vendor_os_name"`
}
VersionFile struct {
Incremental string `json:"incremental"`
Release string `json:"release"`
Codename string `json:"codename"`
Sdk uint32 `json:"sdk"`
}
groupMessageBuilder struct { groupMessageBuilder struct {
MessageSlices []*msg.Message MessageSlices []*msg.Message
} }
versionInfo struct {
ApkSign []byte
ApkId string
SortVersionName string
SdkVersion string
AppId uint32
SubAppId uint32
BuildTime uint32
SSOVersion uint32
MiscBitmap uint32
SubSigmap uint32
MainSigMap uint32
Protocol ClientProtocol
}
incomingPacketInfo struct { incomingPacketInfo struct {
CommandName string CommandName string
SequenceId uint16 SequenceId uint16
@ -153,7 +68,7 @@ var SystemDeviceInfo = &DeviceInfo{
Incremental: []byte("5891938"), Incremental: []byte("5891938"),
Release: []byte("10"), Release: []byte("10"),
CodeName: []byte("REL"), CodeName: []byte("REL"),
Sdk: 29, SDK: 29,
}, },
} }
@ -187,237 +102,6 @@ func GenRandomDevice() {
SystemDeviceInfo.GenNewTgtgtKey() SystemDeviceInfo.GenNewTgtgtKey()
} }
func genVersionInfo(p ClientProtocol) *versionInfo {
switch p {
case AndroidPhone: // Dumped by mirai from qq android v8.8.38
return &versionInfo{
ApkId: "com.tencent.mobileqq",
AppId: 537100432,
SubAppId: 537100432,
SortVersionName: "8.8.38",
BuildTime: 1634310940,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.2487",
SSOVersion: 16,
MiscBitmap: 184024956,
SubSigmap: 0x10400,
MainSigMap: 34869472,
Protocol: p,
}
case AndroidWatch:
return &versionInfo{
ApkId: "com.tencent.qqlite",
AppId: 537064446,
SubAppId: 537064446,
SortVersionName: "2.0.5",
BuildTime: 1559564731,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.236",
SSOVersion: 5,
MiscBitmap: 16252796,
SubSigmap: 0x10400,
MainSigMap: 34869472,
Protocol: p,
}
case IPad:
return &versionInfo{
ApkId: "com.tencent.minihd.qq",
AppId: 537097188,
SubAppId: 537097188,
SortVersionName: "8.8.35",
BuildTime: 1595836208,
ApkSign: []byte{170, 57, 120, 244, 31, 217, 111, 249, 145, 74, 102, 158, 24, 100, 116, 199},
SdkVersion: "6.0.0.2433",
SSOVersion: 12,
MiscBitmap: 150470524,
SubSigmap: 66560,
MainSigMap: 1970400,
Protocol: p,
}
case MacOS:
return &versionInfo{
ApkId: "com.tencent.minihd.qq",
AppId: 537064315,
SubAppId: 537064315,
SortVersionName: "5.8.9",
BuildTime: 1595836208,
ApkSign: []byte{170, 57, 120, 244, 31, 217, 111, 249, 145, 74, 102, 158, 24, 100, 116, 199},
SdkVersion: "6.0.0.2433",
SSOVersion: 12,
MiscBitmap: 150470524,
SubSigmap: 66560,
MainSigMap: 1970400,
Protocol: p,
}
case QiDian:
return &versionInfo{
ApkId: "com.tencent.qidian",
AppId: 537061386,
SubAppId: 537036590,
SortVersionName: "3.8.6",
BuildTime: 1556628836,
ApkSign: []byte{160, 30, 236, 171, 133, 233, 227, 186, 43, 15, 106, 21, 140, 133, 92, 41},
SdkVersion: "6.0.0.2365",
SSOVersion: 5,
MiscBitmap: 49807228,
SubSigmap: 66560,
MainSigMap: 34869472,
Protocol: p,
}
}
return nil
}
func (info *DeviceInfo) ToJson() []byte {
f := &DeviceInfoFile{
Display: string(info.Display),
Product: string(info.Product),
Device: string(info.Device),
Board: string(info.Board),
Model: string(info.Model),
FingerPrint: string(info.FingerPrint),
BootId: string(info.BootId),
ProcVersion: string(info.ProcVersion),
IMEI: info.IMEI,
Brand: string(info.Brand),
Bootloader: string(info.Bootloader),
BaseBand: string(info.BaseBand),
AndroidId: string(info.AndroidId),
Version: &VersionFile{
Incremental: string(info.Version.Incremental),
Release: string(info.Version.Release),
Codename: string(info.Version.CodeName),
Sdk: info.Version.Sdk,
},
SimInfo: string(info.SimInfo),
OsType: string(info.OSType),
MacAddress: string(info.MacAddress),
IpAddress: []int32{int32(info.IpAddress[0]), int32(info.IpAddress[1]), int32(info.IpAddress[2]), int32(info.IpAddress[3])},
WifiBSSID: string(info.WifiBSSID),
WifiSSID: string(info.WifiSSID),
ImsiMd5: hex.EncodeToString(info.IMSIMd5),
Apn: string(info.APN),
VendorName: string(info.VendorName),
VendorOSName: string(info.VendorOSName),
Protocol: func() int {
switch info.Protocol {
case AndroidPhone:
return 1
case AndroidWatch:
return 2
case MacOS:
return 3
case QiDian:
return 4
case IPad:
return 5
}
return 0
}(),
}
d, _ := json.Marshal(f)
return d
}
func (info *DeviceInfo) ReadJson(d []byte) error {
var f DeviceInfoFile
if err := json.Unmarshal(d, &f); err != nil {
return errors.Wrap(err, "failed to unmarshal json message")
}
SetIfNotEmpty := func(trg *[]byte, str string) {
if str != "" {
*trg = []byte(str)
}
}
SetIfNotEmpty(&info.Display, f.Display)
SetIfNotEmpty(&info.Product, f.Product)
SetIfNotEmpty(&info.Device, f.Device)
SetIfNotEmpty(&info.Board, f.Board)
SetIfNotEmpty(&info.Brand, f.Brand)
SetIfNotEmpty(&info.Model, f.Model)
SetIfNotEmpty(&info.Bootloader, f.Bootloader)
SetIfNotEmpty(&info.FingerPrint, f.FingerPrint)
SetIfNotEmpty(&info.BootId, f.BootId)
SetIfNotEmpty(&info.ProcVersion, f.ProcVersion)
SetIfNotEmpty(&info.BaseBand, f.BaseBand)
SetIfNotEmpty(&info.SimInfo, f.SimInfo)
SetIfNotEmpty(&info.OSType, f.OsType)
SetIfNotEmpty(&info.MacAddress, f.MacAddress)
if len(f.IpAddress) == 4 {
info.IpAddress = []byte{byte(f.IpAddress[0]), byte(f.IpAddress[1]), byte(f.IpAddress[2]), byte(f.IpAddress[3])}
}
SetIfNotEmpty(&info.WifiBSSID, f.WifiBSSID)
SetIfNotEmpty(&info.WifiSSID, f.WifiSSID)
if len(f.ImsiMd5) != 0 {
imsiMd5, err := hex.DecodeString(f.ImsiMd5)
if err != nil {
info.IMSIMd5 = imsiMd5
}
}
if f.IMEI != "" {
info.IMEI = f.IMEI
}
SetIfNotEmpty(&info.APN, f.Apn)
SetIfNotEmpty(&info.VendorName, f.VendorName)
SetIfNotEmpty(&info.VendorOSName, f.VendorOSName)
SetIfNotEmpty(&info.AndroidId, f.AndroidId)
if f.AndroidId == "" {
info.AndroidId = info.Display // ?
}
switch f.Protocol {
case 1:
info.Protocol = AndroidPhone
case 2:
info.Protocol = AndroidWatch
case 3:
info.Protocol = MacOS
case 4:
info.Protocol = QiDian
case 5:
info.Protocol = IPad
default:
info.Protocol = IPad
}
SystemDeviceInfo.GenNewGuid()
SystemDeviceInfo.GenNewTgtgtKey()
return nil
}
func (info *DeviceInfo) GenNewGuid() {
t := md5.Sum(append(info.AndroidId, info.MacAddress...))
info.Guid = t[:]
}
func (info *DeviceInfo) GenNewTgtgtKey() {
r := make([]byte, 16)
rand.Read(r)
h := md5.New()
h.Write(r)
h.Write(info.Guid)
info.TgtgtKey = h.Sum(nil)
}
func (info *DeviceInfo) GenDeviceInfoData() []byte {
m := &devinfo.DeviceInfo{
Bootloader: string(info.Bootloader),
ProcVersion: string(info.ProcVersion),
Codename: string(info.Version.CodeName),
Incremental: string(info.Version.Incremental),
Fingerprint: string(info.FingerPrint),
BootId: string(info.BootId),
AndroidId: string(info.AndroidId),
BaseBand: string(info.BaseBand),
InnerVersion: string(info.Version.Incremental),
}
data, err := proto.Marshal(m)
if err != nil {
panic(errors.Wrap(err, "failed to unmarshal protobuf message"))
}
return data
}
func GenIMEI() string { func GenIMEI() string {
sum := 0 // the control sum of digits sum := 0 // the control sum of digits
var final strings.Builder var final strings.Builder
@ -442,7 +126,7 @@ func GenIMEI() string {
} }
func getSSOAddress() ([]*net.TCPAddr, error) { func getSSOAddress() ([]*net.TCPAddr, error) {
protocol := genVersionInfo(SystemDeviceInfo.Protocol) protocol := SystemDeviceInfo.Protocol.Version()
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411") key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
payload := jce.NewJceWriter(). // see ServerConfig.d payload := jce.NewJceWriter(). // see ServerConfig.d
WriteInt64(0, 1).WriteInt64(0, 2).WriteByte(1, 3). WriteInt64(0, 1).WriteInt64(0, 2).WriteByte(1, 3).
@ -649,7 +333,7 @@ func (p requestParams) int32(k string) int32 {
func (c *QQClient) getWebDeviceInfo() (i string) { func (c *QQClient) getWebDeviceInfo() (i string) {
qimei := strings.ToLower(utils.RandomString(36)) qimei := strings.ToLower(utils.RandomString(36))
i += fmt.Sprintf("i=%v&imsi=&mac=%v&m=%v&o=%v&", c.deviceInfo.IMEI, utils.B2S(c.deviceInfo.MacAddress), utils.B2S(c.deviceInfo.Device), utils.B2S(c.deviceInfo.Version.Release)) i += fmt.Sprintf("i=%v&imsi=&mac=%v&m=%v&o=%v&", c.deviceInfo.IMEI, utils.B2S(c.deviceInfo.MacAddress), utils.B2S(c.deviceInfo.Device), utils.B2S(c.deviceInfo.Version.Release))
i += fmt.Sprintf("a=%v&sd=0&c64=0&sc=1&p=1080*2210&aid=%v&", c.deviceInfo.Version.Sdk, c.deviceInfo.IMEI) i += fmt.Sprintf("a=%v&sd=0&c64=0&sc=1&p=1080*2210&aid=%v&", c.deviceInfo.Version.SDK, c.deviceInfo.IMEI)
i += fmt.Sprintf("f=%v&mm=%v&cf=%v&cc=%v&", c.deviceInfo.Brand, 5629 /* Total Memory*/, 1725 /* CPU Frequency */, 8 /* CPU Core Count */) i += fmt.Sprintf("f=%v&mm=%v&cf=%v&cc=%v&", c.deviceInfo.Brand, 5629 /* Total Memory*/, 1725 /* CPU Frequency */, 8 /* CPU Core Count */)
i += fmt.Sprintf("qimei=%v&qimei36=%v&", qimei, qimei) i += fmt.Sprintf("qimei=%v&qimei36=%v&", qimei, qimei)
i += "sharpP=1&n=wifi&support_xsj_live=true&client_mod=default&timezone=Asia/Shanghai&material_sdk_version=2.9.0&vh265=null&refreshrate=60" i += "sharpP=1&n=wifi&support_xsj_live=true&client_mod=default&timezone=Asia/Shanghai&material_sdk_version=2.9.0&vh265=null&refreshrate=60"

View File

@ -0,0 +1,130 @@
package auth
//go:generate stringer -type=Protocol -linecomment
type Protocol int
const (
Unset Protocol = iota
AndroidPhone // Android Phone
AndroidWatch // Android Watch
MacOS // MacOS
QiDian // 企点
IPad // iPad
)
type AppVersion struct {
ApkSign []byte
ApkId string
SortVersionName string
SdkVersion string
AppId uint32
SubAppId uint32
BuildTime uint32
SSOVersion uint32
MiscBitmap uint32
SubSigmap uint32
MainSigMap uint32
Protocol Protocol
}
func (p Protocol) Version() *AppVersion {
switch p {
case AndroidPhone: // Dumped by mirai from qq android v8.8.38
return &AppVersion{
ApkId: "com.tencent.mobileqq",
AppId: 537100432,
SubAppId: 537100432,
SortVersionName: "8.8.38",
BuildTime: 1634310940,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.2487",
SSOVersion: 16,
MiscBitmap: 184024956,
SubSigmap: 0x10400,
MainSigMap: 34869472,
Protocol: p,
}
case AndroidWatch:
return &AppVersion{
ApkId: "com.tencent.qqlite",
AppId: 537064446,
SubAppId: 537064446,
SortVersionName: "2.0.5",
BuildTime: 1559564731,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.236",
SSOVersion: 5,
MiscBitmap: 16252796,
SubSigmap: 0x10400,
MainSigMap: 34869472,
Protocol: p,
}
case IPad:
return &AppVersion{
ApkId: "com.tencent.minihd.qq",
AppId: 537097188,
SubAppId: 537097188,
SortVersionName: "8.8.35",
BuildTime: 1595836208,
ApkSign: []byte{170, 57, 120, 244, 31, 217, 111, 249, 145, 74, 102, 158, 24, 100, 116, 199},
SdkVersion: "6.0.0.2433",
SSOVersion: 12,
MiscBitmap: 150470524,
SubSigmap: 66560,
MainSigMap: 1970400,
Protocol: p,
}
case MacOS:
return &AppVersion{
ApkId: "com.tencent.minihd.qq",
AppId: 537064315,
SubAppId: 537064315,
SortVersionName: "5.8.9",
BuildTime: 1595836208,
ApkSign: []byte{170, 57, 120, 244, 31, 217, 111, 249, 145, 74, 102, 158, 24, 100, 116, 199},
SdkVersion: "6.0.0.2433",
SSOVersion: 12,
MiscBitmap: 150470524,
SubSigmap: 66560,
MainSigMap: 1970400,
Protocol: p,
}
case QiDian:
return &AppVersion{
ApkId: "com.tencent.qidian",
AppId: 537061386,
SubAppId: 537036590,
SortVersionName: "3.8.6",
BuildTime: 1556628836,
ApkSign: []byte{160, 30, 236, 171, 133, 233, 227, 186, 43, 15, 106, 21, 140, 133, 92, 41},
SdkVersion: "6.0.0.2365",
SSOVersion: 5,
MiscBitmap: 49807228,
SubSigmap: 66560,
MainSigMap: 34869472,
Protocol: p,
}
}
return nil
}
type SigInfo struct {
LoginBitmap uint64
TGT []byte
TGTKey []byte
SrmToken []byte // study room manager | 0x16a
T133 []byte
EncryptedA1 []byte
UserStKey []byte
UserStWebSig []byte
SKey []byte
SKeyExpiredTime int64
D2 []byte
D2Key []byte
WtSessionTicketKey []byte
DeviceToken []byte
PsKeyMap map[string][]byte
Pt4TokenMap map[string][]byte
}

View File

@ -0,0 +1,213 @@
package auth
import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"math/rand"
"github.com/pkg/errors"
"github.com/Mrs4s/MiraiGo/client/pb"
"github.com/Mrs4s/MiraiGo/internal/proto"
)
type OSVersion struct {
Incremental []byte
Release []byte
CodeName []byte
SDK uint32
}
type Device struct {
Display []byte
Product []byte
Device []byte
Board []byte
Brand []byte
Model []byte
Bootloader []byte
FingerPrint []byte
BootId []byte
ProcVersion []byte
BaseBand []byte
SimInfo []byte
OSType []byte
MacAddress []byte
IpAddress []byte
WifiBSSID []byte
WifiSSID []byte
IMSIMd5 []byte
IMEI string
AndroidId []byte
APN []byte
VendorName []byte
VendorOSName []byte
Guid []byte
TgtgtKey []byte
Protocol Protocol
Version *OSVersion
}
func (info *Device) ToJson() []byte {
f := &deviceFile{
Display: string(info.Display),
Product: string(info.Product),
Device: string(info.Device),
Board: string(info.Board),
Model: string(info.Model),
FingerPrint: string(info.FingerPrint),
BootId: string(info.BootId),
ProcVersion: string(info.ProcVersion),
IMEI: info.IMEI,
Brand: string(info.Brand),
Bootloader: string(info.Bootloader),
BaseBand: string(info.BaseBand),
AndroidId: string(info.AndroidId),
Version: &osVersionFile{
Incremental: string(info.Version.Incremental),
Release: string(info.Version.Release),
Codename: string(info.Version.CodeName),
Sdk: info.Version.SDK,
},
SimInfo: string(info.SimInfo),
OsType: string(info.OSType),
MacAddress: string(info.MacAddress),
IpAddress: []int32{int32(info.IpAddress[0]), int32(info.IpAddress[1]), int32(info.IpAddress[2]), int32(info.IpAddress[3])},
WifiBSSID: string(info.WifiBSSID),
WifiSSID: string(info.WifiSSID),
ImsiMd5: hex.EncodeToString(info.IMSIMd5),
Apn: string(info.APN),
VendorName: string(info.VendorName),
VendorOSName: string(info.VendorOSName),
Protocol: int(info.Protocol),
}
d, _ := json.Marshal(f)
return d
}
func (info *Device) ReadJson(d []byte) error {
var f deviceFile
if err := json.Unmarshal(d, &f); err != nil {
return errors.Wrap(err, "failed to unmarshal json message")
}
setIfNotEmpty := func(trg *[]byte, str string) {
if str != "" {
*trg = []byte(str)
}
}
setIfNotEmpty(&info.Display, f.Display)
setIfNotEmpty(&info.Product, f.Product)
setIfNotEmpty(&info.Device, f.Device)
setIfNotEmpty(&info.Board, f.Board)
setIfNotEmpty(&info.Brand, f.Brand)
setIfNotEmpty(&info.Model, f.Model)
setIfNotEmpty(&info.Bootloader, f.Bootloader)
setIfNotEmpty(&info.FingerPrint, f.FingerPrint)
setIfNotEmpty(&info.BootId, f.BootId)
setIfNotEmpty(&info.ProcVersion, f.ProcVersion)
setIfNotEmpty(&info.BaseBand, f.BaseBand)
setIfNotEmpty(&info.SimInfo, f.SimInfo)
setIfNotEmpty(&info.OSType, f.OsType)
setIfNotEmpty(&info.MacAddress, f.MacAddress)
if len(f.IpAddress) == 4 {
info.IpAddress = []byte{byte(f.IpAddress[0]), byte(f.IpAddress[1]), byte(f.IpAddress[2]), byte(f.IpAddress[3])}
}
setIfNotEmpty(&info.WifiBSSID, f.WifiBSSID)
setIfNotEmpty(&info.WifiSSID, f.WifiSSID)
if len(f.ImsiMd5) != 0 {
imsiMd5, err := hex.DecodeString(f.ImsiMd5)
if err != nil {
info.IMSIMd5 = imsiMd5
}
}
if f.IMEI != "" {
info.IMEI = f.IMEI
}
setIfNotEmpty(&info.APN, f.Apn)
setIfNotEmpty(&info.VendorName, f.VendorName)
setIfNotEmpty(&info.VendorOSName, f.VendorOSName)
setIfNotEmpty(&info.AndroidId, f.AndroidId)
if f.AndroidId == "" {
info.AndroidId = info.Display // ?
}
switch f.Protocol {
case 1, 2, 3, 4, 5:
info.Protocol = Protocol(f.Protocol)
default:
info.Protocol = IPad
}
info.GenNewGuid()
info.GenNewTgtgtKey()
return nil
}
func (info *Device) GenNewGuid() {
t := md5.Sum(append(info.AndroidId, info.MacAddress...))
info.Guid = t[:]
}
func (info *Device) GenNewTgtgtKey() {
r := make([]byte, 16)
rand.Read(r)
h := md5.New()
h.Write(r)
h.Write(info.Guid)
info.TgtgtKey = h.Sum(nil)
}
func (info *Device) GenDeviceInfoData() []byte {
m := &pb.DeviceInfo{
Bootloader: string(info.Bootloader),
ProcVersion: string(info.ProcVersion),
Codename: string(info.Version.CodeName),
Incremental: string(info.Version.Incremental),
Fingerprint: string(info.FingerPrint),
BootId: string(info.BootId),
AndroidId: string(info.AndroidId),
BaseBand: string(info.BaseBand),
InnerVersion: string(info.Version.Incremental),
}
data, err := proto.Marshal(m)
if err != nil {
panic(errors.Wrap(err, "failed to unmarshal protobuf message"))
}
return data
}
type deviceFile struct {
Display string `json:"display"`
Product string `json:"product"`
Device string `json:"device"`
Board string `json:"board"`
Model string `json:"model"`
FingerPrint string `json:"finger_print"`
BootId string `json:"boot_id"`
ProcVersion string `json:"proc_version"`
Protocol int `json:"protocol"` // 0: Pad 1: Phone 2: Watch
IMEI string `json:"imei"`
Brand string `json:"brand"`
Bootloader string `json:"bootloader"`
BaseBand string `json:"base_band"`
Version *osVersionFile `json:"version"`
SimInfo string `json:"sim_info"`
OsType string `json:"os_type"`
MacAddress string `json:"mac_address"`
IpAddress []int32 `json:"ip_address"`
WifiBSSID string `json:"wifi_bssid"`
WifiSSID string `json:"wifi_ssid"`
ImsiMd5 string `json:"imsi_md5"`
AndroidId string `json:"android_id"`
Apn string `json:"apn"`
VendorName string `json:"vendor_name"`
VendorOSName string `json:"vendor_os_name"`
}
type osVersionFile struct {
Incremental string `json:"incremental"`
Release string `json:"release"`
Codename string `json:"codename"`
Sdk uint32 `json:"sdk"`
}

View File

@ -0,0 +1,28 @@
// Code generated by "stringer -type=Protocol -linecomment"; DO NOT EDIT.
package auth
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Unset-0]
_ = x[AndroidPhone-1]
_ = x[AndroidWatch-2]
_ = x[MacOS-3]
_ = x[QiDian-4]
_ = x[IPad-5]
}
const _Protocol_name = "UnsetAndroid PhoneAndroid WatchMacOS企点iPad"
var _Protocol_index = [...]uint8{0, 5, 18, 31, 36, 42, 46}
func (i Protocol) String() string {
if i < 0 || i >= Protocol(len(_Protocol_index)-1) {
return "Protocol(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Protocol_name[_Protocol_index[i]:_Protocol_index[i+1]]
}

View File

@ -42,7 +42,7 @@ type (
) )
func (c *QQClient) getGtk(domain string) int { func (c *QQClient) getGtk(domain string) int {
if psKey, ok := c.sigInfo.psKeyMap[domain]; ok { if psKey, ok := c.sigInfo.PsKeyMap[domain]; ok {
accu := 5381 accu := 5381
for _, b := range psKey { for _, b := range psKey {
accu = accu + (accu << 5) + int(b) accu = accu + (accu << 5) + int(b)

View File

@ -290,7 +290,7 @@ func (c *QQClient) netLoop() {
continue continue
} }
data, _ := c.TCP.ReadBytes(int(l) - 4) data, _ := c.TCP.ReadBytes(int(l) - 4)
pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.d2Key) pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.D2Key)
if err != nil { if err != nil {
c.Error("parse incoming packet error: %v", err) c.Error("parse incoming packet error: %v", err)
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) { if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
@ -305,7 +305,7 @@ func (c *QQClient) netLoop() {
continue continue
} }
if pkt.Flag2 == 2 { if pkt.Flag2 == 2 {
pkt.Payload, err = pkt.DecryptPayload(c.ecdh.InitialShareKey, c.RandomKey, c.sigInfo.wtSessionTicketKey) pkt.Payload, err = pkt.DecryptPayload(c.ecdh.InitialShareKey, c.RandomKey, c.sigInfo.WtSessionTicketKey)
if err != nil { if err != nil {
c.Error("decrypt payload error: %v", err) c.Error("decrypt payload error: %v", err)
if errors.Is(err, packets.ErrUnknownFlag) { if errors.Is(err, packets.ErrUnknownFlag) {

View File

@ -26,7 +26,7 @@ func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
EncryptType: 1, EncryptType: 1,
SessionID: c.OutGoingPacketSessionId, SessionID: c.OutGoingPacketSessionId,
ExtraData: EmptyBytes, ExtraData: EmptyBytes,
Key: c.sigInfo.d2Key, Key: c.sigInfo.D2Key,
Body: body, Body: body,
} }
return seq, req.Encode() return seq, req.Encode()
@ -41,7 +41,7 @@ func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []b
EncryptType: 1, EncryptType: 1,
SessionID: c.OutGoingPacketSessionId, SessionID: c.OutGoingPacketSessionId,
ExtraData: EmptyBytes, ExtraData: EmptyBytes,
Key: c.sigInfo.d2Key, Key: c.sigInfo.D2Key,
Body: body, Body: body,
} }
return req.Encode() return req.Encode()

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/Mrs4s/MiraiGo/client/internal/auth"
"github.com/Mrs4s/MiraiGo/utils" "github.com/Mrs4s/MiraiGo/utils"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
@ -13,12 +14,14 @@ import (
// --- tlv decoders for qq client --- // --- tlv decoders for qq client ---
func (c *QQClient) decodeT161(data []byte) { func (c *QQClient) decodeT161(data []byte) {
reader := binary.NewReader(data) /*
reader.ReadBytes(2) reader := binary.NewReader(data)
t := reader.ReadTlvMap(2) reader.ReadBytes(2)
if t172, ok := t[0x172]; ok { t := reader.ReadTlvMap(2)
c.rollbackSig = t172 if t172, ok := t[0x172]; ok {
} c.rollbackSig = t172
}
*/
} }
func (c *QQClient) decodeT119(data, ek []byte) { func (c *QQClient) decodeT119(data, ek []byte) {
@ -32,12 +35,14 @@ func (c *QQClient) decodeT119(data, ek []byte) {
if t113, ok := m[0x113]; ok { if t113, ok := m[0x113]; ok {
c.decodeT113(t113) c.decodeT113(t113)
} }
if t528, ok := m[0x528]; ok { /*
c.t528 = t528 if t528, ok := m[0x528]; ok {
} c.t528 = t528
if t530, ok := m[0x530]; ok { }
c.t530 = t530 if t530, ok := m[0x530]; ok {
} c.t530 = t530
}
*/
if t108, ok := m[0x108]; ok { if t108, ok := m[0x108]; ok {
c.ksid = t108 c.ksid = t108
} }
@ -85,28 +90,28 @@ func (c *QQClient) decodeT119(data, ek []byte) {
// readT138(t138) // chg time // readT138(t138) // chg time
} }
c.sigInfo = &loginSigInfo{ c.sigInfo = &auth.SigInfo{
loginBitmap: 0, LoginBitmap: 0,
srmToken: utils.Select(m[0x16a], c.sigInfo.srmToken), SrmToken: utils.Select(m[0x16a], c.sigInfo.SrmToken),
t133: utils.Select(m[0x133], c.sigInfo.t133), T133: utils.Select(m[0x133], c.sigInfo.T133),
encryptedA1: utils.Select(m[0x106], c.sigInfo.encryptedA1), EncryptedA1: utils.Select(m[0x106], c.sigInfo.EncryptedA1),
tgt: m[0x10a], TGT: m[0x10a],
tgtKey: m[0x10d], TGTKey: m[0x10d],
userStKey: m[0x10e], UserStKey: m[0x10e],
userStWebSig: m[0x103], UserStWebSig: m[0x103],
sKey: m[0x120], SKey: m[0x120],
sKeyExpiredTime: time.Now().Unix() + 21600, SKeyExpiredTime: time.Now().Unix() + 21600,
d2: m[0x143], D2: m[0x143],
d2Key: m[0x305], D2Key: m[0x305],
wtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.wtSessionTicketKey), WtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.WtSessionTicketKey),
deviceToken: m[0x322], DeviceToken: m[0x322],
psKeyMap: psKeyMap, PsKeyMap: psKeyMap,
pt4TokenMap: pt4TokenMap, Pt4TokenMap: pt4TokenMap,
} }
if len(c.PasswordMd5[:]) > 0 { 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)) })...)) 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) decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.EncryptedA1)
if len(decrypted) > 51+16 { if len(decrypted) > 51+16 {
dr := binary.NewReader(decrypted) dr := binary.NewReader(decrypted)
dr.ReadBytes(51) dr.ReadBytes(51)
@ -125,9 +130,9 @@ func (c *QQClient) decodeT119R(data []byte) {
reader.ReadBytes(2) reader.ReadBytes(2)
m := reader.ReadTlvMap(2) m := reader.ReadTlvMap(2)
if t120, ok := m[0x120]; ok { if t120, ok := m[0x120]; ok {
c.sigInfo.sKey = t120 c.sigInfo.SKey = t120
c.sigInfo.sKeyExpiredTime = time.Now().Unix() + 21600 c.sigInfo.SKeyExpiredTime = time.Now().Unix() + 21600
c.Debug("skey updated: %v", c.sigInfo.sKey) c.Debug("skey updated: %v", c.sigInfo.SKey)
} }
if t11a, ok := m[0x11a]; ok { if t11a, ok := m[0x11a]; ok {
c.Nickname, c.Age, c.Gender = readT11A(t11a) c.Nickname, c.Age, c.Gender = readT11A(t11a)
@ -138,8 +143,8 @@ func (c *QQClient) decodeT119R(data []byte) {
func (c *QQClient) decodeT130(data []byte) { func (c *QQClient) decodeT130(data []byte) {
reader := binary.NewReader(data) reader := binary.NewReader(data)
reader.ReadBytes(2) reader.ReadBytes(2)
c.timeDiff = int64(reader.ReadInt32()) - time.Now().Unix() // c.timeDiff = int64(reader.ReadInt32()) - time.Now().Unix()
c.t149 = reader.ReadBytes(4) // c.t149 = reader.ReadBytes(4)
} }
func (c *QQClient) decodeT113(data []byte) { func (c *QQClient) decodeT113(data []byte) {
@ -149,7 +154,7 @@ func (c *QQClient) decodeT113(data []byte) {
} }
func (c *QQClient) decodeT186(data []byte) { func (c *QQClient) decodeT186(data []byte) {
c.pwdFlag = data[1] == 1 // c.pwdFlag = data[1] == 1
} }
// --- tlv readers --- // --- tlv readers ---