mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-06 17:39:12 +08:00
Fix debugger
This commit is contained in:
parent
f3278c8afe
commit
16a487129a
@ -17,7 +17,7 @@ inline class SessionKey(override val value: ByteArray) : DecrypterByteArray {
|
||||
*/
|
||||
interface DecrypterByteArray : Decrypter {
|
||||
val value: ByteArray
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket = packet.decryptBy(value)
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,25 +25,25 @@ interface DecrypterByteArray : Decrypter {
|
||||
*/
|
||||
interface DecrypterIoBuffer : Decrypter {
|
||||
val value: IoBuffer
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket = packet.decryptBy(value)
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接在一起的解密器
|
||||
*/
|
||||
inline class LinkedDecrypter(inline val block: (ByteReadPacket) -> ByteReadPacket) : Decrypter {
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket = block(packet)
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket = block(input)
|
||||
}
|
||||
|
||||
object NoDecrypter : Decrypter, DecrypterType<NoDecrypter> {
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket = packet
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密器
|
||||
*/
|
||||
interface Decrypter {
|
||||
fun decrypt(packet: ByteReadPacket): ByteReadPacket
|
||||
fun decrypt(input: ByteReadPacket): ByteReadPacket
|
||||
/**
|
||||
* 连接后将会先用 this 解密, 再用 [another] 解密
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@ object PacketFactoryList : MutableList<PacketFactory<*, *>> by mutableListOf()
|
||||
* @param TPacket 服务器回复包解析结果
|
||||
* @param TDecrypter 服务器回复包解密器
|
||||
*/
|
||||
abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(internal val decrypterType: DecrypterType<TDecrypter>) {
|
||||
abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val decrypterType: DecrypterType<TDecrypter>) {
|
||||
|
||||
/**
|
||||
* 2 Ubyte.
|
||||
|
@ -22,8 +22,8 @@ inline class PrivateKey(override val value: ByteArray) : DecrypterByteArray {
|
||||
}
|
||||
|
||||
inline class SubmitPasswordResponseDecrypter(private val privateKey: PrivateKey) : Decrypter {
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket {
|
||||
var decrypted = ShareKey.decrypt(packet)
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket {
|
||||
var decrypted = ShareKey.decrypt(input)
|
||||
(decrypted.remaining).let {
|
||||
if (it.toInt() % 8 == 0 && it >= 16) {
|
||||
decrypted = try {
|
||||
@ -253,7 +253,7 @@ object SubmitPasswordPacket : PacketFactory<SubmitPasswordPacket.LoginResponse,
|
||||
}
|
||||
|
||||
inline class SessionResponseDecryptionKey(private val delegate: IoBuffer) : Decrypter {
|
||||
override fun decrypt(packet: ByteReadPacket): ByteReadPacket = packet.decryptBy(delegate)
|
||||
override fun decrypt(input: ByteReadPacket): ByteReadPacket = input.decryptBy(delegate)
|
||||
|
||||
override fun toString(): String = "SessionResponseDecryptionKey"
|
||||
companion object Type : DecrypterType<SessionResponseDecryptionKey>
|
||||
|
@ -35,6 +35,6 @@ fun UByteArray.toUHexString(separator: String = " "): String = this.joinToString
|
||||
|
||||
fun ByteArray.toReadPacket(offset: Int = 0, length: Int = this.size) = ByteReadPacket(this, offset = offset, length = length)
|
||||
|
||||
fun <R> ByteArray.read(t: ByteReadPacket.() -> R): R = this.toReadPacket().use(t)
|
||||
inline fun <R> ByteArray.read(t: ByteReadPacket.() -> R): R = this.toReadPacket().use(t)
|
||||
|
||||
fun ByteArray.cutTail(length: Int): ByteArray = this.copyOfRange(0, this.size - length)
|
@ -8,10 +8,13 @@ plugins {
|
||||
javafx {
|
||||
version = "11"
|
||||
modules = listOf("javafx.controls")
|
||||
|
||||
//mainClassName = "Application"
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "Application"
|
||||
}
|
||||
|
||||
val kotlinVersion = rootProject.ext["kotlin_version"].toString()
|
||||
val atomicFuVersion = rootProject.ext["atomicfu_version"].toString()
|
||||
val coroutinesVersion = rootProject.ext["coroutines_version"].toString()
|
||||
|
@ -6,12 +6,25 @@ import Main.localIp
|
||||
import Main.qq
|
||||
import Main.sessionKey
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.io.packet.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.core.readUInt
|
||||
import kotlinx.io.core.readUShort
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.message.internal.readMessageChain
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.DataPacketSocketAdapter
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.PacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.*
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.event.UnknownEventPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.CaptchaKey
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.ShareKey
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.TouchKey
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.DecryptionFailedException
|
||||
import net.mamoe.mirai.utils.decryptBy
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
@ -20,6 +33,7 @@ import org.pcap4j.core.PacketListener
|
||||
import org.pcap4j.core.PcapNetworkInterface
|
||||
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode
|
||||
import org.pcap4j.core.Pcaps
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
suspend fun main() {
|
||||
val nif: PcapNetworkInterface = Pcaps.findAllDevs()[0]
|
||||
@ -40,7 +54,9 @@ suspend fun main() {
|
||||
receiver.setFilter("dst $localIp && udp port 8000", BpfCompileMode.OPTIMIZE)
|
||||
withContext(Dispatchers.IO) {
|
||||
receiver.loop(Int.MAX_VALUE, PacketListener {
|
||||
runBlocking {
|
||||
dataReceived(it.rawData.drop(42).toByteArray())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -73,7 +89,7 @@ object Main {
|
||||
const val qq: UInt = 1040400290u
|
||||
const val localIp = "192.168.3.10"
|
||||
|
||||
fun dataReceived(data: ByteArray) {
|
||||
suspend fun dataReceived(data: ByteArray) {
|
||||
//println("raw = " + data.toUHexString())
|
||||
data.read {
|
||||
discardExact(3)
|
||||
@ -94,7 +110,22 @@ object Main {
|
||||
val decrypted = remaining.decryptBy(sessionKey)
|
||||
println("解密body=${decrypted.toUHexString()}")
|
||||
|
||||
packetReceived(data.read { parseServerPacket(data.size, sessionKey) })
|
||||
discardExact(3)
|
||||
|
||||
val id = matchPacketId(readUShort())
|
||||
val sequenceId = readUShort()
|
||||
|
||||
discardExact(7)//4 for qq number, 3 for 0x00 0x00 0x00
|
||||
|
||||
val packet = use {
|
||||
with(id.factory) {
|
||||
provideDecrypter(id.factory)
|
||||
.decrypt(this@read)
|
||||
.decode(id, sequenceId, DebugNetworkHandler)
|
||||
}
|
||||
}
|
||||
|
||||
handlePacket(id, sequenceId, packet, id.factory)
|
||||
} catch (e: DecryptionFailedException) {
|
||||
println("密文body=" + remaining.toUHexString())
|
||||
println("解密body=解密失败")
|
||||
@ -102,29 +133,45 @@ object Main {
|
||||
}
|
||||
}
|
||||
|
||||
fun packetReceived(packet: ServerPacket) {
|
||||
@Suppress("IMPLICIT_CAST_TO_ANY", "UNCHECKED_CAST")
|
||||
internal fun <D : Decrypter> provideDecrypter(factory: PacketFactory<*, D>): D =
|
||||
when (factory.decrypterType) {
|
||||
TouchKey -> TouchKey
|
||||
CaptchaKey -> CaptchaKey
|
||||
ShareKey -> ShareKey
|
||||
|
||||
NoDecrypter -> NoDecrypter
|
||||
|
||||
SessionKey -> sessionKey
|
||||
|
||||
else -> error("No decrypter is found")
|
||||
} as? D ?: error("Internal error: could not cast decrypter which is found for factory to class Decrypter")
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun <TPacket : Packet> handlePacket(
|
||||
id: PacketId,
|
||||
sequenceId: UShort,
|
||||
packet: TPacket,
|
||||
factory: PacketFactory<TPacket, *>
|
||||
) {
|
||||
when (packet) {
|
||||
is ServerEventPacket.Raw.Encrypted -> {
|
||||
packetReceived(packet.decrypt(sessionKey))
|
||||
}
|
||||
|
||||
is ServerEventPacket.Raw -> packetReceived(packet.distribute())
|
||||
|
||||
is UnknownServerEventPacket -> {
|
||||
is UnknownEventPacket -> {
|
||||
println("--------------")
|
||||
println("未知事件ID=" + packet.idHexString)
|
||||
println("未知事件: " + packet.input.readBytes().toUHexString())
|
||||
println("未知事件ID=$id")
|
||||
println("未知事件: $packet")
|
||||
}
|
||||
|
||||
is ServerEventPacket -> {
|
||||
is UnknownPacket -> {
|
||||
println("--------------")
|
||||
println("未知包ID=$id")
|
||||
println("未知包: $packet")
|
||||
}
|
||||
|
||||
is EventPacket -> {
|
||||
println("事件")
|
||||
println(packet)
|
||||
}
|
||||
|
||||
is UnknownServerPacket -> {
|
||||
//ignore
|
||||
}
|
||||
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
@ -205,3 +252,44 @@ object Main {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal object DebugNetworkHandler : BotNetworkHandler<DataPacketSocketAdapter> {
|
||||
override val socket: DataPacketSocketAdapter
|
||||
get() = object : DataPacketSocketAdapter {
|
||||
override val serverIp: String
|
||||
get() = ""
|
||||
override val channel: PlatformDatagramChannel
|
||||
get() = error("UNSUPPORTED")
|
||||
override val isOpen: Boolean
|
||||
get() = true
|
||||
|
||||
override suspend fun sendPacket(packet: OutgoingPacket) {
|
||||
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
}
|
||||
|
||||
override val owner: Bot
|
||||
get() = bot
|
||||
|
||||
}
|
||||
override val bot: Bot = Bot(0u, "")
|
||||
|
||||
override fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = error("UNSUPPORTED")
|
||||
|
||||
override suspend fun login(configuration: BotConfiguration): LoginResult = error("UNSUPPORTED")
|
||||
|
||||
override suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) {
|
||||
}
|
||||
|
||||
override suspend fun sendPacket(packet: OutgoingPacket) {
|
||||
}
|
||||
|
||||
override suspend fun awaitDisconnection() {
|
||||
}
|
||||
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = GlobalScope.coroutineContext
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
apply plugin: "kotlin"
|
||||
apply plugin: "java"
|
||||
apply plugin: "application"
|
||||
|
||||
dependencies {
|
||||
api project(":mirai-core")
|
||||
@ -11,3 +12,5 @@ dependencies {
|
||||
compile group: 'com.alibaba', name: 'fastjson', version: '1.2.62'
|
||||
implementation 'org.jsoup:jsoup:1.12.1'
|
||||
}
|
||||
|
||||
mainClassName = "demo.gentleman.MainKt"
|
Loading…
Reference in New Issue
Block a user