From ffe8339c9cba044763f365b6265d847b05735299 Mon Sep 17 00:00:00 2001 From: Him188 Date: Thu, 24 Oct 2019 23:26:55 +0800 Subject: [PATCH] Ensure that ResponsePacket will be sent --- .../kotlin/net.mamoe.mirai/event/Event.kt | 3 +-- .../network/protocol/tim/TIMBotNetworkHandler.kt | 9 ++++----- .../protocol/tim/handler/ActionPacketHandler.kt | 12 +++--------- .../network/protocol/tim/handler/PacketHandler.kt | 3 +-- .../protocol/tim/handler/TemporaryPacketHandler.kt | 2 +- .../network/protocol/tim/packet/OutgoingPacket.kt | 3 +++ .../tim/packet/event/MessageEventPackets.kt | 4 +++- .../network/protocol/tim/packet/login/SKey.kt | 2 +- .../network/protocol/tim/packet/login/Touch.kt | 10 +++++----- mirai-debug/src/main/java/DecryptTest.kt | 6 ++++-- mirai-debug/src/main/java/PacketDebuger.kt | 13 ++++++++----- 11 files changed, 34 insertions(+), 33 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt index 266d3eaf4..2f61138b9 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt @@ -4,7 +4,6 @@ package net.mamoe.mirai.event import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.newCoroutineContext import kotlinx.coroutines.withContext import net.mamoe.mirai.contact.Contact import net.mamoe.mirai.event.internal.broadcastInternal @@ -59,7 +58,7 @@ interface Cancellable { @Suppress("UNCHECKED_CAST") @JvmOverloads suspend fun E.broadcast(context: CoroutineContext = EmptyCoroutineContext): E { - return withContext(EventScope.newCoroutineContext(context)) { this@broadcast.broadcastInternal() } + return withContext(EventScope.coroutineContext + context) { this@broadcast.broadcastInternal() } } /** diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt index 03a964498..08f8652b3 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/TIMBotNetworkHandler.kt @@ -164,7 +164,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) : loginResult.complete(LoginResult.TIMEOUT) } } - sendPacket(OutgoingTouchPacket(bot.qqAccount, this.serverIp)) + sendPacket(TouchPacket(bot.qqAccount, this.serverIp)) return loginResult.await() } @@ -206,16 +206,15 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) : } if (packet is ServerEventPacket) { - //no need to sync acknowledgement packets - launch { - sendPacket(packet.ResponsePacket(bot.qqAccount, sessionKey)) - } + //must ensure the response packet is sent + sendPacket(packet.ResponsePacket(bot.qqAccount, sessionKey)) } if (ServerPacketReceivedEvent(bot, packet).broadcast().cancelled) { return@coroutineScope } + //they should be called in sequence otherwise because packet is lock-free loginHandler.onPacketReceived(packet) this@TIMBotNetworkHandler.forEach { it.instance.onPacketReceived(packet) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/ActionPacketHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/ActionPacketHandler.kt index 762aa0888..f00f5c8b5 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/ActionPacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/ActionPacketHandler.kt @@ -15,7 +15,6 @@ import net.mamoe.mirai.network.protocol.tim.packet.event.ServerEventPacket import net.mamoe.mirai.network.protocol.tim.packet.login.RequestSKeyPacket import net.mamoe.mirai.network.qqAccount import net.mamoe.mirai.utils.log -import kotlin.coroutines.CoroutineContext /** * 动作: 获取好友列表, 点赞, 踢人等. @@ -24,9 +23,6 @@ import kotlin.coroutines.CoroutineContext * @author Him188moe */ class ActionPacketHandler(session: BotSession) : PacketHandler(session) { - override val coroutineContext: CoroutineContext - get() = session.NetworkScope.coroutineContext - companion object Key : PacketHandler.Key @@ -71,14 +67,14 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) { } private suspend fun requestSKey() = with(session) { - withContext(coroutineContext) { + withContext(NetworkScope.coroutineContext) { socket.sendPacket(RequestSKeyPacket()) } } suspend fun requestAccountInfo() = with(session) { - withContext(coroutineContext) { + withContext(NetworkScope.coroutineContext) { socket.sendPacket(RequestAccountInfoPacket(qqAccount, sessionKey)) } } @@ -88,6 +84,4 @@ class ActionPacketHandler(session: BotSession) : PacketHandler(session) { this.sKeyRefresherJob = null } -} - -private val UninitializedPacketId: UShort = 0u \ No newline at end of file +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt index ff1aa40fd..259ebd1d8 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/PacketHandler.kt @@ -1,6 +1,5 @@ package net.mamoe.mirai.network.protocol.tim.handler -import kotlinx.coroutines.CoroutineScope import net.mamoe.mirai.network.BotSession import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import kotlin.reflect.KClass @@ -10,7 +9,7 @@ import kotlin.reflect.KClass */ abstract class PacketHandler( val session: BotSession -) : CoroutineScope { +) { abstract suspend fun onPacketReceived(packet: ServerPacket) interface Key diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt index 7a979a4ba..1edabe34a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/handler/TemporaryPacketHandler.kt @@ -10,7 +10,7 @@ import kotlin.reflect.KClass * 临时数据包处理器 * ```kotlin * session.addHandler{ - * toSend { OutgoingTouchPacket() } + * toSend { TouchPacket() } * onExpect {//it: ClientTouchResponsePacket * //do sth. * } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt index 218f8b8a6..5bd9e86ca 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/OutgoingPacket.kt @@ -6,6 +6,7 @@ import kotlinx.atomicfu.atomic import kotlinx.io.core.* import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.utils.io.writeHex +import kotlin.jvm.JvmStatic /** * 发给服务器的数据包. 必须有 [PacketId] 注解或 `override` [id]. 否则将会抛出 [IllegalStateException] @@ -23,6 +24,7 @@ abstract class OutgoingPacket : Packet(), Closeable { } companion object { + @JvmStatic private val sequenceIdInternal = atomic(1) internal fun atomicNextSequenceId() = sequenceIdInternal.getAndIncrement().toUShort() } @@ -58,6 +60,7 @@ abstract class OutgoingPacket : Packet(), Closeable { } } +@Suppress("unused") @MustBeDocumented @Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) @Retention(AnnotationRetention.SOURCE) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt index 5c3f118dd..56e34fc33 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MessageEventPackets.kt @@ -50,8 +50,10 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP //管理员 子map= {5=00 00 00 03, 8=00 00 00 04, 2=65 6F 6D 38 38 31 6D 69 48, 3=02, 4=00 00 00 10} //群成员 子map= {5=00 00 00 03, 8=00 00 00 04, 2=65 6F 6D 38 38 31 6D 69 48, 3=02} + tlv.printTLVMap("Child TLV map") senderPermission = when (val value0x03 = tlv.getValue(0x03)[0].toUInt()) { 0x04u -> SenderPermission.OWNER + 0x03u -> SenderPermission.MEMBER 0x02u -> { if (!tlv.containsKey(0x04)) { SenderPermission.MEMBER @@ -64,8 +66,8 @@ class ServerGroupMessageEventPacket(input: ByteReadPacket, eventIdentity: EventP 0x01u -> SenderPermission.MEMBER else -> { - tlv.printTLVMap("Child TLV map") error("Could not determine member permission, unknown TLV(key=0x03,value=$value0x03;)") + //{5=00 00 00 01, 8=00 00 00 01, 1=48 69 6D 31 38 38 6D 6F 65, 3=03} } } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/SKey.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/SKey.kt index 30ca68ad8..c07dfea1b 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/SKey.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/SKey.kt @@ -41,7 +41,7 @@ class RequestSKeyPacket( //debugDiscardExact(2) sKey = this.readString(10)//16?? DebugLogger.logPurple("SKey=$sKey") - DebugLogger.logPurple("Skey包后面${this.readRemainingBytes().toUHexString()}") + DebugLogger.logPurple("SKey 包后面${this.readRemainingBytes().toUHexString()}") } } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Touch.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Touch.kt index 151d0bf5e..e2fbaf2c0 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Touch.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/login/Touch.kt @@ -15,7 +15,7 @@ import net.mamoe.mirai.utils.toUHexString /** * The packet received when logging in, used to redirect server address * - * @see OutgoingTouchRedirectionPacket + * @see RedirectionPacket * @see SubmitPasswordPacket * * @author Him188moe @@ -62,7 +62,7 @@ class TouchResponsePacket(input: ByteReadPacket) : ServerPacket(input) { * @author Him188moe */ @PacketId(0x08_25u) -class OutgoingTouchPacket(private val bot: UInt, private val serverIp: String) : OutgoingPacket() { +class TouchPacket(private val bot: UInt, private val serverIp: String) : OutgoingPacket() { override fun encode(builder: BytePacketBuilder) = with(builder) { this.writeQQ(bot) this.writeHex(TIMProtocol.fixVer) @@ -86,16 +86,16 @@ class OutgoingTouchPacket(private val bot: UInt, private val serverIp: String) : * @author Him188moe */ @PacketId(0x08_25u) -class OutgoingTouchRedirectionPacket(private val serverIP: String, private val qq: UInt) : OutgoingPacket() { +class RedirectionPacket(private val bot: UInt, private val serverIP: String) : OutgoingPacket() { override fun encode(builder: BytePacketBuilder) = with(builder) { - this.writeQQ(qq) + this.writeQQ(bot) this.writeHex(TIMProtocol.fixVer) this.writeHex(TIMProtocol.touchKey)//redirection key this.encryptAndWrite(TIMProtocol.touchKey) { this.writeHex(TIMProtocol.constantData1) this.writeHex(TIMProtocol.constantData2) - this.writeQQ(qq) + this.writeQQ(bot) this.writeHex("00 01 00 00 03 09 00 0C 00 01") this.writeIP(serverIP) this.writeHex("01 6F A1 58 22 01 00 36 00 12 00 02 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 14 00 1D 01 03 00 19") diff --git a/mirai-debug/src/main/java/DecryptTest.kt b/mirai-debug/src/main/java/DecryptTest.kt index b28e732f8..176859586 100644 --- a/mirai-debug/src/main/java/DecryptTest.kt +++ b/mirai-debug/src/main/java/DecryptTest.kt @@ -1,3 +1,5 @@ +@file:Suppress("UNUSED_VARIABLE") + import net.mamoe.mirai.utils.hexToBytes import net.mamoe.mirai.utils.io.stringOfWitch import net.mamoe.mirai.utils.io.toUHexString @@ -17,9 +19,9 @@ fun main() { // println("53 4B 4B 2F 6F 59 33 42 39 2F 68 56 54 45 4B 65 6A 5A 39 35 45 4D 7A 68 5A 2F 6F 4A 42 79 35 36 61 6F 50 59 32 6E 51 49 77 41 67 37 47 51 33 34 65 72 43 4C 41 72 50 4B 56 39 35 43 76 65 34 64".hexToBytes().stringOfWitch()) println("53 4B 4B 2F 6F 59 33 42 39 2F 68 56 54 45 4B 65 6A 5A 39 35 45 4D 7A 68 5A 2F 6F 4A 42 79 35 36 61 6F 50 59 32 6E 51 49 77 41 67 37 47 51 33 34 65 72 43 4C 41 72 50 4B 56 39 35 43 76 65 34 64" - .hexToBytes().unbase64().stringOfWitch()) + .hexToBytes().unbase64().stringOfWitch()) println("53 4B 4B 2F 6F 59 33 42 39 2F 68 56 54 45 4B 65 6A 5A 39 35 45 4D 7A 68 5A 2F 6F 4A 42 79 35 36 61 6F 50 59 32 6E 51 49 77 41 67 37 47 51 33 34 65 72 43 4C 41 72 50 4B 56 39 35 43 76 65 34 64" - .hexToBytes().unbase64().toUHexString()) + .hexToBytes().unbase64().toUHexString()) //base64解密结果 48 A2 BF A1 8D C1 F7 F8 55 4C 42 9E 8D 9F 79 10 CC E1 67 FA 09 07 2E 7A 6A 83 D8 DA 74 08 C0 08 3B 19 0D F8 7A B0 8B 02 B3 CA 57 DE 42 BD EE 1D diff --git a/mirai-debug/src/main/java/PacketDebuger.kt b/mirai-debug/src/main/java/PacketDebuger.kt index b77b26e61..858984350 100644 --- a/mirai-debug/src/main/java/PacketDebuger.kt +++ b/mirai-debug/src/main/java/PacketDebuger.kt @@ -1,5 +1,8 @@ @file:Suppress("EXPERIMENTAL_API_USAGE", "MemberVisibilityCanBePrivate", "EXPERIMENTAL_UNSIGNED_LITERALS") +import Main.localIp +import Main.qq +import Main.sessionKey import jpcap.JpcapCaptor import jpcap.packet.IPPacket import jpcap.packet.UDPPacket @@ -19,13 +22,12 @@ import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.toUHexString /** - * 抓包分析器 + * 抓包分析器. + * 设置好 [sessionKey], [localIp] 和 [qq] 后运行即可开始抓包和自动解密 * * @author Him188moe */ object Main { - const val localIp = "192.168.3." - @JvmStatic fun main(args: Array) { val devices = JpcapCaptor.getDeviceList() @@ -77,8 +79,9 @@ object Main { * 6. 运行到 `mov eax,dword ptr ss:[ebp+10]` * 7. 查看内存, 从 `eax` 开始的 16 bytes 便是 `sessionKey` */ - val sessionKey: ByteArray = "B7 E2 A6 3D 90 4F 4F 74 7D 55 9C 0E 91 20 40 A5".hexToBytes() - val qq: UInt = 1040400290u + val sessionKey: ByteArray = "1D 1E 71 68 B9 41 FD 5B F3 5A 3F 71 87 B5 86 CB".hexToBytes() + const val qq: UInt = 1040400290u + const val localIp = "192.168.3." fun dataReceived(data: ByteArray) { //println("raw = " + data.toUHexString())