@@ -123,7 +123,15 @@ internal class PacketCodecImpl : PacketCodec {
123
123
val raw = try {
124
124
when (encryptMethod) {
125
125
2 -> TEA .decrypt(buffer, DECRYPTER_16_ZERO , size)
126
- 1 -> TEA .decrypt(buffer, client.wLoginSigInfo.d2Key, size)
126
+ 1 -> {
127
+ TEA .decrypt(buffer, kotlin.runCatching { client.wLoginSigInfo.d2Key }.getOrElse {
128
+ throw PacketCodecException (
129
+ " 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" ,
130
+ PROTOCOL_UPDATED
131
+ )
132
+ }, size)
133
+ }
134
+
127
135
0 -> buffer
128
136
else -> throw PacketCodecException (" Unknown encrypt type=$encryptMethod " , PROTOCOL_UPDATED )
129
137
}.let { decryptedData ->
@@ -163,7 +171,7 @@ internal class PacketCodecImpl : PacketCodec {
163
171
raw.sequenceId,
164
172
raw.body.withUse {
165
173
try {
166
- parseOicqResponse(client)
174
+ parseOicqResponse(client, raw.commandName )
167
175
} catch (e: Throwable ) {
168
176
throw PacketCodecException (e, PacketCodecException .Kind .OTHER )
169
177
}
@@ -268,63 +276,85 @@ internal class PacketCodecImpl : PacketCodec {
268
276
269
277
private fun ByteReadPacket.parseOicqResponse (
270
278
client : SsoSession ,
279
+ commandName : String
271
280
): ByteArray {
272
- readByte().toInt().let {
273
- check(it == 2 ) { " $it " }
274
- }
275
- this .discardExact(2 )
276
- this .discardExact(2 )
277
- this .readUShort()
278
- this .readShort()
279
- this .readUInt().toLong()
280
- val encryptionMethod = this .readUShort().toInt()
281
+ val qqEcdh = (client as QQAndroidClient ).bot.components[EcdhInitialPublicKeyUpdater ].getQQEcdh()
282
+ fun decrypt (encryptionMethod : Int ): ByteArray {
283
+ return when (encryptionMethod) {
284
+ 4 -> {
285
+ val size = (this .remaining - 1 ).toInt()
286
+ val data =
287
+ TEA .decrypt(
288
+ this .readBytes(),
289
+ qqEcdh.initialQQShareKey,
290
+ length = size
291
+ )
281
292
282
- this .discardExact(1 )
283
- val qqEcdh =
284
- (client as QQAndroidClient ).bot.components[EcdhInitialPublicKeyUpdater ].getQQEcdh()
285
- return when (encryptionMethod) {
286
- 4 -> {
287
- val size = (this .remaining - 1 ).toInt()
288
- val data =
293
+ val peerShareKey =
294
+ qqEcdh.calculateQQShareKey(Ecdh .Instance .importPublicKey(readUShortLVByteArray()))
295
+ TEA .decrypt(data, peerShareKey)
296
+ }
297
+
298
+ 3 -> {
299
+ val size = (this .remaining - 1 ).toInt()
300
+ // session
289
301
TEA .decrypt(
290
302
this .readBytes(),
291
- qqEcdh.initialQQShareKey ,
303
+ client.wLoginSigInfo.wtSessionTicketKey ,
292
304
length = size
293
305
)
306
+ }
294
307
295
- val peerShareKey =
296
- qqEcdh.calculateQQShareKey(Ecdh .Instance .importPublicKey(readUShortLVByteArray()))
297
- TEA .decrypt(data, peerShareKey)
298
- }
299
-
300
- 3 -> {
301
- val size = (this .remaining - 1 ).toInt()
302
- // session
303
- TEA .decrypt(
304
- this .readBytes(),
305
- client.wLoginSigInfo.wtSessionTicketKey,
306
- length = size
307
- )
308
- }
309
-
310
- 0 -> {
311
- if (client.loginState == 0 ) {
312
- val size = (this .remaining - 1 ).toInt()
313
- val byteArrayBuffer = this .readBytes(size)
314
-
315
- runCatching {
316
- TEA .decrypt(byteArrayBuffer, qqEcdh.initialQQShareKey, length = size)
317
- }.getOrElse {
318
- TEA .decrypt(byteArrayBuffer, client.randomKey, length = size)
308
+ 0 -> {
309
+ if (client.loginState == 0 ) {
310
+ val size = (this .remaining - 1 ).toInt()
311
+ val byteArrayBuffer = this .readBytes(size)
312
+
313
+ runCatching {
314
+ TEA .decrypt(byteArrayBuffer, qqEcdh.initialQQShareKey, length = size)
315
+ }.getOrElse {
316
+ TEA .decrypt(byteArrayBuffer, client.randomKey, length = size)
317
+ }
318
+ } else {
319
+ val size = (this .remaining - 1 ).toInt()
320
+ TEA .decrypt(this .readBytes(), client.randomKey, length = size)
319
321
}
320
- } else {
321
- val size = (this .remaining - 1 ).toInt()
322
- TEA .decrypt(this .readBytes(), client.randomKey, length = size)
323
322
}
323
+
324
+ else -> error(" Illegal encryption method. expected 0 or 4, got $encryptionMethod " )
324
325
}
326
+ }
325
327
326
- else -> error(" Illegal encryption method. expected 0 or 4, got $encryptionMethod " )
328
+ val packetType = readByte().toInt()
329
+ if (packetType != 2 ) {
330
+ val fullPacketDump = copy().readBytes().toUHexString()
331
+ var decryptedData: String? = null
332
+ if (remaining > 15 ) {
333
+ discardExact(12 )
334
+ val encryptionMethod = this .readUShort().toInt()
335
+ discardExact(1 )
336
+ decryptedData = kotlin.runCatching {
337
+ decrypt(encryptionMethod).toUHexString()
338
+ }.getOrNull()
339
+ }
340
+ throw PacketCodecException (
341
+ " Received unknown oicq packet type = $packetType , command name = $commandName , ignoring..." +
342
+ " \n Please report this message to https://github.com/mamoe/mirai/issues/new/choose, \n " +
343
+ " Full packet dump: $fullPacketDump \n " +
344
+ " Decrypted data (contains your encrypted password, please change your password after reporting issue): $decryptedData " ,
345
+ PROTOCOL_UPDATED
346
+ )
327
347
}
348
+
349
+ this .discardExact(2 )
350
+ this .discardExact(2 )
351
+ this .readUShort()
352
+ this .readShort()
353
+ this .readUInt().toLong()
354
+ val encryptionMethod = this .readUShort().toInt()
355
+
356
+ this .discardExact(1 )
357
+ return decrypt(encryptionMethod)
328
358
}
329
359
330
360
/* *
@@ -363,4 +393,4 @@ internal class RawIncomingPacket constructor(
363
393
* Can be passed to [PacketFactory]
364
394
*/
365
395
val body : ByteArray ,
366
- )
396
+ )
0 commit comments