github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/internal/network/transport.go (about) 1 package network 2 3 import ( 4 "strconv" 5 "strings" 6 7 "github.com/Mrs4s/MiraiGo/binary" 8 "github.com/Mrs4s/MiraiGo/client/internal/auth" 9 "github.com/Mrs4s/MiraiGo/client/pb" 10 "github.com/Mrs4s/MiraiGo/internal/proto" 11 "github.com/Mrs4s/MiraiGo/wrapper" 12 "github.com/pkg/errors" 13 ) 14 15 // Transport is a network transport. 16 type Transport struct { 17 Sig *auth.SigInfo 18 Version *auth.AppVersion 19 Device *auth.Device 20 21 // connection 22 // conn *TCPClient 23 } 24 25 var WhiteListCommands = ` 26 ConnAuthSvr.fast_qq_login 27 ConnAuthSvr.sdk_auth_api 28 ConnAuthSvr.sdk_auth_api_emp 29 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoBarrage 30 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoComment 31 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoFollow 32 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoLike 33 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoPush 34 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.DoReply 35 FeedCloudSvr.trpc.feedcloud.commwriter.ComWriter.PublishFeed 36 FeedCloudSvr.trpc.videocircle.circleprofile.CircleProfile.SetProfile 37 friendlist.addFriend 38 friendlist.AddFriendReq 39 friendlist.ModifyGroupInfoReq 40 MessageSvc.PbSendMsg 41 MsgProxy.SendMsg 42 OidbSvc.0x4ff_9 43 OidbSvc.0x4ff_9_IMCore 44 OidbSvc.0x56c_6 45 OidbSvc.0x6d9_4 46 OidbSvc.0x758 47 OidbSvc.0x758_0 48 OidbSvc.0x758_1 49 OidbSvc.0x88d_0 50 OidbSvc.0x89a_0 51 OidbSvc.0x89b_1 52 OidbSvc.0x8a1_0 53 OidbSvc.0x8a1_7 54 OidbSvc.0x8ba 55 OidbSvc.0x9fa 56 OidbSvc.oidb_0x758 57 OidbSvcTrpcTcp.0x101e_1 58 OidbSvcTrpcTcp.0x101e_2 59 OidbSvcTrpcTcp.0x1100_1 60 OidbSvcTrpcTcp.0x1105_1 61 OidbSvcTrpcTcp.0x1107_1 62 OidbSvcTrpcTcp.0x55f_0 63 OidbSvcTrpcTcp.0x6d9_4 64 OidbSvcTrpcTcp.0xf55_1 65 OidbSvcTrpcTcp.0xf57_1 66 OidbSvcTrpcTcp.0xf57_106 67 OidbSvcTrpcTcp.0xf57_9 68 OidbSvcTrpcTcp.0xf65_1 69 OidbSvcTrpcTcp.0xf65_10 70 OidbSvcTrpcTcp.0xf67_1 71 OidbSvcTrpcTcp.0xf67_5 72 OidbSvcTrpcTcp.0xf6e_1 73 OidbSvcTrpcTcp.0xf88_1 74 OidbSvcTrpcTcp.0xf89_1 75 OidbSvcTrpcTcp.0xfa5_1 76 ProfileService.getGroupInfoReq 77 ProfileService.GroupMngReq 78 QChannelSvr.trpc.qchannel.commwriter.ComWriter.DoComment 79 QChannelSvr.trpc.qchannel.commwriter.ComWriter.DoReply 80 QChannelSvr.trpc.qchannel.commwriter.ComWriter.PublishFeed 81 qidianservice.135 82 qidianservice.207 83 qidianservice.269 84 qidianservice.290 85 SQQzoneSvc.addComment 86 SQQzoneSvc.addReply 87 SQQzoneSvc.forward 88 SQQzoneSvc.like 89 SQQzoneSvc.publishmood 90 SQQzoneSvc.shuoshuo 91 trpc.group_pro.msgproxy.sendmsg 92 trpc.login.ecdh.EcdhService.SsoNTLoginPasswordLoginUnusualDevice 93 trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey 94 trpc.o3.ecdh_access.EcdhAccess.SsoSecureA2Access 95 trpc.o3.ecdh_access.EcdhAccess.SsoSecureA2Establish 96 trpc.o3.ecdh_access.EcdhAccess.SsoSecureAccess 97 trpc.o3.report.Report.SsoReport 98 trpc.passwd.manager.PasswdManager.SetPasswd 99 trpc.passwd.manager.PasswdManager.VerifyPasswd 100 trpc.qlive.relationchain_svr.RelationchainSvr.Follow 101 trpc.qlive.word_svr.WordSvr.NewPublicChat 102 trpc.qqhb.qqhb_proxy.Handler.sso_handle 103 trpc.springfestival.redpacket.LuckyBag.SsoSubmitGrade 104 wtlogin.device_lock 105 wtlogin.exchange_emp 106 wtlogin.login 107 wtlogin.name2uin 108 wtlogin.qrlogin 109 wtlogin.register 110 wtlogin.trans_emp 111 wtlogin_device.login 112 wtlogin_device.tran_sim_emp 113 ` 114 115 func (t *Transport) packBody(req *Request, w *binary.Writer) { 116 pos := w.FillUInt32() 117 if req.Type == RequestTypeLogin { 118 w.WriteUInt32(uint32(req.SequenceID)) 119 w.WriteUInt32(t.Version.AppId) 120 w.WriteUInt32(t.Version.SubAppId) 121 w.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}) 122 tgt := t.Sig.TGT 123 if len(tgt) == 0 || len(tgt) == 4 { 124 w.WriteUInt32(0x04) 125 } else { 126 w.WriteUInt32(uint32(len(tgt) + 4)) 127 w.Write(tgt) 128 } 129 } 130 w.WriteString(req.CommandName) 131 w.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4)) 132 w.Write(t.Sig.OutPacketSessionID) 133 if req.Type == RequestTypeLogin { 134 w.WriteString((*t.Device).IMEI) 135 w.WriteUInt32(0x04) 136 137 w.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2) 138 w.Write(t.Sig.Ksid) 139 } 140 if strings.Contains(WhiteListCommands, req.CommandName) { 141 secSign := t.PackSecSign(req) 142 w.WriteUInt32(uint32(len(secSign) + 4)) 143 w.Write(secSign) 144 } 145 146 w.WriteUInt32(0x04 + uint32(len(t.Device.QImei16))) 147 w.Write([]byte(t.Device.QImei16)) 148 149 w.WriteUInt32At(pos, uint32(w.Len()-pos)) 150 151 w.WriteUInt32(uint32(len(req.Body) + 4)) 152 w.Write(req.Body) 153 } 154 155 func (t *Transport) PackSecSign(req *Request) []byte { 156 if wrapper.FekitGetSign == nil { 157 return []byte{} 158 } 159 sign, extra, token, err := wrapper.FekitGetSign(uint64(req.SequenceID), strconv.FormatInt(req.Uin, 10), req.CommandName, t.Version.QUA, req.Body) 160 if err != nil { 161 return []byte{} 162 } 163 m := &pb.SSOReserveField{ 164 Flag: 0, 165 Qimei: t.Device.QImei16, 166 NewconnFlag: 0, 167 Uid: strconv.FormatInt(req.Uin, 10), 168 Imsi: 0, 169 NetworkType: 1, 170 IpStackType: 1, 171 MessageType: 0, 172 SecInfo: &pb.SsoSecureInfo{ 173 SecSig: sign, 174 SecDeviceToken: token, 175 SecExtra: extra, 176 }, 177 SsoIpOrigin: 0, 178 } 179 data, err := proto.Marshal(m) 180 if err != nil { 181 panic(errors.Wrap(err, "failed to unmarshal protobuf SSOReserveField")) 182 } 183 return data 184 } 185 186 // PackPacket packs a packet. 187 func (t *Transport) PackPacket(req *Request) []byte { 188 // todo(wdvxdr): combine pack packet, send packet and return the response 189 if len(t.Sig.D2) == 0 { 190 req.EncryptType = EncryptTypeEmptyKey 191 } 192 193 w := binary.SelectWriter() 194 defer binary.PutWriter(w) 195 196 pos := w.FillUInt32() 197 // vvv w.Write(head) vvv 198 w.WriteUInt32(uint32(req.Type)) 199 w.WriteByte(byte(req.EncryptType)) 200 switch req.Type { 201 case RequestTypeLogin: 202 switch req.EncryptType { 203 case EncryptTypeD2Key: 204 w.WriteUInt32(uint32(len(t.Sig.D2) + 4)) 205 w.Write(t.Sig.D2) 206 default: 207 w.WriteUInt32(4) 208 } 209 case RequestTypeSimple: 210 w.WriteUInt32(uint32(req.SequenceID)) 211 } 212 w.WriteByte(0x00) 213 w.WriteString(strconv.FormatInt(req.Uin, 10)) 214 // ^^^ w.Write(head) ^^^ 215 216 w2 := binary.SelectWriter() 217 t.packBody(req, w2) 218 body := w2.Bytes() 219 // encrypt body 220 switch req.EncryptType { 221 case EncryptTypeD2Key: 222 body = binary.NewTeaCipher(t.Sig.D2Key).Encrypt(body) 223 case EncryptTypeEmptyKey: 224 emptyKey := make([]byte, 16) 225 body = binary.NewTeaCipher(emptyKey).Encrypt(body) 226 } 227 w.Write(body) 228 binary.PutWriter(w2) 229 230 w.WriteUInt32At(pos, uint32(w.Len())) 231 return append([]byte(nil), w.Bytes()...) 232 }