[core] Handle rare case on packet pipeline (#2450)

* Handle rare case on packet pipeline
Fix #2449, should help #1603

* Fix and improve tips and improve the readability of code

* Improve wording of tips

Co-authored-by: Him188 <Him188@mamoe.net>

* Change d2Key error type to PROTOCOL_UPDATED

* Reformat code

---------

Co-authored-by: Him188 <Him188@mamoe.net>
This commit is contained in:
sandtechnology 2023-03-21 22:43:48 +08:00 committed by GitHub
parent 403380514a
commit 28b1032acd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -123,7 +123,15 @@ internal class PacketCodecImpl : PacketCodec {
val raw = try { val raw = try {
when (encryptMethod) { when (encryptMethod) {
2 -> TEA.decrypt(buffer, DECRYPTER_16_ZERO, size) 2 -> TEA.decrypt(buffer, DECRYPTER_16_ZERO, size)
1 -> TEA.decrypt(buffer, client.wLoginSigInfo.d2Key, size) 1 -> {
TEA.decrypt(buffer, kotlin.runCatching { client.wLoginSigInfo.d2Key }.getOrElse {
throw PacketCodecException(
"Received packet needed d2Key to decrypt but d2Key doesn't existed, ignoring. Please report to https://github.com/mamoe/mirai/issues/new/choose if you see anything abnormal",
PROTOCOL_UPDATED
)
}, size)
}
0 -> buffer 0 -> buffer
else -> throw PacketCodecException("Unknown encrypt type=$encryptMethod", PROTOCOL_UPDATED) else -> throw PacketCodecException("Unknown encrypt type=$encryptMethod", PROTOCOL_UPDATED)
}.let { decryptedData -> }.let { decryptedData ->
@ -163,7 +171,7 @@ internal class PacketCodecImpl : PacketCodec {
raw.sequenceId, raw.sequenceId,
raw.body.withUse { raw.body.withUse {
try { try {
parseOicqResponse(client) parseOicqResponse(client, raw.commandName)
} catch (e: Throwable) { } catch (e: Throwable) {
throw PacketCodecException(e, PacketCodecException.Kind.OTHER) throw PacketCodecException(e, PacketCodecException.Kind.OTHER)
} }
@ -268,20 +276,10 @@ internal class PacketCodecImpl : PacketCodec {
private fun ByteReadPacket.parseOicqResponse( private fun ByteReadPacket.parseOicqResponse(
client: SsoSession, client: SsoSession,
commandName: String
): ByteArray { ): ByteArray {
readByte().toInt().let { val qqEcdh = (client as QQAndroidClient).bot.components[EcdhInitialPublicKeyUpdater].getQQEcdh()
check(it == 2) { "$it" } fun decrypt(encryptionMethod: Int): ByteArray {
}
this.discardExact(2)
this.discardExact(2)
this.readUShort()
this.readShort()
this.readUInt().toLong()
val encryptionMethod = this.readUShort().toInt()
this.discardExact(1)
val qqEcdh =
(client as QQAndroidClient).bot.components[EcdhInitialPublicKeyUpdater].getQQEcdh()
return when (encryptionMethod) { return when (encryptionMethod) {
4 -> { 4 -> {
val size = (this.remaining - 1).toInt() val size = (this.remaining - 1).toInt()
@ -327,6 +325,38 @@ internal class PacketCodecImpl : PacketCodec {
} }
} }
val packetType = readByte().toInt()
if (packetType != 2) {
val fullPacketDump = copy().readBytes().toUHexString()
var decryptedData: String? = null
if (remaining > 15) {
discardExact(12)
val encryptionMethod = this.readUShort().toInt()
discardExact(1)
decryptedData = kotlin.runCatching {
decrypt(encryptionMethod).toUHexString()
}.getOrNull()
}
throw PacketCodecException(
"Received unknown oicq packet type = $packetType, command name = $commandName, ignoring..." +
"\nPlease report this message to https://github.com/mamoe/mirai/issues/new/choose, \n" +
"Full packet dump: $fullPacketDump\n" +
"Decrypted data (contains your encrypted password, please change your password after reporting issue): $decryptedData",
PROTOCOL_UPDATED
)
}
this.discardExact(2)
this.discardExact(2)
this.readUShort()
this.readShort()
this.readUInt().toLong()
val encryptionMethod = this.readUShort().toInt()
this.discardExact(1)
return decrypt(encryptionMethod)
}
/** /**
* Process [RawIncomingPacket] using [IncomingPacketFactory.decode]. * Process [RawIncomingPacket] using [IncomingPacketFactory.decode].
* *