Commit ffe8339c authored by Him188's avatar Him188

Ensure that ResponsePacket will be sent

parent d5bf51a3
......@@ -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 : Event> E.broadcast(context: CoroutineContext = EmptyCoroutineContext): E {
return withContext(EventScope.newCoroutineContext(context)) { this@broadcast.broadcastInternal() }
return withContext(EventScope.coroutineContext + context) { this@broadcast.broadcastInternal() }
}
/**
......
......@@ -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)
......
......@@ -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<ActionPacketHandler>
......@@ -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
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<T : PacketHandler>
......
......@@ -10,7 +10,7 @@ import kotlin.reflect.KClass
* 临时数据包处理器
* ```kotlin
* session.addHandler<ClientTouchResponsePacket>{
* toSend { OutgoingTouchPacket() }
* toSend { TouchPacket() }
* onExpect {//it: ClientTouchResponsePacket
* //do sth.
* }
......
......@@ -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)
......
......@@ -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}
}
}
......
......@@ -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
......@@ -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")
......
@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
......
@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<String>) {
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())
......
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