1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00
sync
This commit is contained in:
wdvxdr1123 2020-10-08 19:36:45 +08:00 committed by GitHub
commit 375490e386
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 373 additions and 85 deletions

View File

@ -36,17 +36,21 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
seq := c.nextSeq()
req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) {
w.WriteUInt16(9)
w.WriteUInt16(17)
if c.AllowSlider {
w.WriteUInt16(0x17)
} else {
w.WriteUInt16(0x16)
}
w.Write(tlv.T18(16, uint32(c.Uin)))
w.Write(tlv.T1(uint32(c.Uin), SystemDeviceInfo.IpAddress))
w.Write(tlv.T106(uint32(c.Uin), 0, uint32(SystemDeviceInfo.Protocol), c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 0))
w.Write(tlv.T116(184024956, 0x10400))
w.Write(tlv.T100(uint32(SystemDeviceInfo.Protocol), 34869472))
w.Write(tlv.T106(uint32(c.Uin), 0, c.version.AppId, c.version.SSOVersion, c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 0))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T100(c.version.SSOVersion, c.version.AppId, c.version.MainSigMap))
w.Write(tlv.T107(0))
w.Write(tlv.T142("com.tencent.mobileqq"))
w.Write(tlv.T142(c.version.ApkId))
w.Write(tlv.T144(
SystemDeviceInfo.AndroidId,
[]byte(SystemDeviceInfo.IMEI),
SystemDeviceInfo.GenDeviceInfoData(),
SystemDeviceInfo.OSType,
SystemDeviceInfo.Version.Release,
@ -60,7 +64,7 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
))
w.Write(tlv.T145(SystemDeviceInfo.Guid))
w.Write(tlv.T147(16, []byte("8.2.7"), []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D}))
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
/*
if (miscBitMap & 0x80) != 0{
w.Write(tlv.T166(1))
@ -80,16 +84,18 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
if len(SystemDeviceInfo.IMSIMd5) != 0 {
w.Write(tlv.T194(SystemDeviceInfo.IMSIMd5))
}
w.Write(tlv.T191(0x82))
if c.AllowSlider {
w.Write(tlv.T191(0x82))
}
if len(SystemDeviceInfo.WifiBSSID) != 0 && len(SystemDeviceInfo.WifiSSID) != 0 {
w.Write(tlv.T202(SystemDeviceInfo.WifiBSSID, SystemDeviceInfo.WifiSSID))
}
w.Write(tlv.T177())
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
w.Write(tlv.T516())
w.Write(tlv.T521())
w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00})))
})
sso := packets.BuildSsoPacket(seq, uint32(SystemDeviceInfo.Protocol), "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
return seq, packet
}
@ -102,11 +108,11 @@ func (c *QQClient) buildDeviceLockLoginPacket(t402 []byte) (uint16, []byte) {
w.Write(tlv.T8(2052))
w.Write(tlv.T104(c.t104))
w.Write(tlv.T116(150470524, 66560))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
h := md5.Sum(append(append(SystemDeviceInfo.Guid, []byte("stMNokHgxZUGhsYp")...), t402...))
w.Write(tlv.T401(h[:]))
})
sso := packets.BuildSsoPacket(seq, uint32(SystemDeviceInfo.Protocol), "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
return seq, packet
}
@ -122,7 +128,45 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt
w.Write(tlv.T104(c.t104))
w.Write(tlv.T116(150470524, 66560))
})
sso := packets.BuildSsoPacket(seq, uint32(SystemDeviceInfo.Protocol), "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
return seq, packet
}
func (c *QQClient) buildSNSRequestPacket() (uint16, []byte) {
seq := c.nextSeq()
req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) {
w.WriteUInt16(8)
w.WriteUInt16(6)
w.Write(tlv.T8(2052))
w.Write(tlv.T104(c.t104))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T174(c.t174))
w.Write(tlv.T17A(9))
w.Write(tlv.T197())
})
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
return seq, packet
}
func (c *QQClient) buildSNSCodeSubmitPacket(code string) (uint16, []byte) {
seq := c.nextSeq()
req := packets.BuildOicqRequestPacket(c.Uin, 0x810, crypto.ECDH, c.RandomKey, func(w *binary.Writer) {
w.WriteUInt16(7)
w.WriteUInt16(7)
w.Write(tlv.T8(2052))
w.Write(tlv.T104(c.t104))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T174(c.t174))
w.Write(tlv.T17C(code))
h := md5.Sum(append(append(SystemDeviceInfo.Guid, []byte("12 34567890123456")...), c.t402...))
w.Write(tlv.T401(h[:]))
w.Write(tlv.T198())
})
sso := packets.BuildSsoPacket(seq, c.version.AppId, "wtlogin.login", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{})
return seq, packet
}
@ -135,9 +179,9 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
w.Write(tlv.T18(16, uint32(c.Uin)))
w.Write(tlv.T1(uint32(c.Uin), SystemDeviceInfo.IpAddress))
w.Write(tlv.T106(uint32(c.Uin), 0, uint32(SystemDeviceInfo.Protocol), c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 1))
w.Write(tlv.T116(150470524, 66560))
w.Write(tlv.T100(2, 34869472))
w.Write(tlv.T106(uint32(c.Uin), 0, c.version.AppId, c.version.SSOVersion, c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 1))
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
w.Write(tlv.T100(c.version.SSOVersion, 2, c.version.MainSigMap))
w.Write(tlv.T107(0))
w.Write(tlv.T144(
SystemDeviceInfo.AndroidId,
@ -152,7 +196,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
SystemDeviceInfo.Brand,
SystemDeviceInfo.TgtgtKey,
))
w.Write(tlv.T142("com.tencent.mobileqq"))
w.Write(tlv.T142(c.version.ApkId))
w.Write(tlv.T145(SystemDeviceInfo.Guid))
w.Write(tlv.T16A(c.sigInfo.srmToken))
w.Write(tlv.T154(seq))
@ -163,8 +207,8 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
}))
w.Write(tlv.T147(16, []byte("8.2.7"), []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D}))
w.Write(tlv.T177())
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
w.Write(tlv.T187(SystemDeviceInfo.MacAddress))
w.Write(tlv.T188(SystemDeviceInfo.AndroidId))
w.Write(tlv.T194(SystemDeviceInfo.IMSIMd5))
@ -218,7 +262,7 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
Context: make(map[string]string),
Status: make(map[string]string),
}
sso := packets.BuildSsoPacket(seq, uint32(SystemDeviceInfo.Protocol), "StatSvc.register", SystemDeviceInfo.IMEI, c.sigInfo.tgt, c.OutGoingPacketSessionId, pkt.ToBytes(), c.ksid)
sso := packets.BuildSsoPacket(seq, c.version.AppId, "StatSvc.register", SystemDeviceInfo.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
}
@ -691,7 +735,7 @@ func (c *QQClient) buildImageUploadPacket(data, updKey []byte, commandId int32,
}
return c.nextGroupDataTransSeq()
}(),
Appid: int32(SystemDeviceInfo.Protocol),
Appid: int32(c.version.AppId),
Dataflag: 4096,
CommandId: commandId,
LocaleId: 2052,
@ -1081,7 +1125,7 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool)
func (c *QQClient) buildGroupInfoRequestPacket(groupCode int64) (uint16, []byte) {
seq := c.nextSeq()
body := &oidb.D88DReqBody{
AppId: proto.Uint32(uint32(SystemDeviceInfo.Protocol)),
AppId: proto.Uint32(c.version.AppId),
ReqGroupInfo: []*oidb.ReqGroupInfo{
{
GroupCode: proto.Uint64(uint64(groupCode)),

View File

@ -31,6 +31,7 @@ import (
type QQClient struct {
Uin int64
PasswordMd5 [16]byte
AllowSlider bool
Nickname string
Age uint16
@ -50,12 +51,15 @@ type QQClient struct {
servers []*net.TCPAddr
currServerIndex int
retryTimes int
version *versionInfo
syncCookie []byte
pubAccountCookie []byte
msgCtrlBuf []byte
ksid []byte
t104 []byte
t174 []byte
t402 []byte // only for sms
t150 []byte
t149 []byte
t528 []byte
@ -159,10 +163,11 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
groupSeq: int32(rand.Intn(20000)),
friendSeq: 22911,
highwayApplyUpSeq: 77918,
ksid: []byte("|454001228437590|A8.2.7.27f6ea96"),
ksid: []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", SystemDeviceInfo.IMEI)),
eventHandlers: &eventHandlers{},
msgSvcCache: utils.NewCache(time.Second * 15),
transCache: utils.NewCache(time.Second * 15),
version: genVersionInfo(SystemDeviceInfo.Protocol),
servers: []*net.TCPAddr{ // default servers
{IP: net.IP{42, 81, 169, 46}, Port: 8080},
{IP: net.IP{42, 81, 172, 81}, Port: 80},
@ -212,6 +217,47 @@ func (c *QQClient) Login() (*LoginResponse, error) {
return &l, nil
}
// SubmitCaptcha send captcha to server
func (c *QQClient) SubmitCaptcha(result string, sign []byte) (*LoginResponse, error) {
seq, packet := c.buildCaptchaPacket(result, sign)
rsp, err := c.sendAndWait(seq, packet)
if err != nil {
return nil, err
}
l := rsp.(LoginResponse)
if l.Success {
c.registerClient()
if !c.heartbeatEnabled {
c.startHeartbeat()
}
}
return &l, nil
}
func (c *QQClient) SubmitSNS(code string) (*LoginResponse, error) {
rsp, err := c.sendAndWait(c.buildSNSCodeSubmitPacket(code))
if err != nil {
return nil, err
}
l := rsp.(LoginResponse)
if l.Success {
c.registerClient()
if !c.heartbeatEnabled {
c.startHeartbeat()
}
}
return &l, nil
}
func (c *QQClient) RequestSNS() bool {
rsp, err := c.sendAndWait(c.buildSNSRequestPacket())
if err != nil {
c.Error("request sms error: %v", err)
return false
}
return rsp.(LoginResponse).Error == SNSNeededError
}
func (c *QQClient) GetVipInfo(target int64) (*VipInfo, error) {
b, err := utils.HttpGetBytes(fmt.Sprintf("https://h5.vip.qq.com/p/mc/cardv2/other?platform=1&qq=%d&adtag=geren&aid=mvip.pingtai.mobileqq.androidziliaoka.fromqita", target), c.getCookiesWithDomain("h5.vip.qq.com"))
if err != nil {
@ -283,23 +329,6 @@ func (c *QQClient) GetSummaryInfo(target int64) (*SummaryCardInfo, error) {
return rsp.(*SummaryCardInfo), nil
}
// SubmitCaptcha send captcha to server
func (c *QQClient) SubmitCaptcha(result string, sign []byte) (*LoginResponse, error) {
seq, packet := c.buildCaptchaPacket(result, sign)
rsp, err := c.sendAndWait(seq, packet)
if err != nil {
return nil, err
}
l := rsp.(LoginResponse)
if l.Success {
c.registerClient()
if !c.heartbeatEnabled {
c.startHeartbeat()
}
}
return &l, nil
}
// ReloadFriendList refresh QQClient.FriendList field via GetFriendList()
func (c *QQClient) ReloadFriendList() error {
rsp, err := c.GetFriendList()
@ -957,6 +986,13 @@ func (c *QQClient) connect() error {
return nil
}
func (c *QQClient) Disconnect() {
if c.Online {
c.Online = false
c.Conn.Close()
}
}
func (c *QQClient) SetCustomServer(servers []*net.TCPAddr) {
c.servers = append(servers, c.servers...)
}
@ -1118,7 +1154,7 @@ func (c *QQClient) startHeartbeat() {
func (c *QQClient) doHeartbeat() {
if c.Online {
seq := c.nextSeq()
sso := packets.BuildSsoPacket(seq, uint32(SystemDeviceInfo.Protocol), "Heartbeat.Alive", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, []byte{}, c.ksid)
sso := packets.BuildSsoPacket(seq, c.version.AppId, "Heartbeat.Alive", SystemDeviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, []byte{}, c.ksid)
packet := packets.BuildLoginPacket(c.Uin, 0, []byte{}, sso, []byte{})
_, err := c.sendAndWait(seq, packet)
if err != nil {

View File

@ -56,8 +56,9 @@ func decodeLoginResponse(c *QQClient, _ uint16, payload []byte) (interface{}, er
c.t104, _ = m[0x104]
if m.Exists(0x192) { // slider, not supported yet
return LoginResponse{
Success: false,
Error: UnknownLoginError,
Success: false,
VerifyUrl: string(m[0x192]),
Error: SliderNeededError,
}, nil
}
if m.Exists(0x165) { // image
@ -80,11 +81,54 @@ func decodeLoginResponse(c *QQClient, _ uint16, payload []byte) (interface{}, er
} // need captcha
if t == 160 {
if t174, ok := m[0x174]; ok { // 短信验证
c.t104 = m[0x104]
c.t174 = t174
c.t402 = m[0x402]
phone := func() string {
r := binary.NewReader(m[0x178])
return r.ReadStringLimit(int(r.ReadInt32()))
}()
if t204, ok := m[0x204]; ok { // 同时支持扫码验证 ?
return LoginResponse{
Success: false,
Error: SNSOrVerifyNeededError,
VerifyUrl: string(t204),
SMSPhone: phone,
ErrorMessage: string(m[0x17e]),
}, nil
}
return LoginResponse{
Success: false,
Error: SNSNeededError,
SMSPhone: phone,
ErrorMessage: string(m[0x17e]),
}, nil
}
if _, ok := m[0x17b]; ok { // 二次验证
c.t104 = m[0x104]
return LoginResponse{
Success: false,
Error: SNSNeededError,
}, nil
}
if t204, ok := m[0x204]; ok { // 扫码验证
return LoginResponse{
Success: false,
Error: UnsafeDeviceError,
VerifyUrl: string(t204),
ErrorMessage: "",
}, nil
}
}
if t == 162 {
return LoginResponse{
Success: false,
Error: UnsafeDeviceError,
VerifyUrl: string(m[0x204]),
ErrorMessage: "",
Error: TooManySNSRequestError,
}, nil
}
@ -139,7 +183,7 @@ func decodeExchangeEmpResponse(c *QQClient, _ uint16, payload []byte) (interface
return nil, nil
}
if cmd == 15 { // TODO: 免密登录
c.decodeT119(m[0x119])
c.decodeT119R(m[0x119])
}
return nil, nil
}

View File

@ -30,6 +30,9 @@ type (
// Unsafe device
VerifyUrl string
// SMS needed
SMSPhone string
// other error
ErrorMessage string
}
@ -119,6 +122,12 @@ type (
Member *GroupMemberInfo
}
MemberCardUpdatedEvent struct {
Group *GroupInfo
OldCard string
Member *GroupMemberInfo
}
IGroupNotifyEvent interface {
From() int64
Content() string
@ -240,18 +249,22 @@ type (
)
const (
NeedCaptcha LoginError = 1
OtherLoginError LoginError = 3
UnsafeDeviceError LoginError = 4
UnknownLoginError LoginError = -1
NeedCaptcha LoginError = 1
OtherLoginError LoginError = 3
UnsafeDeviceError LoginError = 4
SNSNeededError LoginError = 5
TooManySNSRequestError LoginError = 6
SNSOrVerifyNeededError LoginError = 7
SliderNeededError LoginError = 8
UnknownLoginError LoginError = -1
Owner MemberPermission = iota
Administrator
Member
AndroidPhone ClientProtocol = 537062845
AndroidPad ClientProtocol = 537062409
AndroidWatch ClientProtocol = 537061176
AndroidPhone ClientProtocol = 1
AndroidPad ClientProtocol = 2
AndroidWatch ClientProtocol = 3
)
func (g *GroupInfo) UpdateName(newName string) {

View File

@ -17,6 +17,7 @@ type eventHandlers struct {
leaveGroupHandlers []func(*QQClient, *GroupLeaveEvent)
memberJoinedHandlers []func(*QQClient, *MemberJoinGroupEvent)
memberLeavedHandlers []func(*QQClient, *MemberLeaveGroupEvent)
memberCardUpdatedHandlers []func(*QQClient, *MemberCardUpdatedEvent)
permissionChangedHandlers []func(*QQClient, *MemberPermissionChangedEvent)
groupInvitedHandlers []func(*QQClient, *GroupInvitedRequest)
joinRequestHandlers []func(*QQClient, *UserJoinGroupRequest)
@ -69,6 +70,10 @@ func (c *QQClient) OnGroupMemberLeaved(f func(*QQClient, *MemberLeaveGroupEvent)
c.eventHandlers.memberLeavedHandlers = append(c.eventHandlers.memberLeavedHandlers, f)
}
func (c *QQClient) OnGroupMemberCardUpdated(f func(*QQClient, *MemberCardUpdatedEvent)) {
c.eventHandlers.memberCardUpdatedHandlers = append(c.eventHandlers.memberCardUpdatedHandlers, f)
}
func (c *QQClient) OnGroupMemberPermissionChanged(f func(*QQClient, *MemberPermissionChangedEvent)) {
c.eventHandlers.permissionChangedHandlers = append(c.eventHandlers.permissionChangedHandlers, f)
}
@ -237,6 +242,17 @@ func (c *QQClient) dispatchMemberLeaveEvent(e *MemberLeaveGroupEvent) {
}
}
func (c *QQClient) dispatchMemberCardUpdatedEvent(e *MemberCardUpdatedEvent) {
if e == nil {
return
}
for _, f := range c.eventHandlers.memberCardUpdatedHandlers {
cover(func() {
f(c, e)
})
}
}
func (c *QQClient) dispatchPermissionChanged(e *MemberPermissionChangedEvent) {
if e == nil {
return

View File

@ -66,6 +66,19 @@ type groupMessageBuilder struct {
MessageSlices []*msg.Message
}
type versionInfo struct {
ApkId string
AppId uint32
SortVersionName string
BuildTime uint32
ApkSign []byte
SdkVersion string
SSOVersion uint32
MiscBitmap uint32
SubSigmap uint32
MainSigMap uint32
}
// default
var SystemDeviceInfo = &DeviceInfo{
Display: []byte("MIRAI.123456.001"),
@ -125,6 +138,51 @@ func GenRandomDevice() {
SystemDeviceInfo.GenNewTgtgtKey()
}
func genVersionInfo(p ClientProtocol) *versionInfo {
switch p {
case AndroidPhone: // Dumped by mirai from qq android v8.2.7
return &versionInfo{
ApkId: "com.tencent.mobileqq",
AppId: 537062845,
SortVersionName: "8.2.7",
BuildTime: 1571193922,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.2413",
SSOVersion: 5,
MiscBitmap: 184024956,
SubSigmap: 0x10400,
MainSigMap: 34869472,
}
case AndroidWatch:
return &versionInfo{
ApkId: "com.tencent.mobileqq",
AppId: 537061176,
SortVersionName: "8.2.7",
BuildTime: 1571193922,
ApkSign: []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D},
SdkVersion: "6.0.0.2413",
SSOVersion: 5,
MiscBitmap: 184024956,
SubSigmap: 0x10400,
MainSigMap: 34869472,
}
case AndroidPad: // Dumped from qq-hd v5.8.9
return &versionInfo{
ApkId: "com.tencent.minihd.qq",
AppId: 537065549,
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,
}
}
return nil
}
func (info *DeviceInfo) ToJson() []byte {
f := &DeviceInfoFile{
Display: string(info.Display),
@ -309,6 +367,21 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
Member: info,
})
}
if m.Head.GroupInfo != nil && m.Head.GroupInfo.GroupCard != "" && mem.CardName != m.Head.GroupInfo.GroupCard {
old := mem.CardName
if mem.Nickname == m.Head.GroupInfo.GroupCard {
mem.CardName = ""
} else {
mem.CardName = m.Head.GroupInfo.GroupCard
}
if old != mem.CardName {
go c.dispatchMemberCardUpdatedEvent(&MemberCardUpdatedEvent{
Group: group,
OldCard: old,
Member: mem,
})
}
}
sender = &message.Sender{
Uin: mem.Uin,
Nickname: mem.Nickname,

View File

@ -23,18 +23,6 @@ func (c *QQClient) decodeT119(data []byte) {
reader := binary.NewReader(tea.Decrypt(data))
reader.ReadBytes(2)
m := reader.ReadTlvMap(2)
if len(c.sigInfo.sKey) > 0 { // refresh
if t120, ok := m[0x120]; ok {
c.sigInfo.sKey = t120
c.sigInfo.sKeyExpiredTime = time.Now().Unix() + 43200 // 86400 / 2
c.Debug("skey updated: %v", c.sigInfo.sKey)
}
if t11a, ok := m[0x11a]; ok {
c.Nickname, c.Age, c.Gender = readT11A(t11a)
c.Debug("account info updated: " + c.Nickname)
}
return
}
if t130, ok := m[0x130]; ok {
c.decodeT130(t130)
}
@ -117,6 +105,23 @@ func (c *QQClient) decodeT119(data []byte) {
c.Gender = gender
}
// wtlogin.exchange_emp
func (c *QQClient) decodeT119R(data []byte) {
tea := binary.NewTeaCipher(SystemDeviceInfo.TgtgtKey)
reader := binary.NewReader(tea.Decrypt(data))
reader.ReadBytes(2)
m := reader.ReadTlvMap(2)
if t120, ok := m[0x120]; ok {
c.sigInfo.sKey = t120
c.sigInfo.sKeyExpiredTime = time.Now().Unix() + 43200 // 86400 / 2
c.Debug("skey updated: %v", c.sigInfo.sKey)
}
if t11a, ok := m[0x11a]; ok {
c.Nickname, c.Age, c.Gender = readT11A(t11a)
c.Debug("account info updated: " + c.Nickname)
}
}
func (c *QQClient) decodeT130(data []byte) {
reader := binary.NewReader(data)
reader.ReadBytes(2)

View File

@ -24,11 +24,11 @@ func BuildLoginPacket(uin int64, bodyType byte, key, body, extraData []byte) []b
return w.Bytes()
}
func BuildUniPacket(uin int64, seq uint16, commandName string, bodyType byte, sessionId, extraData, key, body []byte) []byte {
func BuildUniPacket(uin int64, seq uint16, commandName string, encryptType byte, sessionId, extraData, key, body []byte) []byte {
w := binary.NewWriter()
w.WriteIntLvPacket(4, func(w *binary.Writer) {
w.WriteUInt32(0x0B)
w.WriteByte(bodyType)
w.WriteByte(encryptType)
w.WriteUInt32(uint32(seq))
w.WriteByte(0)
w.WriteString(strconv.FormatInt(uin, 10))

View File

@ -52,12 +52,12 @@ func BuildOicqRequestPacket(uin int64, commandId uint16, encrypt IEncryptMethod,
return p.Bytes()
}
func BuildSsoPacket(seq uint16, protocol uint32, commandName, imei string, extData, outPacketSessionId, body, ksid []byte) []byte {
func BuildSsoPacket(seq uint16, appId uint32, commandName, imei string, extData, outPacketSessionId, body, ksid []byte) []byte {
p := binary.NewWriter()
p.WriteIntLvPacket(4, func(writer *binary.Writer) {
writer.WriteUInt32(uint32(seq))
writer.WriteUInt32(protocol)
writer.WriteUInt32(protocol)
writer.WriteUInt32(appId)
writer.WriteUInt32(appId)
writer.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
if len(extData) == 0 || len(extData) == 4 {
writer.WriteUInt32(0x04)
@ -66,8 +66,9 @@ func BuildSsoPacket(seq uint16, protocol uint32, commandName, imei string, extDa
writer.Write(extData)
}
writer.WriteString(commandName)
writer.WriteUInt32(0x08)
writer.Write(outPacketSessionId)
writer.WriteIntLvPacket(4, func(w *binary.Writer) {
w.Write(outPacketSessionId)
})
writer.WriteString(imei)
writer.WriteUInt32(0x04)
{

View File

@ -4,12 +4,12 @@ import (
"github.com/Mrs4s/MiraiGo/binary"
)
func T100(protocol, mainSigMap uint32) []byte {
func T100(ssoVersion, protocol, mainSigMap uint32) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x100)
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(1)
w.WriteUInt32(5)
w.WriteUInt32(ssoVersion)
w.WriteUInt32(16)
w.WriteUInt32(protocol)
w.WriteUInt32(0) // App client version

View File

@ -8,13 +8,13 @@ import (
"time"
)
func T106(uin, salt, protocol uint32, passwordMd5 [16]byte, guidAvailable bool, guid, tgtgtKey []byte, wtf uint32) []byte {
func T106(uin, salt, appId, ssoVer uint32, passwordMd5 [16]byte, guidAvailable bool, guid, tgtgtKey []byte, wtf uint32) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x106)
body := binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(4)
w.WriteUInt32(rand.Uint32())
w.WriteUInt32(5)
w.WriteUInt32(ssoVer)
w.WriteUInt32(16) // appId
w.WriteUInt32(0) // app client version
if uin == 0 {
@ -36,7 +36,7 @@ func T106(uin, salt, protocol uint32, passwordMd5 [16]byte, guidAvailable bool,
} else {
w.Write(guid)
}
w.WriteUInt32(protocol)
w.WriteUInt32(appId)
w.WriteUInt32(1) // password login
b := make([]byte, 8)
binary2.BigEndian.PutUint64(b, uint64(uin))

View File

@ -1,9 +1,11 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
import (
"github.com/Mrs4s/MiraiGo/binary"
)
func T144(
androidId, devInfo, osType, osVersion, simInfo, apn []byte,
imei, devInfo, osType, osVersion, simInfo, apn []byte,
isGuidFromFileNull, isGuidAvailable, isGuidChanged bool,
guidFlag uint32,
buildModel, guid, buildBrand, tgtgtKey []byte,
@ -13,7 +15,7 @@ func T144(
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
w.EncryptAndWrite(tgtgtKey, binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(5)
w.Write(T109(androidId))
w.Write(T109(imei))
w.Write(T52D(devInfo))
w.Write(T124(osType, osVersion, simInfo, apn))
w.Write(T128(isGuidFromFileNull, isGuidAvailable, isGuidChanged, guidFlag, buildModel, guid, buildBrand))

10
protocol/tlv/t174.go Normal file
View File

@ -0,0 +1,10 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T174(data []byte) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x174)
w.WriteTlv(data)
})
}

View File

@ -2,13 +2,13 @@ package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T177() []byte {
func T177(buildTime uint32, sdkVersion string) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x177)
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
w.WriteByte(0x01)
w.WriteUInt32(1571193922)
w.WriteTlv([]byte("6.0.0.2413"))
w.WriteUInt32(buildTime)
w.WriteTlv([]byte(sdkVersion))
}))
})
}

12
protocol/tlv/t17a.go Normal file
View File

@ -0,0 +1,12 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T17A(value int32) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x17a)
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt32(uint32(value))
}))
})
}

12
protocol/tlv/t17c.go Normal file
View File

@ -0,0 +1,12 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T17C(code string) []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x17c)
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
w.WriteStringShort(code)
}))
})
}

10
protocol/tlv/t197.go Normal file
View File

@ -0,0 +1,10 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T197() []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x197)
w.WriteTlv([]byte{0})
})
}

10
protocol/tlv/t198.go Normal file
View File

@ -0,0 +1,10 @@
package tlv
import "github.com/Mrs4s/MiraiGo/binary"
func T198() []byte {
return binary.NewWriterF(func(w *binary.Writer) {
w.WriteUInt16(0x198)
w.WriteTlv([]byte{0})
})
}