Skip to content

Commit

Permalink
Generate and handle tgtgtKey correctly, fix mamoe#2418
Browse files Browse the repository at this point in the history
  • Loading branch information
sandtechnology committed Jan 11, 2023
1 parent b38687a commit db8f1f0
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.utils.*
import kotlin.jvm.Synchronized
import kotlin.jvm.Volatile
import kotlin.random.Random

/**
* For a [Bot].
Expand Down Expand Up @@ -138,7 +139,7 @@ internal fun AccountSecretsImpl(
dpwd = get_mpasswd().toByteArray(),
randSeed = EMPTY_BYTE_ARRAY,
ksid = EMPTY_BYTE_ARRAY,
tgtgtKey = (account.passwordMd5 + ByteArray(4) + account.id.toInt().toByteArray()).md5(),
tgtgtKey = (Random.nextBytes(16) + device.guid).md5(),
randomKey = getRandomByteArray(16),
ecdhInitialPublicKey = QQEcdhInitialPublicKey.default
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,9 @@ internal class WtLogin {
tlvMap119.smartToString().printStructure("TlvMap119")
}

tlvMap119[0x106]?.let { client.analyzeTlv106(it) }
tlvMap119[0x10c]?.read {
client.tgtgtKey = readBytes(16)
}

// ???
tlvMap119[0x1c]?.read {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import io.ktor.utils.io.core.*
import net.mamoe.mirai.internal.network.*
import net.mamoe.mirai.internal.network.protocol.packet.*
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.utils.io.writeShortLVPacket

internal object WtLogin9 : WtLoginExt {
private const val appId = 16L
Expand All @@ -26,13 +27,20 @@ internal object WtLogin9 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(9) // subCommand
writeShort(if (allowSlider) 0x18 else 0x17) // count of TLVs, probably ignored by server?
writeShort((if (client.wLoginSigInfoInitialized && client.wLoginSigInfo.noPicSig != null) (if (allowSlider) 0x18 else 0x17) + 1 else (if (allowSlider) 0x18 else 0x17)).toShort()) // count of TLVs, probably ignored by server?
//writeShort(LoginType.PASSWORD.value.toShort())

t18(appId, client.appClientVersion, client.uin)
t1(client.uin, client.device.ipAddress)

t106(appId, client)
if (client.wLoginSigInfoInitialized && client.wLoginSigInfo.encryptA1 != null) {
writeShort(0x106)
writeShortLVPacket {
writeFully(client.wLoginSigInfo.encryptA1!!)
}
} else {
t106(appId, client)
}

/* // from GetStWithPasswd
int mMiscBitmap = this.mMiscBitmap;
Expand Down Expand Up @@ -66,8 +74,9 @@ internal object WtLogin9 : WtLoginExt {
t166(1)
}
*/

// ignored t16a because array5 is null
if (client.wLoginSigInfoInitialized && client.wLoginSigInfo.noPicSig != null) {
t16a(client.wLoginSigInfo.noPicSig!!)
}

t154(sequenceId)
t141(client.device.simInfo, client.networkType, client.device.apn)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import net.mamoe.mirai.internal.network.WLoginSigInfo
import net.mamoe.mirai.internal.network.protocol.packet.Tlv
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.protocol.packet.t145
import net.mamoe.mirai.internal.utils.crypto.TEA
import net.mamoe.mirai.internal.utils.io.writeShortLVByteArray
import net.mamoe.mirai.utils.*

Expand Down Expand Up @@ -208,22 +207,9 @@ internal interface WtLoginExt { // so as not to register to global extension
}
}

fun QQAndroidClient.analyzeTlv106(t106: ByteArray) {
val tgtgtKey = decodeA1(t106) {
discardExact(51)
readBytes(16)
}
this.tgtgtKey = tgtgtKey
}

fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
}

internal inline fun <R> QQAndroidClient.decodeA1(a1: ByteArray, block: ByteReadPacket.() -> R): R {
val key = (account.passwordMd5 + ByteArray(4) + uin.toInt().toByteArray()).md5()
val v = TEA.decrypt(a1, key)
return v.toReadPacket().withUse(block)
}

internal fun ByteArray?.orEmpty(size: Int = 0): ByteArray {
return this ?: if (size == 0) EMPTY_BYTE_ARRAY else ByteArray(size)
Expand Down

0 comments on commit db8f1f0

Please sign in to comment.