github.com/Mrs4s/MiraiGo@v0.0.0-20240226124653-54bdd873e3fe/client/internal/auth/device.go (about) 1 package auth 2 3 import ( 4 "crypto/md5" 5 "crypto/rand" 6 "encoding/hex" 7 "encoding/json" 8 9 "github.com/pkg/errors" 10 11 "github.com/Mrs4s/MiraiGo/client/pb" 12 "github.com/Mrs4s/MiraiGo/internal/proto" 13 ) 14 15 type OSVersion struct { 16 Incremental []byte 17 Release []byte 18 CodeName []byte 19 SDK uint32 20 } 21 22 type Device struct { 23 Display []byte 24 Product []byte 25 Device []byte 26 Board []byte 27 Brand []byte 28 Model []byte 29 Bootloader []byte 30 FingerPrint []byte 31 BootId []byte 32 ProcVersion []byte 33 BaseBand []byte 34 SimInfo []byte 35 OSType []byte 36 MacAddress []byte 37 IpAddress []byte 38 WifiBSSID []byte 39 WifiSSID []byte 40 IMSIMd5 []byte 41 IMEI string 42 AndroidId []byte 43 APN []byte 44 VendorName []byte 45 VendorOSName []byte 46 Guid []byte 47 TgtgtKey []byte 48 QImei16 string 49 QImei36 string 50 Protocol ProtocolType 51 Version *OSVersion 52 } 53 54 func (info *Device) ToJson() []byte { 55 f := &deviceFile{ 56 Display: string(info.Display), 57 Product: string(info.Product), 58 Device: string(info.Device), 59 Board: string(info.Board), 60 Model: string(info.Model), 61 FingerPrint: string(info.FingerPrint), 62 BootId: string(info.BootId), 63 ProcVersion: string(info.ProcVersion), 64 IMEI: info.IMEI, 65 Brand: string(info.Brand), 66 Bootloader: string(info.Bootloader), 67 BaseBand: string(info.BaseBand), 68 AndroidId: string(info.AndroidId), 69 Version: &osVersionFile{ 70 Incremental: string(info.Version.Incremental), 71 Release: string(info.Version.Release), 72 Codename: string(info.Version.CodeName), 73 Sdk: info.Version.SDK, 74 }, 75 SimInfo: string(info.SimInfo), 76 OsType: string(info.OSType), 77 MacAddress: string(info.MacAddress), 78 IpAddress: []int32{int32(info.IpAddress[0]), int32(info.IpAddress[1]), int32(info.IpAddress[2]), int32(info.IpAddress[3])}, 79 WifiBSSID: string(info.WifiBSSID), 80 WifiSSID: string(info.WifiSSID), 81 ImsiMd5: hex.EncodeToString(info.IMSIMd5), 82 Apn: string(info.APN), 83 VendorName: string(info.VendorName), 84 VendorOSName: string(info.VendorOSName), 85 Protocol: int(info.Protocol), 86 } 87 d, _ := json.Marshal(f) 88 return d 89 } 90 91 func (info *Device) ReadJson(d []byte) error { 92 var f deviceFile 93 if err := json.Unmarshal(d, &f); err != nil { 94 return errors.Wrap(err, "failed to unmarshal json message") 95 } 96 setIfNotEmpty := func(trg *[]byte, str string) { 97 if str != "" { 98 *trg = []byte(str) 99 } 100 } 101 setIfNotEmpty(&info.Display, f.Display) 102 setIfNotEmpty(&info.Product, f.Product) 103 setIfNotEmpty(&info.Device, f.Device) 104 setIfNotEmpty(&info.Board, f.Board) 105 setIfNotEmpty(&info.Brand, f.Brand) 106 setIfNotEmpty(&info.Model, f.Model) 107 setIfNotEmpty(&info.Bootloader, f.Bootloader) 108 setIfNotEmpty(&info.FingerPrint, f.FingerPrint) 109 setIfNotEmpty(&info.BootId, f.BootId) 110 setIfNotEmpty(&info.ProcVersion, f.ProcVersion) 111 setIfNotEmpty(&info.BaseBand, f.BaseBand) 112 setIfNotEmpty(&info.SimInfo, f.SimInfo) 113 setIfNotEmpty(&info.OSType, f.OsType) 114 setIfNotEmpty(&info.MacAddress, f.MacAddress) 115 if len(f.IpAddress) == 4 { 116 info.IpAddress = []byte{byte(f.IpAddress[0]), byte(f.IpAddress[1]), byte(f.IpAddress[2]), byte(f.IpAddress[3])} 117 } 118 setIfNotEmpty(&info.WifiBSSID, f.WifiBSSID) 119 setIfNotEmpty(&info.WifiSSID, f.WifiSSID) 120 if len(f.ImsiMd5) != 0 { 121 imsiMd5, err := hex.DecodeString(f.ImsiMd5) 122 if err != nil { 123 info.IMSIMd5 = imsiMd5 124 } 125 } 126 if f.IMEI != "" { 127 info.IMEI = f.IMEI 128 } 129 setIfNotEmpty(&info.APN, f.Apn) 130 setIfNotEmpty(&info.VendorName, f.VendorName) 131 setIfNotEmpty(&info.VendorOSName, f.VendorOSName) 132 133 setIfNotEmpty(&info.AndroidId, f.AndroidId) 134 if f.AndroidId == "" { 135 info.AndroidId = info.Display // ? 136 } 137 138 switch f.Protocol { 139 case 1, 2, 3, 4, 5, 6: 140 info.Protocol = ProtocolType(f.Protocol) 141 default: 142 info.Protocol = AndroidPad 143 } 144 145 v := new(OSVersion) 146 v.SDK = f.Version.Sdk 147 v.Release = []byte(f.Version.Release) 148 v.CodeName = []byte(f.Version.Codename) 149 v.Incremental = []byte(f.Version.Incremental) 150 info.Version = v 151 152 info.GenNewGuid() 153 info.GenNewTgtgtKey() 154 info.RequestQImei() // 应该可以缓存, 理论上同一设备每次请求都是一样的 155 return nil 156 } 157 158 func (info *Device) GenNewGuid() { 159 t := md5.Sum(append(info.AndroidId, info.MacAddress...)) 160 info.Guid = t[:] 161 } 162 163 func (info *Device) GenNewTgtgtKey() { 164 r := make([]byte, 16) 165 rand.Read(r) 166 h := md5.New() 167 h.Write(r) 168 h.Write(info.Guid) 169 info.TgtgtKey = h.Sum(nil) 170 } 171 172 func (info *Device) GenDeviceInfoData() []byte { 173 m := &pb.DeviceInfo{ 174 Bootloader: string(info.Bootloader), 175 ProcVersion: string(info.ProcVersion), 176 Codename: string(info.Version.CodeName), 177 Incremental: string(info.Version.Incremental), 178 Fingerprint: string(info.FingerPrint), 179 BootId: string(info.BootId), 180 AndroidId: string(info.AndroidId), 181 BaseBand: string(info.BaseBand), 182 InnerVersion: string(info.Version.Incremental), 183 } 184 data, err := proto.Marshal(m) 185 if err != nil { 186 panic(errors.Wrap(err, "failed to unmarshal protobuf message")) 187 } 188 return data 189 } 190 191 type deviceFile struct { 192 Display string `json:"display"` 193 Product string `json:"product"` 194 Device string `json:"device"` 195 Board string `json:"board"` 196 Model string `json:"model"` 197 FingerPrint string `json:"finger_print"` 198 BootId string `json:"boot_id"` 199 ProcVersion string `json:"proc_version"` 200 Protocol int `json:"protocol"` // 0: Pad 1: Phone 2: Watch 201 IMEI string `json:"imei"` 202 Brand string `json:"brand"` 203 Bootloader string `json:"bootloader"` 204 BaseBand string `json:"base_band"` 205 Version *osVersionFile `json:"version"` 206 SimInfo string `json:"sim_info"` 207 OsType string `json:"os_type"` 208 MacAddress string `json:"mac_address"` 209 IpAddress []int32 `json:"ip_address"` 210 WifiBSSID string `json:"wifi_bssid"` 211 WifiSSID string `json:"wifi_ssid"` 212 ImsiMd5 string `json:"imsi_md5"` 213 AndroidId string `json:"android_id"` 214 Apn string `json:"apn"` 215 VendorName string `json:"vendor_name"` 216 VendorOSName string `json:"vendor_os_name"` 217 } 218 219 type osVersionFile struct { 220 Incremental string `json:"incremental"` 221 Release string `json:"release"` 222 Codename string `json:"codename"` 223 Sdk uint32 `json:"sdk"` 224 }