Debugging updates

This commit is contained in:
Him188 2019-10-07 12:44:44 +08:00
parent 8e97b47a8c
commit 6d58cb1880
14 changed files with 133 additions and 56 deletions

View File

@ -18,7 +18,7 @@
1. Clone 1. Clone
2. Import as Maven project 2. Import as Maven project
3. Run demo[Demo 1 Main](mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L16) 3. Run demo[Demo 1 Main](mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L22)
### 事件 Hook ### 事件 Hook
#### Java: #### Java:
@ -38,7 +38,7 @@ FriendMessageEvent.subscribeAlways{
![](.github/68f8fec9.png) ![](.github/68f8fec9.png)
发送图片已经完成,但我们还在开发上传图片至服务器。 发送图片已经完成,但我们还在开发上传图片至服务器。
现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看 [Image.kt](mirai-core/src/main/java/net/mamoe/mirai/message/defaults/Image.kt#L20-L93) 现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看 [Image.kt](mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Image.kt#L20-L93)
## 语言使用说明 ## 语言使用说明
我们使用 Kotlin但我们也会保留对 Java 和 Java开发者的支持。 我们使用 Kotlin但我们也会保留对 Java 和 Java开发者的支持。

View File

@ -23,6 +23,7 @@ kotlin {
implementation rootProject.ext.coroutine implementation rootProject.ext.coroutine
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.4.0'
implementation 'org.yaml:snakeyaml:1.18' implementation 'org.yaml:snakeyaml:1.18'
implementation 'org.jsoup:jsoup:1.12.1' implementation 'org.jsoup:jsoup:1.12.1'
implementation 'org.ini4j:ini4j:0.5.2' implementation 'org.ini4j:ini4j:0.5.2'

View File

@ -39,6 +39,7 @@ class PlainText(private val text: String) : Message() {
override operator fun contains(sub: String): Boolean = this.toString().contains(sub) override operator fun contains(sub: String): Boolean = this.toString().contains(sub)
internal object PacketHelper { internal object PacketHelper {
@JvmStatic
fun ofByteArray(data: ByteArray): PlainText = lazyDecode(data) { fun ofByteArray(data: ByteArray): PlainText = lazyDecode(data) {
it.skip(1) it.skip(1)
PlainText(it.readLVString()) PlainText(it.readLVString())

View File

@ -4,11 +4,13 @@ import kotlinx.coroutines.*
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.ListeningStatus
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.bot.BotLoginSucceedEvent import net.mamoe.mirai.event.events.bot.BotLoginSucceedEvent
import net.mamoe.mirai.event.events.network.BeforePacketSendEvent import net.mamoe.mirai.event.events.network.BeforePacketSendEvent
import net.mamoe.mirai.event.events.network.PacketSentEvent import net.mamoe.mirai.event.events.network.PacketSentEvent
import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent
import net.mamoe.mirai.event.subscribe
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.LoginSession import net.mamoe.mirai.network.LoginSession
import net.mamoe.mirai.network.NetworkScope import net.mamoe.mirai.network.NetworkScope
@ -62,7 +64,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
//if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) { //if (state == LoginState.UNKNOWN || state == LoginState.TIMEOUT) {
// loginInternal(ipQueue)//超时或未知, 重试连接下一个服务器 // loginInternal(ipQueue)//超时或未知, 重试连接下一个服务器
//} else { //} else {
state state
// } // }
} }
} }
@ -146,7 +148,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
restartSocket() restartSocket()
} }
internal var loginResult: CompletableDeferred<LoginState>? = null internal lateinit var loginResult: CompletableDeferred<LoginState>
@Synchronized @Synchronized
private fun restartSocket() { private fun restartSocket() {
@ -172,10 +174,6 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
} }
} }
/**
* Start network and touch the server
*/
internal suspend fun touch(serverAddress: String): LoginState { internal suspend fun touch(serverAddress: String): LoginState {
bot.info("Connecting server: $serverAddress") bot.info("Connecting server: $serverAddress")
restartSocket() restartSocket()
@ -189,10 +187,24 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
//bot.waitForPacket(ServerTouchResponsePacket::class, timeoutMillis) { //bot.waitForPacket(ServerTouchResponsePacket::class, timeoutMillis) {
// loginResult?.complete(LoginState.TIMEOUT) // loginResult?.complete(LoginState.TIMEOUT)
//} //}
var received = false
ServerPacketReceivedEvent.subscribe {
if (it.packet is ServerTouchResponsePacket && it.bot === bot) {
received = true
ListeningStatus.STOPPED
} else
ListeningStatus.LISTENING
}
NetworkScope.launch {
delay(2000)
if (!received) {
loginResult.complete(LoginState.TIMEOUT)
}
}
sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP)) sendPacket(ClientTouchPacket(bot.account.qqNumber, serverIP))
return withContext(Dispatchers.IO) { return withContext(Dispatchers.IO) {
loginResult!!.await() loginResult.await()
} }
} }
@ -227,11 +239,10 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
override fun close() { override fun close() {
this.socket?.close() this.socket?.close()
if (this.loginResult != null) { if (this::loginResult.isInitialized) {
if (!this.loginResult!!.isCompleted) { if (!this.loginResult.isCompleted && !this.loginResult.isCancelled) {
this.loginResult!!.cancel(CancellationException("socket closed")) this.loginResult.cancel(CancellationException("socket closed"))
} }
this.loginResult = null
} }
} }
@ -282,7 +293,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
} }
is ServerLoginResponseFailedPacket -> { is ServerLoginResponseFailedPacket -> {
socket.loginResult?.complete(packet.loginState) socket.loginResult.complete(packet.loginState)
bot.close() bot.close()
return return
} }
@ -375,7 +386,7 @@ internal class TIMBotNetworkHandler(private val bot: Bot) : BotNetworkHandler {
socket.sendPacket(ClientHeartbeatPacket(bot.account.qqNumber, sessionKey)) socket.sendPacket(ClientHeartbeatPacket(bot.account.qqNumber, sessionKey))
} }
socket.loginResult!!.complete(LoginState.SUCCESS) socket.loginResult.complete(LoginState.SUCCESS)
loginHandler.changeOnlineStatus(ClientLoginStatus.ONLINE) loginHandler.changeOnlineStatus(ClientLoginStatus.ONLINE)
} }

View File

@ -40,6 +40,7 @@ object TIMProtocol {
* _fixVer * _fixVer
*/ */
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
/** /**
* 0825data1 * 0825data1
*/ */
@ -81,7 +82,8 @@ object TIMProtocol {
/** /**
* 没有任何地方写入了这个 key * 没有任何地方写入了这个 key
*/ */
const val shareKey = "1A E9 7F 7D C9 73 75 98 AC 02 E0 80 5F A9 C6 AF"//16 //const val shareKey = "5B 6C 91 55 D9 92 F5 A7 99 85 37 76 3D 0F 08 B7"//16
const val shareKey = "1A E9 7F 7D C9 73 75 98 AC 02 E0 80 5F A9 C6 AF"//16//original
const val key00BA = "C1 9C B8 C8 7B 8C 81 BA 9E 9E 7A 89 E1 7A EC 94" const val key00BA = "C1 9C B8 C8 7B 8C 81 BA 9E 9E 7A 89 E1 7A EC 94"
const val key00BAFix = "69 20 D1 14 74 F5 B3 93 E4 D5 02 B3 71 1A CD 2A" const val key00BAFix = "69 20 D1 14 74 F5 B3 93 E4 D5 02 B3 71 1A CD 2A"

View File

@ -7,10 +7,10 @@ interface Packet
internal object PacketNameFormatter { internal object PacketNameFormatter {
@JvmSynthetic @JvmStatic
private var longestNameLength: Int = 43 private var longestNameLength: Int = 43
@JvmSynthetic @JvmStatic
fun adjustName(name: String): String { fun adjustName(name: String): String {
if (name.length > longestNameLength) { if (name.length > longestNameLength) {
longestNameLength = name.length longestNameLength = name.length

View File

@ -2,10 +2,12 @@
package net.mamoe.mirai.network.protocol.tim.packet package net.mamoe.mirai.network.protocol.tim.packet
import kotlinx.coroutines.* import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent import net.mamoe.mirai.event.events.network.ServerPacketReceivedEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeWhileTrue import net.mamoe.mirai.event.subscribeWhileTrue
import net.mamoe.mirai.network.protocol.tim.packet.PacketNameFormatter.adjustName import net.mamoe.mirai.network.protocol.tim.packet.PacketNameFormatter.adjustName
import net.mamoe.mirai.network.protocol.tim.packet.action.ServerCanAddFriendResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.action.ServerCanAddFriendResponsePacket
@ -13,7 +15,6 @@ import net.mamoe.mirai.network.protocol.tim.packet.action.ServerSendFriendMessag
import net.mamoe.mirai.network.protocol.tim.packet.action.ServerSendGroupMessageResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.action.ServerSendGroupMessageResponsePacket
import net.mamoe.mirai.network.protocol.tim.packet.image.ServerTryGetImageIDResponsePacket import net.mamoe.mirai.network.protocol.tim.packet.image.ServerTryGetImageIDResponsePacket
import net.mamoe.mirai.network.protocol.tim.packet.login.* import net.mamoe.mirai.network.protocol.tim.packet.login.*
import net.mamoe.mirai.task.MiraiThreadPool
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import java.io.DataInputStream import java.io.DataInputStream
import java.io.EOFException import java.io.EOFException
@ -84,9 +85,9 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
return ServerLoginResponseFailedPacket(when (bytes.size) { return ServerLoginResponseFailedPacket(when (bytes.size) {
135 -> LoginState.UNKNOWN//账号已经在另一台电脑登录?? 135 -> LoginState.UNKNOWN//账号已经在另一台电脑登录??
63, 319, 351 -> LoginState.WRONG_PASSWORD//63不是密码错误, 应该是登录过频繁 319, 351 -> LoginState.WRONG_PASSWORD
//135 -> LoginState.RETYPE_PASSWORD //135 -> LoginState.RETYPE_PASSWORD
279 -> LoginState.BLOCKED 63, 279 -> LoginState.BLOCKED
263 -> LoginState.UNKNOWN_QQ_NUMBER 263 -> LoginState.UNKNOWN_QQ_NUMBER
551, 487 -> LoginState.DEVICE_LOCK 551, 487 -> LoginState.DEVICE_LOCK
359 -> LoginState.TAKEN_BACK 359 -> LoginState.TAKEN_BACK
@ -306,8 +307,8 @@ fun <N : Number> DataInputStream.readShortAt(position: N): Short {
return this.readShort() return this.readShort()
} }
//添加@JvmSynthetic 导致 idea 无法检查这个文件的错误
@JvmSynthetic //@JvmSynthetic
fun DataInputStream.gotoWhere(matcher: UByteArray): DataInputStream { fun DataInputStream.gotoWhere(matcher: UByteArray): DataInputStream {
return this.gotoWhere(matcher.toByteArray()) return this.gotoWhere(matcher.toByteArray())
} }

View File

@ -26,14 +26,16 @@ class ClientSendFriendMessagePacket(
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") writeHex("37 0F")//TIM最新: 38 03
writeQQ(botQQ) writeQQ(botQQ)
writeQQ(targetQQ) writeQQ(targetQQ)
write(md5(lazyEncode { md5Key -> md5Key.writeQQ(targetQQ); md5Key.write(sessionKey) })) write(md5(lazyEncode { md5Key -> md5Key.writeQQ(targetQQ); md5Key.write(sessionKey) }))
writeHex("00 0B") writeHex("00 0B")
writeRandom(2) writeRandom(2)
writeTime() writeTime()
writeHex("00 00 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00") writeHex("00 00" +
"00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00")
//01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00
writeTime() writeTime()
writeRandom(4) writeRandom(4)
writeHex("00 00 00 00 09 00 86") writeHex("00 00 00 00 09 00 86")
@ -54,5 +56,9 @@ class ClientSendFriendMessagePacket(
} }
} }
fun main() {
}
@PacketId("00 CD") @PacketId("00 CD")
class ServerSendFriendMessageResponsePacket(input: DataInputStream) : ServerPacket(input) class ServerSendFriendMessageResponsePacket(input: DataInputStream) : ServerPacket(input)

View File

@ -0,0 +1,42 @@
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
package net.mamoe.mirai.utils
import com.sun.jna.Library
import com.sun.jna.Native
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import sun.misc.Unsafe
/**
* @author Him188moe
*/
object ECDH : IECDH by Native.load("ecdhdll64", IECDH::class.java)
interface IECDH : Library {
//fun encrypt(publicKey: UByteArray, shaKey: UByteArray): UByteArray
fun encrypt(publicKey: Long, shaKey: Long): Long
}
fun main() {
//
// ECDH.encrypt(TIMProtocol.publicKey.hexToUBytes(), TIMProtocol.key0836.hexToUBytes())
val unsafe = Unsafe::class.java.getDeclaredField("theUnsafe").also { it.trySetAccessible() }.get(null) as Unsafe
val publicKeyAddress = unsafe.allocateMemory(25)
TIMProtocol.publicKey.hexToUBytes().forEachIndexed { index, value ->
unsafe.setMemory(publicKeyAddress + index, 1, value.toByte())
}
val key0836Address = unsafe.allocateMemory(16)
TIMProtocol.key0836.hexToUBytes().forEachIndexed { index, value ->
unsafe.setMemory(key0836Address + index, 1, value.toByte())
}
val encrypt = ECDH.encrypt(publicKeyAddress, key0836Address)
//
val bytes = mutableListOf<Byte>()
repeat(16) {
bytes += unsafe.getByte(encrypt + it)
}
println(bytes.toByteArray().toUHexString())
}

View File

@ -162,7 +162,7 @@ object TEA {
} }
fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? { fun decrypt(cipherText: ByteArray, offset: Int, len: Int): ByteArray? {
require(!(len % 8 != 0 || len < 16)) { "must len % 8 == 0 && len >= 16" } require(!(len % 8 != 0 || len < 16)) { "data must len % 8 == 0 && len >= 16" }
mIV = decode(cipherText, offset) mIV = decode(cipherText, offset)
mIndexPos = (mIV[0] and 7).toInt() mIndexPos = (mIV[0] and 7).toInt()
var plen = len - mIndexPos - 10 var plen = len - mIndexPos - 10

View File

@ -15,7 +15,6 @@ import java.util.zip.CRC32
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream import java.util.zip.GZIPOutputStream
import javax.imageio.ImageIO import javax.imageio.ImageIO
import kotlin.jvm.JvmSynthetic
/** /**
@ -23,7 +22,7 @@ import kotlin.jvm.JvmSynthetic
* @author NaturalHG * @author NaturalHG
*/ */
@JvmSynthetic //@JvmSynthetic
fun ByteArray.toHexString(): String = toHexString(" ") fun ByteArray.toHexString(): String = toHexString(" ")
fun ByteArray.toHexString(separator: String = " "): String = this.joinToString(separator) { fun ByteArray.toHexString(separator: String = " "): String = this.joinToString(separator) {
@ -38,11 +37,11 @@ fun ByteArray.toHexString(separator: String = " "): String = this.joinToString(s
fun ByteArray.toUHexString(separator: String = " "): String = this.toUByteArray().toUHexString(separator) fun ByteArray.toUHexString(separator: String = " "): String = this.toUByteArray().toUHexString(separator)
@JvmSynthetic //@JvmSynthetic
fun ByteArray.toUHexString(): String = this.toUByteArray().toUHexString() fun ByteArray.toUHexString(): String = this.toUByteArray().toUHexString()
@JvmSynthetic //@JvmSynthetic
fun UByteArray.toUHexString(separator: String = " "): String { fun UByteArray.toUHexString(separator: String = " "): String {
return this.joinToString(separator) { return this.joinToString(separator) {
var ret = it.toString(16).toUpperCase() var ret = it.toString(16).toUpperCase()
@ -54,7 +53,7 @@ fun UByteArray.toUHexString(separator: String = " "): String {
} }
@JvmSynthetic //@JvmSynthetic
fun UByteArray.toUHexString(): String = this.toUHexString(" ") fun UByteArray.toUHexString(): String = this.toUHexString(" ")
@ -79,10 +78,8 @@ open class ByteArrayDataOutputStream : DataOutputStream(ByteArrayOutputStream())
open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray() open fun toUByteArray(): UByteArray = (out as ByteArrayOutputStream).toByteArray().toUByteArray()
} }
@JvmSynthetic
fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().also(t).toByteArray() fun lazyEncode(t: (ByteArrayDataOutputStream) -> Unit): ByteArray = ByteArrayDataOutputStream().also(t).toByteArray()
@JvmSynthetic
fun <T> lazyDecode(byteArray: ByteArray, t: (DataInputStream) -> T): T = byteArray.dataInputStream().let(t) fun <T> lazyDecode(byteArray: ByteArray, t: (DataInputStream) -> T): T = byteArray.dataInputStream().let(t)
fun DataInputStream.skip(n: Number) { fun DataInputStream.skip(n: Number) {
@ -95,7 +92,6 @@ fun getRandomByteArray(length: Int): ByteArray {
return bytes.toByteArray() return bytes.toByteArray()
} }
@JvmSynthetic
operator fun File.plus(child: String): File = File(this, child) operator fun File.plus(child: String): File = File(this, child)
private const val GTK_BASE_VALUE: Int = 5381 private const val GTK_BASE_VALUE: Int = 5381

View File

@ -15,7 +15,7 @@ import java.io.DataInputStream
* @author Him188moe * @author Him188moe
*/ */
object Main { object Main {
const val localIp = "192.168.3.10" const val localIp = "192.168.3."
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
@ -41,7 +41,7 @@ object Main {
val caplen = 4096 val caplen = 4096
val promiscCheck = true val promiscCheck = true
jpcap = JpcapCaptor.openDevice(devices[1], caplen, promiscCheck, 50) jpcap = JpcapCaptor.openDevice(devices[0], caplen, promiscCheck, 50)
/*----------第二步抓包-----------------*/ /*----------第二步抓包-----------------*/
@ -55,10 +55,11 @@ object Main {
continue continue
} }
if (localIp == pk.dst_ip.hostAddress) {//接受 if (localIp in pk.dst_ip.hostAddress) {//接受
dataReceived(pk.data) dataReceived(pk.data)
} else { } else {
try { try {
println("size = " + pk.data.size)
dataSent(pk.data) dataSent(pk.data)
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
@ -116,13 +117,21 @@ object Main {
println("Got sessionKey=" + sessionKey.toUHexString()) println("Got sessionKey=" + sessionKey.toUHexString())
} }
is ServerEventPacket.Raw.Encrypted -> {
val sessionKey = "8B 45 10 0F 10 00 66 0F 38 00 05 20 39 18 64 0F".hexToBytes()
println("! ServerEventPacket.Raw.Encrypted")
packetReceived(packet.decrypt(sessionKey))
println("! decrypt succeed")
}
else -> { else -> {
} }
} }
} }
@Volatile @Volatile
private var debugStarted = false private var debugStarted = true
private const val qq: Int = 1994701021 private const val qq: Int = 1994701021
private const val password: String = "xiaoqqq" private const val password: String = "xiaoqqq"
@ -141,14 +150,29 @@ object Main {
lazyDecode(data.cutTail(1)) { lazyDecode(data.cutTail(1)) {
it.skip(3) it.skip(3)
val idHex = it.readNBytes(4).toUHexString() val idHex = it.readNBytes(4).toUHexString()
println("qq=" + it.readUInt()) println("发出包$idHex")
println(idHex)
when (idHex.substring(0, 5)) { when (idHex.substring(0, 5)) {
"08 25" -> { "08 25" -> {
debugStarted = true debugStarted = true
println("Detected touch, debug start!!") println("Detected touch, debug start!!")
} }
"00 CD" -> {
println("好友消息发出: ")
val sessionKey = "70 BD 1E 12 20 C1 25 12 A0 F8 4F 0D C0 A0 97 0E".hexToBytes()
lazyDecode(data) {
//it.readShort()
//println(it.readUInt())
println(it.readNBytes(TIMProtocol.fixVer2.hexToBytes().size + 1 + 5 - 3 + 1).toUHexString())
it.readAllBytes().let {
println("解密")
println(it.size)
println(it.toUHexString())
println(it.decryptBy(sessionKey).toUHexString())
}
}
}
"08 36" -> { "08 36" -> {
println(data.toUHexString()) println(data.toUHexString())
println("tim的 passwordSubmissionKey1 = " + it.readNBytes(TIMProtocol.passwordSubmissionTLV1.hexToBytes().size).toUHexString()) println("tim的 passwordSubmissionKey1 = " + it.readNBytes(TIMProtocol.passwordSubmissionTLV1.hexToBytes().size).toUHexString())
@ -200,9 +224,9 @@ object Main {
val shareKeyFromCS = "60 42 3B 51 C3 B1 F6 0F 67 E8 9C 00 F0 A7 BD A3" val shareKeyFromCS = "60 42 3B 51 C3 B1 F6 0F 67 E8 9C 00 F0 A7 BD A3"
fun main() { fun main() {
val data = "76 AF AE 95 EB 89 BE B5 1C 83 D2 87 23 3B 5A 3B 6B 4C 78 AD F9 93 86 CA 13 D7 86 B5 0C D1 84 FB 2B ED 59 26 42 3B E0 6F 1A 91 A5 98 91 20 25 3F 6D C0 F6 FC 27 3D F8 34 EA 50 95 8C 2A BB 22 73 BD 76 60 2A 6B 68 51 07 4A 2F 37 6D 97 42 51 C5 14 47 96 3A A9 6B 8F 66 F8 D4 F4 52 22 13 D5 CC 9F B1 B4 06 BC 4B 35 B6 CF D8 CB 70 0F 0C E6 AA D9 12 E9 A2 C7 7F D8 24 7E 1B 2D 97 67 DA 34 0A FD 8E 44 D3 58 50 0D F0 0A 20 08 0A 46 28 68 0A 06 17 36 84 94 2C 97 2A 22 32 7B 01 67 3F E4 90 71 88 B2 F9 7B 7B AC 1A 00 CD 54 4A D7 AE 71 68 B3 FB E5 F3 94 9A C2 A1 C3 CA A5 4E AB 2C B0 78 AD EE 63 3F E6 24 6E AC 31 A5 00 F4 DB C7 4B 65 44 7B 92 87 30 7D 73 B3 21 81 C8 99 33 06 65 28 0C 98 56 EF 41 DC 64 79 55 69 AD B7 F4 A4 CF 4A 28 4B 3B E3 5A 2B C1 72 20 95 D9 8E 9F 1E A5 DE 9A DD 39 0B BE 76 A8 BE 95 9D 7C C2 C5 A8 3A D3 76 B6 D4 ED 15 34 5D 3C 8E 96 C6 93 64 78 A1 89 78 DA F8 17 E5 96 75 5F B6 97 FC 41 18 A4 54 67 BA 3B ED 97 27 B7 E3 90 81 1E DC 8D 17 25 46 2D 08 0D BB 95 D0 CB C8 9B 78 36 2D 70 E3 C6 4C 21 E9 C0 02 69 3B C5 F7 91 6B 62 D8 E4 10 F0 01 5B 7F 1A 3E 9F 1A D4 D3 A9 2B 4A C2 BD 6D 8B B0 0A AE A4 E9 72 71 F4 39 28 CE 18 42 ED FD BB 61 08 B1 95 93 8E F6 29 D7 B6 CB 15 2A AA AF A7 81 AD DF 3B D5 3F 47 29 AB 61 0C 86 48 82 93 AE 8C 2C 32 CC 83 83 68 08 C6 9D 10 81 82 BA 92 24 0E ED 71 B1 83 E1 08 D0 01 BB DF E2 26 D0 20 DF 8C 95 E1 A6 42 C2 A2 E7 85 00 E6 AA 54 A8 0C 5D BB 8D 46 37 AD 47 88 38 B9 D7 3B 48 13 13 81 3B A5 05 4D 32 24 A4 CE 08 73 6D 89 FD 6D CC F5 AB 8B 6A 39 4B 9D 30 33 73 F1 01 7F E4 43 03 72 44 67 3A 24 28 40 51 2B EB 48 EB F9 05 A9 3C 20 EB 4D B7 45 56 D3 4E BD A0 B5 40 65 D1 16 57 73 A4 81 B1 A6 8C 3F 68 28 AA EB 83".hexToBytes() val data = "2C 3C 4A 0D 14 D3 C4 8D FA 99 58 02 87 04 47 66 F9 F9 4F DF B8 01 1E C6 2A 52 3E 83 B0 96 4C 1C 3C D0 1C A0 D6 58 3C D0 2B 6B 33 1E 37 0A 6E C3 49 CE 57 B0 70 41 88 C1 3B A3 61 72 5E 3C 65 EC B1 2E EC 25 0E 1B 66 7A C4 28 F7 1D 53 15 56 99 BB 18 90 ED E6 13 97 19 FE 42 DB D1 16 E3 21 77 6E 90 B8 E2 5A 6D C3 AE FF 5C 63 98 AE 42 B0 AB 96 0B 08 D8 DA E0 D3 BD 17 E4 7B 76 1C 16 17 DC".hexToBytes()
println(TEA.decrypt(data, TIMProtocol.shareKey.hexToBytes())) println(TEA.decrypt(data, "9A 45 7B D4 54 EF 7C E7 86 F5 20 EF 27 BE CF C1".hexToBytes()).toUHexString())
//succeed
} }

View File

@ -20,9 +20,9 @@ import kotlin.system.exitProcess
* @author Him188moe * @author Him188moe
*/ */
suspend fun main() { suspend fun main() {
val bot = Bot(BotAccount( val bot = Bot(BotAccount(//填写你的账号
qqNumber = 1683921395, qqNumber = 1994701021,
password = "bb22222" password = "xiaoqqq"
), Console()) ), Console())
bot.login().let { bot.login().let {

View File

@ -6,10 +6,3 @@ include(':mirai-demos:mirai-demo-1')
include(':mirai-demos') include(':mirai-demos')
include(':mirai-debug') include(':mirai-debug')
project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1') project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1')
def kotlinVersion = "1.3.50"
def coroutinesVersion = "1.3.0-M2"
def kotlinStandardLib = "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
def kotlinCoroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion"