Commit 4d346a2c authored by Him188's avatar Him188

Fix SendFriendMessage due to TIM update

parent 05e590c9
...@@ -5,7 +5,7 @@ package net.mamoe.mirai.message ...@@ -5,7 +5,7 @@ package net.mamoe.mirai.message
@Suppress("unused") @Suppress("unused")
enum class MessageType(val value: UByte) { enum class MessageType(val value: UByte) {
PLAIN_TEXT(0x03u), PLAIN_TEXT(0x01u),
AT(0x06u), AT(0x06u),
FACE(0x02u), FACE(0x02u),
IMAGE(0x03u),//may be 0x06? IMAGE(0x03u),//may be 0x06?
......
...@@ -31,7 +31,7 @@ object TIMProtocol { ...@@ -31,7 +31,7 @@ object TIMProtocol {
*/ */
const val fixVer2 = "02 00 00 00 01 01 01 00 00 68 20" const val fixVer2 = "02 00 00 00 01 01 01 00 00 68 20"
// 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00 // 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00
// 02 00 00 00 01 2E 01 00 00 69 35 const val versionNewest = "02 00 00 00 01 2E 01 00 00 69 35"
const val constantData1 = "00 18 00 16 00 01 " const val constantData1 = "00 18 00 16 00 01 "
const val constantData2 = "00 00 04 53 00 00 00 01 00 00 15 85 " const val constantData2 = "00 00 04 53 00 00 00 01 00 00 15 85 "
...@@ -92,5 +92,6 @@ object TIMProtocol { ...@@ -92,5 +92,6 @@ object TIMProtocol {
* length=15 * length=15
*/ */
const val messageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91" const val messageConst1 = "00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
const val messageConstNewest = "22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
// TIM最新 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91 // TIM最新 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91
} }
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS") @file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
package net.mamoe.mirai.network.protocol.tim.packet.action package net.mamoe.mirai.network.protocol.tim.packet.action
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.message.MessageChain import net.mamoe.mirai.message.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.message.toChain
import net.mamoe.mirai.message.toMessage
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.ClientPacket import net.mamoe.mirai.network.protocol.tim.packet.ClientPacket
import net.mamoe.mirai.network.protocol.tim.packet.PacketId import net.mamoe.mirai.network.protocol.tim.packet.PacketId
import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
fun main() {
println("牛逼".toMessage().toChain().toPacket().readBytes().toUHexString())
}
@PacketId(0x00_CDu) @PacketId(0x00_CDu)
class ClientSendFriendMessagePacket( class ClientSendFriendMessagePacket(
...@@ -19,29 +24,55 @@ class ClientSendFriendMessagePacket( ...@@ -19,29 +24,55 @@ class ClientSendFriendMessagePacket(
private val sessionKey: ByteArray, private val sessionKey: ByteArray,
private val message: MessageChain private val message: MessageChain
) : ClientPacket() { ) : ClientPacket() {
override fun encode(builder: BytePacketBuilder) = with(builder) { override fun encode(builder: BytePacketBuilder) = with(builder) {
writeQQ(botQQ) writeQQ(botQQ)
writeHex(TIMProtocol.fixVer2) writeHex(TIMProtocol.versionNewest)
encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
//TIM最新
//3E 03 3F A2
//76 E4 B8 DD
//00 00 00 08 00 01 00 04 00 00 00 00
//38 03
//3E 03 3F A2
//76 E4 B8 DD
//C6 FB 06 30 0C 69 0C AD C6 AD 14 BF 0B C6 38 EA
//00 0B
//3D 7F
//5D AA A8 E2
//01 1D
// 00 00 00 00
//01
// 00
// 00
//00 01 4D 53 47 00 00 00 00 00
//5D AA A8 E2
//E2 AE 94 2D
//00 00 00 00 0C 00 86
//22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91
//00 00
//
//01 00 09 01 00 06 E7 89 9B E9 80 BC
writeQQ(botQQ) writeQQ(botQQ)
writeQQ(targetQQ) writeQQ(targetQQ)
writeHex("00 00 00 08 00 01 00 04 00 00 00 00") writeHex("00 00 00 08 00 01 00 04 00 00 00 00")
writeHex("37 0F")//TIM最新: 38 03 writeHex("38 03")//TIM最新: 38 03
writeQQ(botQQ) writeQQ(botQQ)
writeQQ(targetQQ) writeQQ(targetQQ)
writeFully(md5(buildPacket { writeQQ(targetQQ); writeFully(sessionKey) }.readBytes())) writeFully(md5(buildPacket { writeQQ(targetQQ); writeFully(sessionKey) }.readBytes()))
writeHex("00 0B") writeHex("00 0B")
writeRandom(2) writeRandom(2)
writeTime() writeTime()
writeHex("00 00" + writeHex("01 1D" +
"00 00 00 00") " 00 00 00 00")
//消息过多要分包发送 //消息过多要分包发送
//如果只有一个 //如果只有一个
writeByte(0x01) writeByte(0x01)
writeByte(0)//第几个包 writeByte(0)//第几个包
writeByte(0) writeUByte(0x00u)
//如果大于一个, //如果大于一个,
//writeByte(0x02)//数量 //writeByte(0x02)//数量
//writeByte(0)//第几个包 //writeByte(0)//第几个包
...@@ -50,10 +81,11 @@ class ClientSendFriendMessagePacket( ...@@ -50,10 +81,11 @@ class ClientSendFriendMessagePacket(
writeHex("00 01 4D 53 47 00 00 00 00 00") writeHex("00 01 4D 53 47 00 00 00 00 00")
writeTime() writeTime()
writeRandom(4) writeRandom(4)
writeHex("00 00 00 00 09 00 86")//TIM最新 0C 00 86 writeHex("00 00 00 00 0C 00 86")//TIM最新 0C 00 86
writeHex(TIMProtocol.messageConst1)//... 85 E9 BB 91 writeHex(TIMProtocol.messageConstNewest)//... 85 E9 BB 91
writeZero(2) writeZero(2)
message.toPacket().debugPrint("CHAIN")
writePacket(message.toPacket()) writePacket(message.toPacket())
/* /*
......
...@@ -43,8 +43,6 @@ internal object HexComparator { ...@@ -43,8 +43,6 @@ internal object HexComparator {
val 群 = "群".toByteArray().toUHexString() val 群 = "群".toByteArray().toUHexString()
val 你好 = "你好".toByteArray().toUHexString() val 你好 = "你好".toByteArray().toUHexString()
val SINGLE_PLAIN_MESSAGE_HEAD = "00 00 01 00 09 01"
val MESSAGE_TAIL_10404 = "0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00" val MESSAGE_TAIL_10404 = "0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00"
.replace(" ", " ") .replace(" ", " ")
......
...@@ -5,6 +5,7 @@ import jpcap.packet.IPPacket ...@@ -5,6 +5,7 @@ import jpcap.packet.IPPacket
import jpcap.packet.UDPPacket import jpcap.packet.UDPPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
import kotlinx.io.core.readUInt
import net.mamoe.mirai.message.internal.readMessageChain import net.mamoe.mirai.message.internal.readMessageChain
import net.mamoe.mirai.network.protocol.tim.TIMProtocol import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket import net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
...@@ -71,7 +72,7 @@ object Main { ...@@ -71,7 +72,7 @@ object Main {
* 6. 运行到 `mov eax,dword ptr ss:[ebp+10]` * 6. 运行到 `mov eax,dword ptr ss:[ebp+10]`
* 7. 查看内存, 从 `eax` 开始的 16 bytes 便是 `sessionKey` * 7. 查看内存, 从 `eax` 开始的 16 bytes 便是 `sessionKey`
*/ */
val sessionKey: ByteArray = "99 91 B9 8B 79 45 FD CF 51 4A B9 DE 14 61 ED E3".hexToBytes() val sessionKey: ByteArray = "99 82 67 D4 62 20 CA 5D 81 F8 6F 83 EE 8A F7 68".hexToBytes()
fun dataReceived(data: ByteArray) { fun dataReceived(data: ByteArray) {
println("--------------") println("--------------")
...@@ -121,7 +122,8 @@ object Main { ...@@ -121,7 +122,8 @@ object Main {
discardExact(3)//head discardExact(3)//head
val idHex = readBytes(4).toUHexString() val idHex = readBytes(4).toUHexString()
println("发出包ID = $idHex") println("发出包ID = $idHex")
discardExact(TIMProtocol.fixVer2.hexToBytes().size + 1 + 5 - 3 + 1) readUInt()//客户端登录的qq
println("TIM的fixVer2=" + readBytes(TIMProtocol.fixVer2.hexToBytes().size).toUHexString())
val encryptedBody = readRemainingBytes() val encryptedBody = readRemainingBytes()
println("解密body = ${encryptedBody.decryptBy(sessionKey).toUHexString()}") println("解密body = ${encryptedBody.decryptBy(sessionKey).toUHexString()}")
......
...@@ -13,15 +13,30 @@ import net.mamoe.mirai.message.Image ...@@ -13,15 +13,30 @@ import net.mamoe.mirai.message.Image
import net.mamoe.mirai.message.PlainText import net.mamoe.mirai.message.PlainText
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.utils.BotAccount import net.mamoe.mirai.utils.BotAccount
import net.mamoe.mirai.utils.Console
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.PlatformLogger
import java.io.File
private fun readTestAccount(): BotAccount? {
val file = File("testAccount.txt")
if (!file.exists() || !file.canRead()) {
return null
}
val lines = file.readLines()
return try {
BotAccount(lines[0].toLong(), lines[1])
} catch (e: IndexOutOfBoundsException) {
null
}
}
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
suspend fun main() { suspend fun main() {
val bot = Bot(BotAccount(//填写你的账号 val bot = Bot(readTestAccount() ?: BotAccount(//填写你的账号
account = 1994701121, account = 1994701121,
password = "123456" password = "123456"
), Console()) ), PlatformLogger())
bot.login { bot.login {
randomDeviceName = true randomDeviceName = true
......
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