Commit 809cfcb2 authored by Him188's avatar Him188

LoginPacket done.

parent 78ee01de
......@@ -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()
discardExact(1) // const = 0
val packet = when (val encryptionMethod = readByte().toInt()) {
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()
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())
}
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 4, got $encryptionMethod")
else -> error("Illegal encryption method. expected 0 or 4, got $encryptionMethod")
}
consumer(packet, packetFactory.id, ssoSequenceId)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment