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/jce"
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/codec"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
||||
@ -111,7 +112,7 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
|
||||
}
|
||||
|
||||
func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
|
||||
watch := genVersionInfo(AndroidWatch)
|
||||
watch := auth.AndroidWatch.Version()
|
||||
seq := c.nextSeq()
|
||||
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteHex(`0001110000001000000072000000`) // trans header
|
||||
@ -138,7 +139,7 @@ func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
|
||||
}
|
||||
|
||||
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
|
||||
watch := genVersionInfo(AndroidWatch)
|
||||
watch := auth.AndroidWatch.Version()
|
||||
seq := c.nextSeq()
|
||||
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
|
||||
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))
|
||||
wb, cl := binary.OpenWriterF(func(bw *binary.Writer) {
|
||||
bw.WriteUInt16(0x106)
|
||||
bw.WriteBytesShort(c.sigInfo.encryptedA1)
|
||||
bw.WriteBytesShort(c.sigInfo.EncryptedA1)
|
||||
})
|
||||
w.Write(wb)
|
||||
cl()
|
||||
@ -336,7 +337,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||
))
|
||||
w.Write(tlv.T142(c.version.ApkId))
|
||||
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.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN))
|
||||
w.Write(tlv.T8(2052))
|
||||
@ -362,8 +363,8 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||
oicq := codec.OICQ{
|
||||
Uin: uint32(c.Uin),
|
||||
Command: 0x810,
|
||||
EncryptMethod: crypto.NewEncryptSession(c.sigInfo.t133),
|
||||
Key: c.sigInfo.wtSessionTicketKey,
|
||||
EncryptMethod: crypto.NewEncryptSession(c.sigInfo.T133),
|
||||
Key: c.sigInfo.WtSessionTicketKey,
|
||||
Body: req,
|
||||
}
|
||||
|
||||
@ -388,10 +389,10 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
|
||||
w.WriteUInt16(17)
|
||||
|
||||
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.T108(c.ksid))
|
||||
h := md5.Sum(c.sigInfo.d2Key)
|
||||
h := md5.Sum(c.sigInfo.D2Key)
|
||||
w.Write(tlv.T144(
|
||||
c.deviceInfo.AndroidId,
|
||||
c.deviceInfo.GenDeviceInfoData(),
|
||||
@ -405,7 +406,7 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
|
||||
c.deviceInfo.Brand,
|
||||
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.T154(seq))
|
||||
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))
|
||||
}))
|
||||
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)
|
||||
return seq, packet
|
||||
}
|
||||
@ -438,7 +439,7 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
||||
Status: 11,
|
||||
KickPC: 0,
|
||||
KickWeak: 0,
|
||||
IOSVersion: int64(c.deviceInfo.Version.Sdk),
|
||||
IOSVersion: int64(c.deviceInfo.Version.SDK),
|
||||
NetType: 1,
|
||||
RegType: 0,
|
||||
Guid: c.deviceInfo.Guid,
|
||||
@ -471,8 +472,8 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
||||
Context: 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)
|
||||
packet := packets.BuildLoginPacket(c.Uin, 1, c.sigInfo.d2Key, sso, c.sigInfo.d2)
|
||||
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)
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
@ -485,7 +486,7 @@ func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte
|
||||
KickPC: 0,
|
||||
KickWeak: 0,
|
||||
Timestamp: time.Now().Unix(),
|
||||
IOSVersion: int64(c.deviceInfo.Version.Sdk),
|
||||
IOSVersion: int64(c.deviceInfo.Version.SDK),
|
||||
NetType: 1,
|
||||
RegType: 0,
|
||||
Guid: c.deviceInfo.Guid,
|
||||
@ -1069,7 +1070,7 @@ func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
|
||||
body := &qweb.QWebReq{
|
||||
Seq: proto.Int64(1),
|
||||
Qua: proto.String("V1_AND_SQ_8.4.8_1492_YYB_D"),
|
||||
DeviceInfo: proto.String(c.getWebDeviceInfo()),
|
||||
Device: proto.String(c.getWebDeviceInfo()),
|
||||
BusiBuff: b,
|
||||
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) {
|
||||
c.syncCookie = rsp.SyncCookie
|
||||
c.pubAccountCookie = rsp.PubAccountCookie
|
||||
c.msgCtrlBuf = rsp.MsgCtrlBuf
|
||||
// c.msgCtrlBuf = rsp.MsgCtrlBuf
|
||||
if rsp.UinPairMsgs == nil {
|
||||
return
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"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/pb/msg"
|
||||
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
||||
@ -58,36 +59,36 @@ type QQClient struct {
|
||||
servers []*net.TCPAddr
|
||||
currServerIndex int
|
||||
retryTimes int
|
||||
version *versionInfo
|
||||
deviceInfo *DeviceInfo
|
||||
version *auth.AppVersion
|
||||
deviceInfo *auth.Device
|
||||
alive bool
|
||||
ecdh *crypto.EncryptECDH
|
||||
|
||||
// tlv cache
|
||||
t104 []byte
|
||||
t174 []byte
|
||||
g []byte
|
||||
t402 []byte
|
||||
t150 []byte
|
||||
t149 []byte
|
||||
t528 []byte
|
||||
t530 []byte
|
||||
randSeed []byte // t403
|
||||
rollbackSig []byte
|
||||
t104 []byte
|
||||
t174 []byte
|
||||
g []byte
|
||||
t402 []byte
|
||||
randSeed []byte // t403
|
||||
// rollbackSig []byte
|
||||
// t149 []byte
|
||||
// t150 []byte
|
||||
// t528 []byte
|
||||
// t530 []byte
|
||||
|
||||
// sync info
|
||||
syncCookie []byte
|
||||
pubAccountCookie []byte
|
||||
msgCtrlBuf []byte
|
||||
ksid []byte
|
||||
// msgCtrlBuf []byte
|
||||
|
||||
// session info
|
||||
qwebSeq atomic.Int64
|
||||
sigInfo *loginSigInfo
|
||||
sigInfo *auth.SigInfo
|
||||
highwaySession *highway.Session
|
||||
dpwd []byte
|
||||
timeDiff int64
|
||||
pwdFlag bool
|
||||
// pwdFlag bool
|
||||
// timeDiff int64
|
||||
|
||||
// address
|
||||
otherSrvAddrs []string
|
||||
@ -110,27 +111,6 @@ type QQClient struct {
|
||||
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 {
|
||||
MasterUin int64
|
||||
ExtName string
|
||||
@ -201,7 +181,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
||||
RandomKey: make([]byte, 16),
|
||||
OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B},
|
||||
TCP: &utils.TCPListener{},
|
||||
sigInfo: &loginSigInfo{},
|
||||
sigInfo: &auth.SigInfo{},
|
||||
eventHandlers: &eventHandlers{},
|
||||
msgSvcCache: 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
|
||||
}
|
||||
|
||||
func (c *QQClient) UseDevice(info *DeviceInfo) {
|
||||
c.version = genVersionInfo(info.Protocol)
|
||||
func (c *QQClient) UseDevice(info *auth.Device) {
|
||||
c.version = info.Protocol.Version()
|
||||
c.highwaySession.AppID = int32(c.version.AppId)
|
||||
c.ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
|
||||
c.deviceInfo = info
|
||||
@ -320,13 +300,13 @@ func (c *QQClient) TokenLogin(token []byte) error {
|
||||
{
|
||||
r := binary.NewReader(token)
|
||||
c.Uin = r.ReadInt64()
|
||||
c.sigInfo.d2 = r.ReadBytesShort()
|
||||
c.sigInfo.d2Key = r.ReadBytesShort()
|
||||
c.sigInfo.tgt = r.ReadBytesShort()
|
||||
c.sigInfo.srmToken = r.ReadBytesShort()
|
||||
c.sigInfo.t133 = r.ReadBytesShort()
|
||||
c.sigInfo.encryptedA1 = r.ReadBytesShort()
|
||||
c.sigInfo.wtSessionTicketKey = r.ReadBytesShort()
|
||||
c.sigInfo.D2 = r.ReadBytesShort()
|
||||
c.sigInfo.D2Key = r.ReadBytesShort()
|
||||
c.sigInfo.TGT = r.ReadBytesShort()
|
||||
c.sigInfo.SrmToken = r.ReadBytesShort()
|
||||
c.sigInfo.T133 = r.ReadBytesShort()
|
||||
c.sigInfo.EncryptedA1 = r.ReadBytesShort()
|
||||
c.sigInfo.WtSessionTicketKey = r.ReadBytesShort()
|
||||
c.OutGoingPacketSessionId = r.ReadBytesShort()
|
||||
// SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||
c.deviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||
@ -455,7 +435,7 @@ func (c *QQClient) init(tokenLogin bool) error {
|
||||
go c.doHeartbeat()
|
||||
}
|
||||
_ = c.RefreshStatus()
|
||||
if c.version.Protocol == QiDian {
|
||||
if c.version.Protocol == auth.QiDian {
|
||||
_, _ = c.sendAndWait(c.buildLoginExtraPacket()) // 小登录
|
||||
_, _ = 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 {
|
||||
return binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt64(uint64(c.Uin))
|
||||
w.WriteBytesShort(c.sigInfo.d2)
|
||||
w.WriteBytesShort(c.sigInfo.d2Key)
|
||||
w.WriteBytesShort(c.sigInfo.tgt)
|
||||
w.WriteBytesShort(c.sigInfo.srmToken)
|
||||
w.WriteBytesShort(c.sigInfo.t133)
|
||||
w.WriteBytesShort(c.sigInfo.encryptedA1)
|
||||
w.WriteBytesShort(c.sigInfo.wtSessionTicketKey)
|
||||
w.WriteBytesShort(c.sigInfo.D2)
|
||||
w.WriteBytesShort(c.sigInfo.D2Key)
|
||||
w.WriteBytesShort(c.sigInfo.TGT)
|
||||
w.WriteBytesShort(c.sigInfo.SrmToken)
|
||||
w.WriteBytesShort(c.sigInfo.T133)
|
||||
w.WriteBytesShort(c.sigInfo.EncryptedA1)
|
||||
w.WriteBytesShort(c.sigInfo.WtSessionTicketKey)
|
||||
w.WriteBytesShort(c.OutGoingPacketSessionId)
|
||||
w.WriteBytesShort(c.deviceInfo.TgtgtKey)
|
||||
})
|
||||
@ -525,7 +505,7 @@ func (c *QQClient) ReloadFriendList() error {
|
||||
// 当使用普通QQ时: 请求好友列表
|
||||
// 当使用企点QQ时: 请求外部联系人列表
|
||||
func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
|
||||
if c.version.Protocol == QiDian {
|
||||
if c.version.Protocol == auth.QiDian {
|
||||
rsp, err := c.getQiDianAddressDetailList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -700,11 +680,11 @@ func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
|
||||
}
|
||||
|
||||
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.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
|
||||
}
|
||||
return string(c.sigInfo.sKey)
|
||||
return string(c.sigInfo.SKey)
|
||||
}
|
||||
|
||||
func (c *QQClient) getCookies() string {
|
||||
@ -714,7 +694,7 @@ func (c *QQClient) getCookies() string {
|
||||
func (c *QQClient) getCookiesWithDomain(domain string) string {
|
||||
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)
|
||||
} else {
|
||||
return cookie
|
||||
|
@ -44,9 +44,9 @@ func decodeLoginResponse(c *QQClient, _ *incomingPacketInfo, payload []byte) (in
|
||||
c.g = h[:]
|
||||
}
|
||||
if t == 0 { // login success
|
||||
if t150, ok := m[0x150]; ok {
|
||||
c.t150 = t150
|
||||
}
|
||||
// if t150, ok := m[0x150]; ok {
|
||||
// c.t150 = t150
|
||||
// }
|
||||
if t161, ok := m[0x161]; ok {
|
||||
c.decodeT161(t161)
|
||||
}
|
||||
@ -209,7 +209,7 @@ func decodeExchangeEmpResponse(c *QQClient, _ *incomingPacketInfo, payload []byt
|
||||
c.decodeT119R(m[0x119])
|
||||
}
|
||||
if cmd == 11 {
|
||||
h := md5.Sum(c.sigInfo.d2Key)
|
||||
h := md5.Sum(c.sigInfo.D2Key)
|
||||
c.decodeT119(m[0x119], h[:])
|
||||
}
|
||||
return nil, nil
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
)
|
||||
|
||||
@ -22,7 +23,7 @@ type (
|
||||
|
||||
UserOnlineStatus int
|
||||
|
||||
ClientProtocol int
|
||||
ClientProtocol = auth.Protocol
|
||||
|
||||
LoginResponse struct {
|
||||
Success bool
|
||||
@ -343,12 +344,12 @@ const (
|
||||
Administrator MemberPermission = 2
|
||||
Member MemberPermission = 3
|
||||
|
||||
Unset ClientProtocol = 0
|
||||
AndroidPhone ClientProtocol = 1
|
||||
AndroidWatch ClientProtocol = 2
|
||||
MacOS ClientProtocol = 3
|
||||
QiDian ClientProtocol = 4
|
||||
IPad ClientProtocol = 5
|
||||
Unset = auth.Unset
|
||||
AndroidPhone = auth.AndroidPhone
|
||||
AndroidWatch = auth.AndroidWatch
|
||||
MacOS = auth.MacOS
|
||||
QiDian = auth.QiDian
|
||||
IPad = auth.IPad
|
||||
)
|
||||
|
||||
func (r *UserJoinGroupRequest) Accept() {
|
||||
|
328
client/global.go
328
client/global.go
@ -3,7 +3,6 @@ package client
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"net"
|
||||
@ -16,7 +15,7 @@ import (
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"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/oidb"
|
||||
"github.com/Mrs4s/MiraiGo/internal/proto"
|
||||
@ -25,97 +24,13 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
DeviceInfo 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 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"`
|
||||
}
|
||||
DeviceInfo = auth.Device
|
||||
Version = auth.OSVersion
|
||||
|
||||
groupMessageBuilder struct {
|
||||
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 {
|
||||
CommandName string
|
||||
SequenceId uint16
|
||||
@ -153,7 +68,7 @@ var SystemDeviceInfo = &DeviceInfo{
|
||||
Incremental: []byte("5891938"),
|
||||
Release: []byte("10"),
|
||||
CodeName: []byte("REL"),
|
||||
Sdk: 29,
|
||||
SDK: 29,
|
||||
},
|
||||
}
|
||||
|
||||
@ -187,237 +102,6 @@ func GenRandomDevice() {
|
||||
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 {
|
||||
sum := 0 // the control sum of digits
|
||||
var final strings.Builder
|
||||
@ -442,7 +126,7 @@ func GenIMEI() string {
|
||||
}
|
||||
|
||||
func getSSOAddress() ([]*net.TCPAddr, error) {
|
||||
protocol := genVersionInfo(SystemDeviceInfo.Protocol)
|
||||
protocol := SystemDeviceInfo.Protocol.Version()
|
||||
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
|
||||
payload := jce.NewJceWriter(). // see ServerConfig.d
|
||||
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) {
|
||||
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("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("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"
|
||||
|
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 {
|
||||
if psKey, ok := c.sigInfo.psKeyMap[domain]; ok {
|
||||
if psKey, ok := c.sigInfo.PsKeyMap[domain]; ok {
|
||||
accu := 5381
|
||||
for _, b := range psKey {
|
||||
accu = accu + (accu << 5) + int(b)
|
||||
|
@ -290,7 +290,7 @@ func (c *QQClient) netLoop() {
|
||||
continue
|
||||
}
|
||||
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 {
|
||||
c.Error("parse incoming packet error: %v", err)
|
||||
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
|
||||
@ -305,7 +305,7 @@ func (c *QQClient) netLoop() {
|
||||
continue
|
||||
}
|
||||
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 {
|
||||
c.Error("decrypt payload error: %v", err)
|
||||
if errors.Is(err, packets.ErrUnknownFlag) {
|
||||
|
@ -26,7 +26,7 @@ func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
|
||||
EncryptType: 1,
|
||||
SessionID: c.OutGoingPacketSessionId,
|
||||
ExtraData: EmptyBytes,
|
||||
Key: c.sigInfo.d2Key,
|
||||
Key: c.sigInfo.D2Key,
|
||||
Body: body,
|
||||
}
|
||||
return seq, req.Encode()
|
||||
@ -41,7 +41,7 @@ func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []b
|
||||
EncryptType: 1,
|
||||
SessionID: c.OutGoingPacketSessionId,
|
||||
ExtraData: EmptyBytes,
|
||||
Key: c.sigInfo.d2Key,
|
||||
Key: c.sigInfo.D2Key,
|
||||
Body: body,
|
||||
}
|
||||
return req.Encode()
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
||||
"github.com/Mrs4s/MiraiGo/utils"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
@ -13,12 +14,14 @@ import (
|
||||
// --- tlv decoders for qq client ---
|
||||
|
||||
func (c *QQClient) decodeT161(data []byte) {
|
||||
reader := binary.NewReader(data)
|
||||
reader.ReadBytes(2)
|
||||
t := reader.ReadTlvMap(2)
|
||||
if t172, ok := t[0x172]; ok {
|
||||
c.rollbackSig = t172
|
||||
}
|
||||
/*
|
||||
reader := binary.NewReader(data)
|
||||
reader.ReadBytes(2)
|
||||
t := reader.ReadTlvMap(2)
|
||||
if t172, ok := t[0x172]; ok {
|
||||
c.rollbackSig = t172
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
@ -32,12 +35,14 @@ func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
if t113, ok := m[0x113]; ok {
|
||||
c.decodeT113(t113)
|
||||
}
|
||||
if t528, ok := m[0x528]; ok {
|
||||
c.t528 = t528
|
||||
}
|
||||
if t530, ok := m[0x530]; ok {
|
||||
c.t530 = t530
|
||||
}
|
||||
/*
|
||||
if t528, ok := m[0x528]; ok {
|
||||
c.t528 = t528
|
||||
}
|
||||
if t530, ok := m[0x530]; ok {
|
||||
c.t530 = t530
|
||||
}
|
||||
*/
|
||||
if t108, ok := m[0x108]; ok {
|
||||
c.ksid = t108
|
||||
}
|
||||
@ -85,28 +90,28 @@ func (c *QQClient) decodeT119(data, ek []byte) {
|
||||
// readT138(t138) // chg time
|
||||
}
|
||||
|
||||
c.sigInfo = &loginSigInfo{
|
||||
loginBitmap: 0,
|
||||
srmToken: utils.Select(m[0x16a], c.sigInfo.srmToken),
|
||||
t133: utils.Select(m[0x133], c.sigInfo.t133),
|
||||
encryptedA1: utils.Select(m[0x106], c.sigInfo.encryptedA1),
|
||||
tgt: m[0x10a],
|
||||
tgtKey: m[0x10d],
|
||||
userStKey: m[0x10e],
|
||||
userStWebSig: m[0x103],
|
||||
sKey: m[0x120],
|
||||
sKeyExpiredTime: time.Now().Unix() + 21600,
|
||||
d2: m[0x143],
|
||||
d2Key: m[0x305],
|
||||
wtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.wtSessionTicketKey),
|
||||
deviceToken: m[0x322],
|
||||
c.sigInfo = &auth.SigInfo{
|
||||
LoginBitmap: 0,
|
||||
SrmToken: utils.Select(m[0x16a], c.sigInfo.SrmToken),
|
||||
T133: utils.Select(m[0x133], c.sigInfo.T133),
|
||||
EncryptedA1: utils.Select(m[0x106], c.sigInfo.EncryptedA1),
|
||||
TGT: m[0x10a],
|
||||
TGTKey: m[0x10d],
|
||||
UserStKey: m[0x10e],
|
||||
UserStWebSig: m[0x103],
|
||||
SKey: m[0x120],
|
||||
SKeyExpiredTime: time.Now().Unix() + 21600,
|
||||
D2: m[0x143],
|
||||
D2Key: m[0x305],
|
||||
WtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.WtSessionTicketKey),
|
||||
DeviceToken: m[0x322],
|
||||
|
||||
psKeyMap: psKeyMap,
|
||||
pt4TokenMap: pt4TokenMap,
|
||||
PsKeyMap: psKeyMap,
|
||||
Pt4TokenMap: pt4TokenMap,
|
||||
}
|
||||
if len(c.PasswordMd5[:]) > 0 {
|
||||
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
||||
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.encryptedA1)
|
||||
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.EncryptedA1)
|
||||
if len(decrypted) > 51+16 {
|
||||
dr := binary.NewReader(decrypted)
|
||||
dr.ReadBytes(51)
|
||||
@ -125,9 +130,9 @@ func (c *QQClient) decodeT119R(data []byte) {
|
||||
reader.ReadBytes(2)
|
||||
m := reader.ReadTlvMap(2)
|
||||
if t120, ok := m[0x120]; ok {
|
||||
c.sigInfo.sKey = t120
|
||||
c.sigInfo.sKeyExpiredTime = time.Now().Unix() + 21600
|
||||
c.Debug("skey updated: %v", c.sigInfo.sKey)
|
||||
c.sigInfo.SKey = t120
|
||||
c.sigInfo.SKeyExpiredTime = time.Now().Unix() + 21600
|
||||
c.Debug("skey updated: %v", c.sigInfo.SKey)
|
||||
}
|
||||
if t11a, ok := m[0x11a]; ok {
|
||||
c.Nickname, c.Age, c.Gender = readT11A(t11a)
|
||||
@ -138,8 +143,8 @@ func (c *QQClient) decodeT119R(data []byte) {
|
||||
func (c *QQClient) decodeT130(data []byte) {
|
||||
reader := binary.NewReader(data)
|
||||
reader.ReadBytes(2)
|
||||
c.timeDiff = int64(reader.ReadInt32()) - time.Now().Unix()
|
||||
c.t149 = reader.ReadBytes(4)
|
||||
// c.timeDiff = int64(reader.ReadInt32()) - time.Now().Unix()
|
||||
// c.t149 = reader.ReadBytes(4)
|
||||
}
|
||||
|
||||
func (c *QQClient) decodeT113(data []byte) {
|
||||
@ -149,7 +154,7 @@ func (c *QQClient) decodeT113(data []byte) {
|
||||
}
|
||||
|
||||
func (c *QQClient) decodeT186(data []byte) {
|
||||
c.pwdFlag = data[1] == 1
|
||||
// c.pwdFlag = data[1] == 1
|
||||
}
|
||||
|
||||
// --- tlv readers ---
|
||||
|
Loading…
x
Reference in New Issue
Block a user