mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 18:00:33 +08:00
Fix captcha packet
This commit is contained in:
parent
29ded71c69
commit
70f0228804
@ -78,8 +78,22 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
writeFully(TIMProtocol.fixVer)
|
||||
writeFully(TIMProtocol.key00BA)
|
||||
encryptAndWrite(TIMProtocol.key00BA) {
|
||||
|
||||
//00 02 00 00 08 04 01 E0
|
||||
// 00 00 04 56 00 00 00 01 00 00 15 E3 01
|
||||
// 00 38 58 CE A0 12 81 31 5C 5E 36 23 5B E4 0E 05 A6 47 BF 7C 1A 7A 35 37 59 90 17 50 66 0C 07 03 77 E4 48 DB 28 0A CF C3 A9 B7 C0 95 D3 9D 00 AA A5 EB FB D6 85 8D 10 61 5A D0
|
||||
// 01 03
|
||||
// 00 19 02 CA 53 7E F0 7B 32 82 EC 9F DE CF 51 8B A4 93 26 76 EC 42 1C 02 00 74 58
|
||||
// 14 00 05 00 00 00 00 00
|
||||
// 04
|
||||
// 6C 73 64 61
|
||||
//
|
||||
// 00 40 CE 99 84 E8 F1 59 31 B0 3F 6C 4D 44 09 E4 82 77 96 67 03 A7 3A EA 8F 36 B9 20 79 7E C9 0F 75 3C 2A C3 E1 E5 C6 00 B3 5E 91 5B 47 63 EF AF 30 C0 48 2F 58 23 96 CF 65 2F 4C 75 95 A6 CA 5A 2C 5C
|
||||
//
|
||||
// 00 10 E1 50 C9 F4 F6 F4 2F D1 7F E9 8C AB B6 1C 38 7B
|
||||
|
||||
writeHex("00 02 00 00 08 04 01 E0")
|
||||
writeFully(TIMProtocol.constantData2)
|
||||
writeFully(TIMProtocol.constantData2) //00 00 04 53 00 00 00 01 00 00 15 85
|
||||
writeHex("01 00 38")
|
||||
writeFully(token0825)
|
||||
writeHex("01 03")
|
||||
@ -89,7 +103,7 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
|
||||
writeHex("14 00 05 00 00 00 00 00 04")
|
||||
writeStringUtf8(captcha.toUpperCase())
|
||||
writeHex("00 38")
|
||||
writeHex("00 40")
|
||||
writeFully(captchaToken)
|
||||
|
||||
writeShort(16)
|
||||
@ -106,7 +120,7 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
|
||||
class Transmission : CaptchaResponse() {
|
||||
lateinit var captchaSectionN: IoBuffer
|
||||
lateinit var captchaToken: IoBuffer//56bytes
|
||||
lateinit var captchaToken: IoBuffer//0x40=64bytes
|
||||
var transmissionCompleted: Boolean = false//验证码是否已经传输完成
|
||||
override fun toString(): String = "CaptchaResponse.Transmission"
|
||||
}
|
||||
@ -133,7 +147,7 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
* 00 10 CC A9 FA 63 A8 34 C7 3C E6 F7 2E 15 B7 EF 3E 07
|
||||
*/
|
||||
discardExact(7)
|
||||
captchaToken = readIoBuffer(readUShort().toInt()) // 56
|
||||
captchaToken = readIoBuffer(readUShort().toInt()) // 0x40=64,
|
||||
|
||||
/*
|
||||
*00 05 01 00 00 01 23
|
||||
@ -158,6 +172,22 @@ internal object CaptchaPacket : PacketFactory<CaptchaPacket.CaptchaResponse, Cap
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
发出包ID = CaptchaPacket(00 BA)
|
||||
sequence = 71 6B
|
||||
fixVer2=03 00 01 00 01 2E 01 00 00 69 35 00 00 00 00
|
||||
密文=65 F7 F3 14 E3 94 10 1F DD 95 84 A3 F5 9F AD 94 8D 4F 6A 70 F8 4A DE 43 AF 75 D1 3F 3A 3F F2 E0 A8 16 1A 46 13 CD B0 51 45 00 29 52 57 75 6D 4A 4C D9 B7 98 8C B0 96 EC 57 4E 67 FB 8D C5 F1 BF 72 38 40 42 19 54 C2 28 F4 72 C8 AE 24 EB 66 B5 D0 45 0B 72 44 81 E2 F6 2B EE C3 85 93 BA CB B7 72 F4 1A 30 F9 5B 3D B0 79 3E F4 0B F2 1A A7 49 60 3B 37 02 60 0C 5D D5 76 76 47 4F B5 B3 F5 CA 58 6C FC D2 41 3E 24 D1 FB 0A 18 53 D8 E5 A5 85 A8 BC 51 54 3B 66 5B 21 C6 7B AF C9 62 F0 AA 9C CF 2E 84 0F CC 15 5B 35 93 49 5C E4 28 49 A7 8A D3 30 A9 6E 36 4E 7A 49 28 69 4D C3 25 39 6E 45 6E 40 F2 86 1E F4 4F 00 A6 9D E6 9B 84 19 69 C1 31 6A 17 BA F0 0D 8A 22 09 86 24 92 F7 22 C3 47 7F F2 BF 94 8A 8A B5 29
|
||||
解密body=
|
||||
00 02 00 00 08 04 01 E0 00 00 04 56 00 00 00 01 00 00 15 E3 01 00 38 58 CE A0 12 81 31 5C 5E 36 23 5B E4 0E 05 A6 47 BF 7C 1A 7A 35 37 59 90 17 50 66 0C 07 03 77 E4 48 DB 28 0A CF C3 A9 B7 C0 95 D3 9D 00 AA A5 EB FB D6 85 8D 10 61 5A D0 01 03 00 19 02 CA 53 7E F0 7B 32 82 EC 9F DE CF 51 8B A4 93 26 76 EC 42 1C 02 00 74 58 14 00 05 00 00 00 00 00 04 6C 73 64 61 00 40 CE 99 84 E8 F1 59 31 B0 3F 6C 4D 44 09 E4 82 77 96 67 03 A7 3A EA 8F 36 B9 20 79 7E C9 0F 75 3C 2A C3 E1 E5 C6 00 B3 5E 91 5B 47 63 EF AF 30 C0 48 2F 58 23 96 CF 65 2F 4C 75 95 A6 CA 5A 2C 5C 00 10 E1 50 C9 F4 F6 F4 2F D1 7F E9 8C AB B6 1C 38 7B
|
||||
--------------
|
||||
接收包id=CaptchaPacket(00 BA),
|
||||
sequence=71 6B
|
||||
密文body=92 74 E1 41 8D DE AA 26 5B 3E 8F 91 E0 DC 41 DD 39 EF 1E 2F FD 0E 19 41 B2 AD 8F A1 8D 5D C7 D4 D5 36 2B 51 E5 05 91 9F EE 89 82 B0 C6 B7 EC BE 40 8A 7E 06 FC 82 FA 39 AC 54 94 27 26 8D 71 46 1A F2 BB 23 A8 7E 15 69 8A C7 00 D1 52 06 2C 8B
|
||||
解密body=解密失败
|
||||
|
||||
*/
|
||||
|
||||
else -> error("Unable to analyze RequestCaptchaTransmissionPacket, unknown id: $flag")
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,10 @@ import kotlin.random.Random
|
||||
/**
|
||||
* 解密错误
|
||||
*/
|
||||
internal class DecryptionFailedException : Exception()
|
||||
internal class DecryptionFailedException : Exception {
|
||||
constructor() : super()
|
||||
constructor(message: String?) : super(message)
|
||||
}
|
||||
|
||||
|
||||
// region encrypt
|
||||
@ -360,6 +363,8 @@ private object TEA {
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
private inline fun ByteArray.checkDataLengthAndReturnSelf(length: Int = this.size): ByteArray {
|
||||
require(length % 8 == 0 && length >= 16) { "data must len % 8 == 0 && len >= 16 but given (length=$length) ${this.toUHexString()}" }
|
||||
if (!(length % 8 == 0 && length >= 16)) {
|
||||
throw DecryptionFailedException("data must len % 8 == 0 && len >= 16 but given (length=$length) ${this.toUHexString()}")
|
||||
}
|
||||
return this
|
||||
}
|
@ -156,8 +156,8 @@ suspend fun main() {
|
||||
}
|
||||
}
|
||||
|
||||
decryptRecordedPackets(null)
|
||||
//startPacketListening()
|
||||
//decryptRecordedPackets(null)
|
||||
startPacketListening()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +188,7 @@ internal object PacketDebugger {
|
||||
/**
|
||||
* null 则不筛选
|
||||
*/
|
||||
val qq: UInt? = 215555909u
|
||||
val qq: UInt? = null
|
||||
/**
|
||||
* 打开后则记录每一个包到文件.
|
||||
*/
|
||||
@ -219,12 +219,13 @@ internal object PacketDebugger {
|
||||
|
||||
discardExact(3)//0x00 0x00 0x00. 但更可能是应该 discard 8
|
||||
// val remaining = this.readRemainingBytes().cutTail(1)
|
||||
val encryptedBody = this@read.readRemainingBytes().cutTail(1)
|
||||
try {
|
||||
lateinit var decodedBody: ByteArray
|
||||
val packet = use {
|
||||
with(id.factory) {
|
||||
provideDecrypter(id.factory)
|
||||
.decrypt(this@read.readRemainingBytes().let { ByteReadPacket(it, 0, it.size - 1) })
|
||||
.decrypt(ByteReadPacket(encryptedBody))
|
||||
.let {
|
||||
decodedBody = it.readBytes()
|
||||
ByteReadPacket(decodedBody)
|
||||
@ -246,10 +247,10 @@ internal object PacketDebugger {
|
||||
}
|
||||
|
||||
//handlePacket(id, sequenceId, packet, id.factory)
|
||||
} catch (e: DecryptionFailedException) {
|
||||
// println("密文body=" + remaining.toUHexString())
|
||||
} catch (e: Exception) {
|
||||
println("--------------")
|
||||
println("接收包id=$id, \nsequence=${sequenceId.toUHexString()}")
|
||||
println(" 密文body=" + encryptedBody.toUHexString())
|
||||
println(" 解密body=解密失败")
|
||||
} finally {
|
||||
|
||||
@ -271,7 +272,7 @@ internal object PacketDebugger {
|
||||
|
||||
SessionKey -> sessionKey
|
||||
|
||||
else -> error("No decrypter is found")
|
||||
else -> error("No decrypter is found for ${factory.decrypterType}")
|
||||
} as? D ?: error("Internal error: could not cast decrypter which is found for factory to class Decrypter")
|
||||
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
package mirai.test.packetdebugger
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUShort
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.PacketId
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.CaptchaPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.matchPacketId
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@UseExperimental(ExperimentalUnsignedTypes::class)
|
||||
class PacketDecoderScope(
|
||||
val packet: ByteReadPacket
|
||||
) {
|
||||
@PublishedApi
|
||||
internal var _id: UShort = 0u
|
||||
@PublishedApi
|
||||
internal var _sequence: UShort = 0u
|
||||
|
||||
internal val id: PacketId get() = matchPacketId(_id)
|
||||
val sequence: UShort get() = _sequence
|
||||
}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
inline fun ByteReadPacket.decodeOutgoingPacket(block: PacketDecoderScope.() -> Unit) {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
this.use {
|
||||
PacketDecoderScope(it).apply {
|
||||
discardExact(1) // head
|
||||
discardExact(2) // ver
|
||||
_id = readUShort()
|
||||
_sequence = readUShort()
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package mirai.test.testCaptchaPacket
|
||||
|
||||
import net.mamoe.mirai.utils.decryptBy
|
||||
import net.mamoe.mirai.utils.io.hexToBytes
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
|
||||
|
||||
fun main() {
|
||||
val key = "65 F7 F3 14 E3 94 10 1F DD 95 84 A3 F5 9F AD 94".hexToBytes()
|
||||
val data =
|
||||
"8D 4F 6A 70 F8 4A DE 43 AF 75 D1 3F 3A 3F F2 E0 A8 16 1A 46 13 CD B0 51 45 00 29 52 57 75 6D 4A 4C D9 B7 98 8C B0 96 EC 57 4E 67 FB 8D C5 F1 BF 72 38 40 42 19 54 C2 28 F4 72 C8 AE 24 EB 66 B5 D0 45 0B 72 44 81 E2 F6 2B EE C3 85 93 BA CB B7 72 F4 1A 30 F9 5B 3D B0 79 3E F4 0B F2 1A A7 49 60 3B 37 02 60 0C 5D D5 76 76 47 4F B5 B3 F5 CA 58 6C FC D2 41 3E 24 D1 FB 0A 18 53 D8 E5 A5 85 A8 BC 51 54 3B 66 5B 21 C6 7B AF C9 62 F0 AA 9C CF 2E 84 0F CC 15 5B 35 93 49 5C E4 28 49 A7 8A D3 30 A9 6E 36 4E 7A 49 28 69 4D C3 25 39 6E 45 6E 40 F2 86 1E F4 4F 00 A6 9D E6 9B 84 19 69 C1 31 6A 17 BA F0 0D 8A 22 09 86 24 92 F7 22 C3 47 7F F2 BF 94 8A 8A B5 29".hexToBytes()
|
||||
.decryptBy(key)
|
||||
println(data.toUHexString())
|
||||
|
||||
//00 02 00 00 08 04 01 E0 00 00 04 56 00 00 00 01 00 00 15 E3 01 00 38 58 CE A0 12 81 31 5C 5E 36 23 5B E4 0E 05 A6 47 BF 7C 1A 7A 35 37 59 90 17 50 66 0C 07 03 77 E4 48 DB 28 0A CF C3 A9 B7 C0 95 D3 9D 00 AA A5 EB FB D6 85 8D 10 61 5A D0 01 03 00 19 02 CA 53 7E F0 7B 32 82 EC 9F DE CF 51 8B A4 93 26 76 EC 42 1C 02 00 74 58 14 00 05 00 00 00 00 00 04 6C 73 64 61 00 40 CE 99 84 E8 F1 59 31 B0 3F 6C 4D 44 09 E4 82 77 96 67 03 A7 3A EA 8F 36 B9 20 79 7E C9 0F 75 3C 2A C3 E1 E5 C6 00 B3 5E 91 5B 47 63 EF AF 30 C0 48 2F 58 23 96 CF 65 2F 4C 75 95 A6 CA 5A 2C 5C 00 10 E1 50 C9 F4 F6 F4 2F D1 7F E9 8C AB B6 1C 38 7B
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user