Add unknown statuses

This commit is contained in:
Him188 2019-11-11 19:37:33 +08:00
parent 620882957a
commit 368abbe130
3 changed files with 143 additions and 93 deletions

View File

@ -26,13 +26,18 @@ enum class OnlineStatus(
*/
OFFLINE(0x02u),
/**
* ?
*/
UNKNOWN(0x20u)
UNKNOWN1(0x20u),
UNKNOWN2(0x46u),
UNKNOWN3(0x14u),
UNKNOWN4(0xC9u),
UNKNOWN5(0x1Eu),
;
// TODO: 2019/10/29 what is 0x20u
// TODO: 2019/11/11 what is 0x46u
// TODO: 2019/11/11 what is 0x14u
// TODO: 2019/11/11 0xC9u
// TODO: 2019/11/11 0x1Eu
companion object {
fun ofId(id: UByte): OnlineStatus? = values().firstOrNull { it.id == id }
}

View File

@ -3,6 +3,7 @@ package net.mamoe.mirai.utils
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.IoBuffer
import kotlinx.io.pool.useInstance
import net.mamoe.mirai.network.protocol.tim.packet.Decrypter
import net.mamoe.mirai.network.protocol.tim.packet.DecrypterByteArray
import net.mamoe.mirai.utils.io.*
import kotlin.experimental.and
@ -123,6 +124,8 @@ fun ByteReadPacket.decryptBy(key: ByteArray): ByteReadPacket = decryptAsByteArra
fun ByteReadPacket.decryptBy(key: IoBuffer): ByteReadPacket = decryptAsByteArray(key) { data -> ByteReadPacket(data, 0) }
fun ByteReadPacket.decryptBy(key: Decrypter): ByteReadPacket = key.decrypt(this)
fun ByteReadPacket.decryptBy(keyHex: String): ByteReadPacket = decryptBy(keyHex.hexToBytes())
inline fun <R> ByteReadPacket.decryptAsByteArray(key: ByteArray, consumer: (ByteArray) -> R): R =

View File

@ -4,15 +4,13 @@ import PacketDebugger.dataSent
import PacketDebugger.localIp
import PacketDebugger.qq
import PacketDebugger.sessionKey
import kotlinx.coroutines.GlobalScope
import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes
import kotlinx.io.core.readUInt
import kotlinx.io.core.readUShort
import kotlinx.coroutines.*
import kotlinx.io.core.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.message.internal.readMessageChain
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.BotSession
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.handler.ActionPacketHandler
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
@ -29,10 +27,13 @@ import net.mamoe.mirai.utils.decryptBy
import net.mamoe.mirai.utils.io.*
import org.pcap4j.core.BpfProgram.BpfCompileMode
import org.pcap4j.core.PacketListener
import org.pcap4j.core.PcapNetworkInterface
import org.pcap4j.core.PcapNetworkInterface.PromiscuousMode
import org.pcap4j.core.Pcaps
import java.util.concurrent.Executors
import kotlin.concurrent.thread
import kotlin.coroutines.CoroutineContext
import kotlin.io.use
/**
* 需使用 32 JDK
@ -47,39 +48,58 @@ fun main() {
JpcapCaptor.openDevice(JpcapCaptor.getDeviceList()[0], 65535, true, 1000).loopPacket(Int.MAX_VALUE) {
println(it)
}*/
listenDevice()
Pcaps.findAllDevs().forEach {
listenDevice(it)
}
}
private fun listenDevice() {
/**
* 避免 print 重叠. 单线程处理足够调试
*/
val DISPATCHER = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
private fun listenDevice(device: PcapNetworkInterface) {
val sender = device.openLive(65536, PromiscuousMode.PROMISCUOUS, 10)
thread {
val sender = Pcaps.findAllDevs().first { it.addresses.any { it.address.hostAddress == localIp } }.openLive(65536, PromiscuousMode.PROMISCUOUS, 10)
sender.setFilter("src $localIp && udp port 8000", BpfCompileMode.OPTIMIZE)
println("sendListener started")
try {
sender.loop(999999, PacketListener {
sender.loop(Int.MAX_VALUE, PacketListener {
runBlocking {
withContext(DISPATCHER) {
try {
dataSent(it.rawData.drop(42).toByteArray())
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
})
} catch (e: Exception) {
} catch (e: Throwable) {
e.printStackTrace()
}
}
/*
val receiver = device.openLive(65536, PromiscuousMode.PROMISCUOUS, 10)
thread {
val receiver = Pcaps.findAllDevs().first { it.addresses.any { it.address.hostAddress == localIp } }.openLive(65536, PromiscuousMode.PROMISCUOUS, 10)
receiver.setFilter("dst $localIp && udp port 8000", BpfCompileMode.OPTIMIZE)
println("receiveListener started")
try {
receiver.loop(Int.MAX_VALUE, PacketListener {
runBlocking {
dataReceived(it.rawData.drop(42).toByteArray())
withContext(DISPATCHER) {
try {
PacketDebugger.dataReceived(it.rawData.drop(42).toByteArray())
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
})
}*/
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
/**
@ -103,9 +123,15 @@ object PacketDebugger {
* 7. 运行完 `mov eax,dword ptr ss:[ebp+10]`
* 8. 查看内存, `eax` `eax+10` 16 字节就是 `sessionKey`
*/
val sessionKey: ByteArray = "F9 37 23 8F E7 04 AF 52 6D B9 94 13 E1 3A BD 4A".hexToBytes()
val sessionKey: SessionKey = SessionKey("9B AA 9C 93 78 47 7B 6F C4 57 F2 13 76 AC C7 72".hexToBytes())
const val qq: UInt = 1040400290u
const val localIp = "192.168.3.10"
val localIp: String = "10.162.12.231".also { println("Local IP: $it") }
val IgnoredPacketIdList: List<PacketId> = listOf(
KnownPacketId.FRIEND_ONLINE_STATUS_CHANGE,
KnownPacketId.CHANGE_ONLINE_STATUS,
KnownPacketId.HEARTBEAT
)
suspend fun dataReceived(data: ByteArray) {
//println("raw = " + data.toUHexString())
@ -115,27 +141,33 @@ object PacketDebugger {
val sequenceId = readUShort()
if (id == KnownPacketId.HEARTBEAT || readUInt() != qq)
return@read
if (IgnoredPacketIdList.contains(id)) {
return
}
println("--------------")
println("接收数据包")
discardExact(3)//0x00 0x00 0x00. 但更可能是应该 discard 8
println("id=$id, sequence=${sequenceId.toUHexString()}")
val remaining = this.readRemainingBytes().cutTail(1)
println(
"接收包id=$id, " +
"\nsequence=${sequenceId.toUHexString()}"
)
// val remaining = this.readRemainingBytes().cutTail(1)
try {
val decrypted = remaining.decryptBy(sessionKey)
println("解密body=${decrypted.toUHexString()}")
val packet = use {
with(id.factory) {
provideDecrypter(id.factory)
.decrypt(this@read)
.decrypt(this@read.readRemainingBytes().let { ByteReadPacket(it, 0, it.size - 1) })
.decode(id, sequenceId, DebugNetworkHandler)
}
}
println(" 解析body=$packet")
handlePacket(id, sequenceId, packet, id.factory)
} catch (e: DecryptionFailedException) {
println("密文body=" + remaining.toUHexString())
// println("密文body=" + remaining.toUHexString())
println(" 解密body=解密失败")
}
}
@ -162,6 +194,7 @@ object PacketDebugger {
packet: TPacket,
factory: PacketFactory<TPacket, *>
) {
return
when (packet) {
is UnknownEventPacket -> {
println("--------------")
@ -195,13 +228,18 @@ object PacketDebugger {
// 01 BD 63 D6
// 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35
println("---------------------------")
discardExact(3)//head
val idHex = readBytes(4).toUHexString()
println("发出包ID = $idHex")
val id = matchPacketId(readUShort())
val sequence = readUShort()
if (IgnoredPacketIdList.contains(id)) {
return
}
if (readUInt() != qq) {
return@read
}
println("---------------------------")
println("发出包ID = $id")
println("sequence = $sequence")
println(
" fixVer2=" + when (val flag = readByte().toInt()) {
@ -216,7 +254,7 @@ object PacketDebugger {
val encryptedBody = readRemainingBytes()
try {
println("解密body=${encryptedBody.decryptBy(sessionKey).toUHexString()}")
println(" 解密body=${encryptedBody.decryptBy(sessionKey.value).toUHexString()}")
} catch (e: DecryptionFailedException) {
println(" 密文=" + encryptedBody.toUHexString())
println(" 解密body=解密失败")
@ -224,13 +262,14 @@ object PacketDebugger {
encryptedBody.read {
/*
when (idHex.substring(0, 5)) {
"00 CD" -> {
println("好友消息")
val raw = readRemainingBytes()
//println("解密前数据: " + raw.toUHexString())
val messageData = raw.decryptBy(sessionKey)
val messageData = raw.decryptBy(sessionKey.value)
//println("解密结果: " + messageData.toUHexString())
println("尝试解消息")
@ -246,8 +285,9 @@ object PacketDebugger {
} catch (e: Exception) {
println("失败")
}
}
}*/
/*
"03 88" -> {
println("0388上传图片-获取图片ID")
discardExact(8)
@ -255,16 +295,15 @@ object PacketDebugger {
//val body = readRemainingBytes().decryptBy(sessionKey)
//println(body.toUHexString())
}
}
}*/
}
}
}
internal object DebugNetworkHandler : BotNetworkHandler<DataPacketSocketAdapter> {
override val socket: DataPacketSocketAdapter
get() = object : DataPacketSocketAdapter {
internal object DebugNetworkHandler : BotNetworkHandler<DataPacketSocketAdapter>, CoroutineScope {
override val socket: DataPacketSocketAdapter = object : DataPacketSocketAdapter {
override val serverIp: String
get() = ""
override val channel: PlatformDatagramChannel
@ -284,10 +323,13 @@ internal object DebugNetworkHandler : BotNetworkHandler<DataPacketSocketAdapter>
}
override val bot: Bot = Bot(0u, "")
val session = BotSession(bot, sessionKey, socket, this)
val action = ActionPacketHandler(session)
override fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = error("UNSUPPORTED")
@Suppress("UNCHECKED_CAST")
override fun <T : PacketHandler> get(key: PacketHandler.Key<T>): T = action as? T ?: error("UNSUPPORTED")
override suspend fun login(configuration: BotConfiguration): LoginResult = error("UNSUPPORTED")
override suspend fun login(configuration: BotConfiguration): LoginResult = LoginResult.SUCCESS
override suspend fun addHandler(temporaryPacketHandler: TemporaryPacketHandler<*, *>) {
}