mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-08 17:20:11 +08:00
LoginPacket done.
This commit is contained in:
parent
78ee01ded1
commit
809cfcb299
@ -54,12 +54,12 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
|
||||
}
|
||||
|
||||
launch(CoroutineName("Incoming Packet handler")) {
|
||||
rawInput.debugPrint("Received").use {
|
||||
if (it.remaining == 0L) {
|
||||
rawInput.debugPrint("Received").use { input ->
|
||||
if (input.remaining == 0L) {
|
||||
bot.logger.error("Empty packet received. Consider if bad packet was sent.")
|
||||
return@launch
|
||||
}
|
||||
KnownPacketFactories.parseIncomingPacket(bot, rawInput) { packet: Packet, packetId: PacketId, sequenceId: Int ->
|
||||
KnownPacketFactories.parseIncomingPacket(bot, input) { packet: Packet, packetId: PacketId, sequenceId: Int ->
|
||||
if (PacketReceivedEvent(packet).broadcast().cancelled) {
|
||||
return@parseIncomingPacket
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ internal open class QQAndroidClient(
|
||||
|
||||
val apkVersionName: ByteArray = "8.2.0".toByteArray()
|
||||
|
||||
var loginState = 0
|
||||
|
||||
val appClientVersion: Int = 0
|
||||
|
||||
var networkType: NetworkType = NetworkType.WIFI
|
||||
|
@ -257,16 +257,16 @@ internal interface EncryptMethodECDH : EncryptMethod {
|
||||
writeFully(ByteArray(16))
|
||||
writeShort(258) // const
|
||||
|
||||
writeShortLVByteArray("04 CB 36 66 98 56 1E 93 6E 80 C1 57 E0 74 CA B1 3B 0B B6 8D DE B2 82 45 48 A1 B1 8D D4 FB 61 22 AF E1 2F E4 8C 52 66 D8 D7 26 9D 76 51 A8 EB 6F E7".hexToBytes())
|
||||
// writeShortLVByteArray("04 CB 36 66 98 56 1E 93 6E 80 C1 57 E0 74 CA B1 3B 0B B6 8D DE B2 82 45 48 A1 B1 8D D4 FB 61 22 AF E1 2F E4 8C 52 66 D8 D7 26 9D 76 51 A8 EB 6F E7".hexToBytes())
|
||||
|
||||
/*writeShortLVByteArray(ecdh.keyPair.publicKey.getEncoded().drop(23).take(49).toByteArray().also {
|
||||
writeShortLVByteArray(ecdh.keyPair.publicKey.getEncoded().drop(23).take(49).toByteArray().also {
|
||||
it.toUHexString().debugPrint("PUBLIC KEY")
|
||||
check(it[0].toInt() == 0x04) { "Bad publicKey generated. Expected first element=0x04, got${it[0]}" }
|
||||
//check(ecdh.calculateShareKeyByPeerPublicKey(it.adjustToPublicKey()).contentEquals(ecdh.keyPair.shareKey)) { "PublicKey Validation failed" }
|
||||
})*/
|
||||
})
|
||||
|
||||
encryptAndWrite("26 33 BA EC 86 EB 79 E6 BC E0 20 06 5E A9 56 6C".hexToBytes(), body)
|
||||
//encryptAndWrite(ecdh.keyPair.shareKey, body)
|
||||
// encryptAndWrite("26 33 BA EC 86 EB 79 E6 BC E0 20 06 5E A9 56 6C".hexToBytes(), body)
|
||||
encryptAndWrite(ecdh.keyPair.shareKey, body)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,10 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.IoBuffer
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.LoginPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.NullPacketId
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.NullPacketId.commandName
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.login.PacketId
|
||||
@ -16,6 +18,7 @@ import net.mamoe.mirai.utils.cryptor.decryptBy
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
* 一种数据包的处理工厂. 它可以解密解码服务器发来的这个包, 也可以编码加密要发送给服务器的这个包
|
||||
@ -41,11 +44,20 @@ internal abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypt
|
||||
abstract suspend fun ByteReadPacket.decode(bot: QQAndroidBot): TPacket
|
||||
}
|
||||
|
||||
@JvmName("decode0")
|
||||
private suspend inline fun <P : Packet> PacketFactory<P, *>.decode(bot: QQAndroidBot, packet: ByteReadPacket): P {
|
||||
return this.run {
|
||||
packet.decode(bot)
|
||||
}
|
||||
}
|
||||
|
||||
private val DECRYPTER_16_ZERO = ByteArray(16)
|
||||
|
||||
internal typealias PacketConsumer = suspend (packet: Packet, packetId: PacketId, ssoSequenceId: Int) -> Unit
|
||||
|
||||
internal object KnownPacketFactories : List<PacketFactory<*, *>> by mutableListOf() {
|
||||
internal object KnownPacketFactories : List<PacketFactory<*, *>> by mutableListOf(
|
||||
LoginPacket
|
||||
) {
|
||||
|
||||
fun findPacketFactory(commandName: String): PacketFactory<*, *> = this.first { it.id.commandName == commandName }
|
||||
|
||||
@ -61,9 +73,6 @@ internal object KnownPacketFactories : List<PacketFactory<*, *>> by mutableListO
|
||||
when (val flag1 = readInt()) {
|
||||
0x0A -> when (val flag2 = readByte().toInt()) {
|
||||
0x02 -> {
|
||||
val extraData = readIoBuffer(readInt() - 4).debugCopyUse {
|
||||
this.debugPrint("Extra data")
|
||||
}
|
||||
val flag3 = readByte().toInt()
|
||||
check(flag3 == 0) { "Illegal flag3. Expected 0, got $flag3" }
|
||||
|
||||
@ -90,33 +99,55 @@ internal object KnownPacketFactories : List<PacketFactory<*, *>> by mutableListO
|
||||
|
||||
commandName = readString(readInt() - 4)
|
||||
val unknown = readBytes(readInt() - 4)
|
||||
if (unknown.toInt() != 0x02B05B8B) DebugLogger.debug("got new unknown: $unknown")
|
||||
if (unknown.toInt() != 0x02B05B8B) DebugLogger.debug("got new unknown: ${unknown.toUHexString()}")
|
||||
|
||||
check(readInt() == 0)
|
||||
}
|
||||
|
||||
bot.logger.verbose(commandName)
|
||||
val packetFactory = findPacketFactory(commandName)
|
||||
|
||||
val qq: Long
|
||||
val subCommandId: Int
|
||||
readIoBuffer(readInt() - 4).withUse {
|
||||
check(readByte().toInt() == 2)
|
||||
discardExact(2) // 27 + 2 + body.size
|
||||
discardExact(2) // const, =8001
|
||||
readShort() // commandId
|
||||
readShort() // innerSequenceId
|
||||
qq = readInt().toLong()
|
||||
this.discardExact(2) // 27 + 2 + body.size
|
||||
this.discardExact(2) // const, =8001
|
||||
this.readShort() // commandId
|
||||
this.readShort() // const, =0x0001
|
||||
qq = this.readInt().toLong()
|
||||
val encryptionMethod = this.readShort().toInt()
|
||||
|
||||
discardExact(1) // const = 0
|
||||
val packet = when (val encryptionMethod = readByte().toInt()) {
|
||||
this.discardExact(1) // const = 0
|
||||
val packet = when (encryptionMethod) {
|
||||
4 -> { // peer public key, ECDH
|
||||
packetFactory.run {
|
||||
bot.client.ecdh.calculateShareKeyByPeerPublicKey(readUShortLVByteArray().adjustToPublicKey()).read {
|
||||
decode(bot)
|
||||
}
|
||||
}
|
||||
var data = this.decryptBy(bot.client.ecdh.keyPair.shareKey, this.readRemaining - 1)
|
||||
|
||||
val peerShareKey = bot.client.ecdh.calculateShareKeyByPeerPublicKey(readUShortLVByteArray().adjustToPublicKey())
|
||||
data = data.decryptBy(peerShareKey)
|
||||
|
||||
packetFactory.decode(bot, data.toReadPacket())
|
||||
}
|
||||
else -> error("Illegal encryption method. expected 4, got $encryptionMethod")
|
||||
0 -> {
|
||||
val data = if (bot.client.loginState == 0) {
|
||||
ByteArrayPool.useInstance { byteArrayBuffer ->
|
||||
val size = this.readRemaining - 1
|
||||
this.readFully(byteArrayBuffer, 0, size)
|
||||
|
||||
runCatching {
|
||||
byteArrayBuffer.decryptBy(bot.client.ecdh.keyPair.shareKey, size)
|
||||
}.getOrElse {
|
||||
byteArrayBuffer.decryptBy(bot.client.tgtgtKey, size)
|
||||
} // 这里实际上应该用 privateKey(另一个random出来的key)
|
||||
}
|
||||
} else {
|
||||
this.decryptBy(bot.client.tgtgtKey, 0, this.readRemaining - 1)
|
||||
}
|
||||
|
||||
packetFactory.decode(bot, data.toReadPacket())
|
||||
|
||||
}
|
||||
else -> error("Illegal encryption method. expected 0 or 4, got $encryptionMethod")
|
||||
}
|
||||
|
||||
consumer(packet, packetFactory.id, ssoSequenceId)
|
||||
|
Loading…
Reference in New Issue
Block a user