Fix debugger

This commit is contained in:
Him188 2019-11-08 21:17:25 +08:00
parent f3278c8afe
commit 16a487129a
7 changed files with 124 additions and 30 deletions

View File

@ -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] 解密
*/

View File

@ -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.

View File

@ -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>

View File

@ -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)

View File

@ -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()

View File

@ -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
}

View File

@ -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"