From 760075e9140c01a55711fa2d2cf09ae27252e74e Mon Sep 17 00:00:00 2001 From: sandtechnology <a1294790523@hotmail.com> Date: Sun, 18 Jun 2023 19:58:50 +0800 Subject: [PATCH] [core] Fix wrong SSOReserveField proto and packet codec 1.Body is a lambda function, so invoke it by only once 2.Fix wrong protoBuf serializer, use protocol one 3.Pass all packets to EncryptService (which packet should be sign should judge by service itself) 4.Fix wrong proto number and add missed default value, also fix proto naming --- .../protocol/data/proto/SSOReserveField.kt | 74 +++++++++---------- .../network/protocol/packet/OutgoingPacket.kt | 50 ++++++------- 2 files changed, 61 insertions(+), 63 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/SSOReserveField.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/SSOReserveField.kt index 467050106..7e6f86f08 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/SSOReserveField.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/SSOReserveField.kt @@ -17,46 +17,46 @@ import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY internal class SSOReserveField { @Serializable internal class ReserveFields( - @JvmField @ProtoNumber(1) val client_ipcookie: ByteArray = EMPTY_BYTE_ARRAY, - @JvmField @ProtoNumber(2) val flag: Int = 0, - @JvmField @ProtoNumber(3) val env_id: Int = 0, - @JvmField @ProtoNumber(4) val locale_id: Int = 0, - @JvmField @ProtoNumber(5) val qimei: ByteArray = EMPTY_BYTE_ARRAY, - @JvmField @ProtoNumber(6) val env: String = "", - @JvmField @ProtoNumber(7) val newconn_flag: Int = 0, - @JvmField @ProtoNumber(8) val trace_parent: String = "", - @JvmField @ProtoNumber(9) val uid: String = "", - @JvmField @ProtoNumber(10) val imsi: Int = 0, - @JvmField @ProtoNumber(11) val network_type: Int = 0, - @JvmField @ProtoNumber(12) val ip_stack_type: Int = 0, - @JvmField @ProtoNumber(13) val message_type: Int = 0, - @JvmField @ProtoNumber(14) val trpc_rsp: SsoTrpcResponse? = null, - @JvmField @ProtoNumber(15) val trans_info: List<SsoMapEntry>? = null, - @JvmField @ProtoNumber(16) val sec_info: SsoSecureInfo? = null, - @JvmField @ProtoNumber(17) val sec_sig_flag: Int = 0, - @JvmField @ProtoNumber(18) val nt_core_version: Int = 0, - @JvmField @ProtoNumber(19) val sso_route_cost: Int = 0, - @JvmField @ProtoNumber(20) val sso_ip_origin: Int = 0, - @JvmField @ProtoNumber(21) val presure_token: ByteArray = EMPTY_BYTE_ARRAY, - ) : ProtoBuf - - @Serializable - internal class SsoSecureInfo( - @JvmField @ProtoNumber(1) val sec_sig: ByteArray = EMPTY_BYTE_ARRAY, - @JvmField @ProtoNumber(2) val sec_device_token: ByteArray = EMPTY_BYTE_ARRAY, - @JvmField @ProtoNumber(3) val sec_extra: ByteArray = EMPTY_BYTE_ARRAY, - ) : ProtoBuf - - @Serializable - internal class SsoTrpcResponse( - @JvmField @ProtoNumber(1) val ret: Int = 0, - @JvmField @ProtoNumber(2) val func_ret: Int = 0, - @JvmField @ProtoNumber(3) val error_msg: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(8) @JvmField val clientIpcookie: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(9) @JvmField val flag: Int = 0, + @ProtoNumber(10) @JvmField val envId: Int = 0, + @ProtoNumber(11) @JvmField val localeId: Int = 2052, + @ProtoNumber(12) @JvmField val qimei: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(13) @JvmField val env: String = "", + @ProtoNumber(14) @JvmField val newconnFlag: Int = 0, + @ProtoNumber(15) @JvmField val traceParent: String = "", + @ProtoNumber(16) @JvmField val uid: String = "", + @ProtoNumber(18) @JvmField val imsi: Int = 0, + @ProtoNumber(19) @JvmField val networkType: Int = 0, + @ProtoNumber(20) @JvmField val ipStackType: Int = 0, + @ProtoNumber(21) @JvmField val messageType: Int = 0, + @ProtoNumber(22) @JvmField val trpcRsp: SsoTrpcResponse? = null, + @ProtoNumber(23) @JvmField val transInfo: List<SsoMapEntry> = emptyList(), + @ProtoNumber(24) @JvmField val secInfo: SsoSecureInfo? = null, + @ProtoNumber(25) @JvmField val secSigFlag: Int = 0, + @ProtoNumber(26) @JvmField val ntCoreVersion: Int = 0, + @ProtoNumber(27) @JvmField val ssoRouteCost: Int = 0, + @ProtoNumber(28) @JvmField val ssoIpOrigin: Int = 0, + @ProtoNumber(30) @JvmField val presureToken: ByteArray = EMPTY_BYTE_ARRAY ) : ProtoBuf @Serializable internal class SsoMapEntry( - @JvmField @ProtoNumber(1) val key: String = "", - @JvmField @ProtoNumber(2) val value: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(1) @JvmField val key: String = "", + @ProtoNumber(2) @JvmField val value: ByteArray = EMPTY_BYTE_ARRAY + ) : ProtoBuf + + @Serializable + internal class SsoSecureInfo( + @ProtoNumber(1) @JvmField val secSig: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(2) @JvmField val secDeviceToken: ByteArray = EMPTY_BYTE_ARRAY, + @ProtoNumber(3) @JvmField val secExtra: ByteArray = EMPTY_BYTE_ARRAY + ) : ProtoBuf + + @Serializable + internal class SsoTrpcResponse( + @ProtoNumber(1) @JvmField val ret: Int = 0, + @ProtoNumber(2) @JvmField val funcRet: Int = 0, + @ProtoNumber(3) @JvmField val errorMsg: ByteArray = EMPTY_BYTE_ARRAY ) : ProtoBuf } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt index b71f02a62..a2f8a2dfd 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/OutgoingPacket.kt @@ -12,11 +12,11 @@ package net.mamoe.mirai.internal.network.protocol.packet import io.ktor.utils.io.core.* import kotlinx.serialization.encodeToByteArray +import kotlinx.serialization.protobuf.ProtoBuf import net.mamoe.mirai.internal.QQAndroidBot import net.mamoe.mirai.internal.network.* import net.mamoe.mirai.internal.network.components.EcdhInitialPublicKeyUpdater import net.mamoe.mirai.internal.network.protocol.data.proto.SSOReserveField -import net.mamoe.mirai.internal.network.protocol.packet.chat.receive.MessageSvcPbSendMsg import net.mamoe.mirai.internal.network.protocol.packet.sso.TRpcRawPacket import net.mamoe.mirai.internal.spi.EncryptService import net.mamoe.mirai.internal.spi.EncryptServiceContext @@ -314,14 +314,10 @@ internal inline fun BytePacketBuilder.writeSsoPacket( * 00 00 00 04 */ val encryptWorker = EncryptService.instance + val bodyBytes = buildPacket(body).readBytes() + val reserveField = if (encryptWorker != null) { - val reserveField = if ( - commandName.startsWith("wtlogin") - || commandName == MessageSvcPbSendMsg.commandName - || encryptWorker != null - ) { - - val signResult = encryptWorker?.qSecurityGetSign( + val signResult = encryptWorker.qSecurityGetSign( EncryptServiceContext(client.uin, buildTypeSafeMap { set(EncryptServiceContext.KEY_APP_QUA, "V1_AND_SQ_8.9.58_4106_YYB_D") // 8.9.58 set(EncryptServiceContext.KEY_CHANNEL_PROXY, createChannelProxy(client.bot)) @@ -330,25 +326,27 @@ internal inline fun BytePacketBuilder.writeSsoPacket( }), sequenceId, commandName, - buildPacket(body).readBytes() + bodyBytes ) - if (signResult != null) ProtoBufForCache.encodeToByteArray( - SSOReserveField.ReserveFields( - flag = 0, - qimei = client.qimei16?.toByteArray() ?: EMPTY_BYTE_ARRAY, - newconn_flag = 0, - uid = client.uin.toString(), - imsi = 0, - network_type = 1, - ip_stack_type = 1, - message_type = 0, - sec_info = SSOReserveField.SsoSecureInfo( - sec_sig = signResult.sign, - sec_device_token = signResult.token, - sec_extra = signResult.extra + if (signResult != null) + ProtoBuf.encodeToByteArray( + SSOReserveField.ReserveFields( + flag = 0, + qimei = client.qimei16?.toByteArray() ?: EMPTY_BYTE_ARRAY, + newconnFlag = 0, + uid = client.uin.toString(), + imsi = 0, + networkType = 1, + ipStackType = 1, + messageType = 0, + secInfo = SSOReserveField.SsoSecureInfo( + secSig = signResult.sign, + secDeviceToken = signResult.token, + secExtra = signResult.extra + ), + ssoIpOrigin = 0, ) - ) - ) else EMPTY_BYTE_ARRAY + ) else EMPTY_BYTE_ARRAY } else EMPTY_BYTE_ARRAY writeIntLVPacket(lengthOffset = { it + 4 }) { @@ -387,7 +385,7 @@ internal inline fun BytePacketBuilder.writeSsoPacket( } // body - writeIntLVPacket(lengthOffset = { it + 4 }, builder = body) + writeIntLVPacket(lengthOffset = { it + 4 }, builder = { writeFully(bodyBytes) }) } internal fun BytePacketBuilder.writeOicqRequestPacket(