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:
parent
6b5ba9f9c4
commit
950567e4b7
@ -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())),
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
328
client/global.go
328
client/global.go
@ -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"
|
||||||
|
130
client/internal/auth/auth.go
Normal file
130
client/internal/auth/auth.go
Normal 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
|
||||||
|
}
|
213
client/internal/auth/device.go
Normal file
213
client/internal/auth/device.go
Normal 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"`
|
||||||
|
}
|
28
client/internal/auth/protocol_string.go
Normal file
28
client/internal/auth/protocol_string.go
Normal 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]]
|
||||||
|
}
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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()
|
||||||
|
@ -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 ---
|
||||||
|
Loading…
x
Reference in New Issue
Block a user