Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update login protocol, fix #2426 #2433

Merged
merged 10 commits into from
Jan 18, 2023
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ const val `netty-transport` = "io.netty:netty-transport:${Versions.netty}"
const val `netty-buffer` = "io.netty:netty-buffer:${Versions.netty}"
const val `bouncycastle` = "org.bouncycastle:bcprov-jdk15on:${Versions.bouncycastle}"

const val `kt-bignum` = "com.ionspin.kotlin:bignum:0.3.7"
val `kt-bignum_relocated` = RelocatedDependency(`kt-bignum`, "com.ionspin.kotlin.bignum")

const val `maven-resolver-api` = "org.apache.maven.resolver:maven-resolver-api:${Versions.mavenArtifactResolver}"
const val `maven-resolver-impl` = "org.apache.maven.resolver:maven-resolver-impl:${Versions.mavenArtifactResolver}"
const val `maven-resolver-connector-basic` =
Expand Down
1 change: 1 addition & 0 deletions mirai-core-all/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies {
api(project(":mirai-core-utils"))
implementation(`slf4j-api`) // Required by mirai-console

relocateImplementation(project, `kt-bignum_relocated`)
relocateImplementation(project, `ktor-client-core_relocated`)
relocateImplementation(project, `ktor-client-okhttp_relocated`)
relocateImplementation(project, `ktor-io_relocated`)
Expand Down
5 changes: 4 additions & 1 deletion mirai-core-utils/src/commonMain/kotlin/ByteArrayOp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public fun String.sha1(): ByteArray = toByteArray().sha1()

public expect fun ByteArray.sha1(offset: Int = 0, length: Int = size - offset): ByteArray

public fun String.sha256(): ByteArray = toByteArray().sha256()

public expect fun ByteArray.sha256(offset: Int = 0, length: Int = size - offset): ByteArray

///////////////////////////////////////////////////////////////////////////
// How to choose 'inflate', 'inflateAllAvailable', 'InflateInput'?
Expand Down Expand Up @@ -112,4 +115,4 @@ public expect fun DeflateInput(source: Input): Input
/**
* @see DeflateInput
*/
public fun Input.deflateInput(): Input = DeflateInput(this)
public fun Input.deflateInput(): Input = DeflateInput(this)
12 changes: 11 additions & 1 deletion mirai-core-utils/src/jvmBaseMain/kotlin/ByteArrayOp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
package net.mamoe.mirai.utils

import io.ktor.utils.io.core.*
import io.ktor.utils.io.streams.asInput
import io.ktor.utils.io.streams.*
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream
Expand Down Expand Up @@ -50,6 +50,10 @@ public fun InputStream.sha1(): ByteArray {
return digest("SHA-1")
}

public fun InputStream.sha256(): ByteArray {
return digest("SHA-256")
}

public actual fun ByteArray.md5(offset: Int, length: Int): ByteArray {
checkOffsetAndLength(offset, length)
return MessageDigest.getInstance("MD5").apply { update(this@md5, offset, length) }.digest()
Expand All @@ -62,6 +66,12 @@ public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray {
return MessageDigest.getInstance("SHA-1").apply { update(this@sha1, offset, length) }.digest()
}

@JvmOverloads
public actual fun ByteArray.sha256(offset: Int, length: Int): ByteArray {
checkOffsetAndLength(offset, length)
return MessageDigest.getInstance("SHA-256").apply { update(this@sha256, offset, length) }.digest()
}

@JvmOverloads
public actual fun ByteArray.gzip(offset: Int, length: Int): ByteArray {
ByteArrayOutputStream().use { buf ->
Expand Down
5 changes: 5 additions & 0 deletions mirai-core-utils/src/nativeMain/kotlin/ByteArrayOp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public actual fun ByteArray.sha1(offset: Int, length: Int): ByteArray = SHA1.cre
return digest().bytes
}

public actual fun ByteArray.sha256(offset: Int, length: Int): ByteArray = SHA256.create().run {
update(this@sha256, offset, length)
return digest().bytes
}

/**
* WARNING: DO NOT SET THIS BUFFER TOO SMALL, OR YOU WILL SEE COMPRESSION ERROR.
*/
Expand Down
76 changes: 76 additions & 0 deletions mirai-core-utils/src/nativeMain/kotlin/CommonDigest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,79 @@ internal class SHA1 : SHA(chunkSize = 64, digestSize = 20) {
for (n in out.indices) out[n] = (h[n / 4] ushr (24 - 8 * (n % 4))).toByte()
}
}

internal class SHA256 : SHA(chunkSize = 64, digestSize = 32) {
companion object : HasherFactory({ SHA256() }) {
private val H = intArrayOf(
0x6a09e667, -0x4498517b, 0x3c6ef372, -0x5ab00ac6,
0x510e527f, -0x64fa9774, 0x1f83d9ab, 0x5be0cd19
)

private val K = intArrayOf(
0x428a2f98, 0x71374491, -0x4a3f0431, -0x164a245b,
0x3956c25b, 0x59f111f1, -0x6dc07d5c, -0x54e3a12b,
-0x27f85568, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, -0x7f214e02, -0x6423f959, -0x3e640e8c,
-0x1b64963f, -0x1041b87a, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-0x67c1aeae, -0x57ce3993, -0x4ffcd838, -0x40a68039,
-0x391ff40d, -0x2a586eb9, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, -0x7e3d36d2, -0x6d8dd37b,
-0x5d40175f, -0x57e599b5, -0x3db47490, -0x3893ae5d,
-0x2e6d17e7, -0x2966f9dc, -0xbf1ca7b, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, -0x7b3787ec, -0x7338fdf8,
-0x6f410006, -0x5baf9315, -0x41065c09, -0x398e870e
)
}


private val h = IntArray(8)
private val r = IntArray(8)
private val w = IntArray(64)

init {
coreReset()
}

override fun coreReset() {
arraycopy(H, 0, h, 0, 8)
}

override fun coreUpdate(chunk: ByteArray) {
arraycopy(h, 0, r, 0, 8)

for (j in 0 until 16) w[j] = chunk.readS32_be(j * 4)
for (j in 16 until 64) {
val s0 = w[j - 15].rotateRight(7) xor w[j - 15].rotateRight(18) xor w[j - 15].ushr(3)
val s1 = w[j - 2].rotateRight(17) xor w[j - 2].rotateRight(19) xor w[j - 2].ushr(10)
w[j] = w[j - 16] + s0 + w[j - 7] + s1
}

for (j in 0 until 64) {
val s1 = r[4].rotateRight(6) xor r[4].rotateRight(11) xor r[4].rotateRight(25)
val ch = r[4] and r[5] xor (r[4].inv() and r[6])
val t1 = r[7] + s1 + ch + K[j] + w[j]
val s0 = r[0].rotateRight(2) xor r[0].rotateRight(13) xor r[0].rotateRight(22)
val maj = r[0] and r[1] xor (r[0] and r[2]) xor (r[1] and r[2])
val t2 = s0 + maj
r[7] = r[6]
r[6] = r[5]
r[5] = r[4]
r[4] = r[3] + t1
r[3] = r[2]
r[2] = r[1]
r[1] = r[0]
r[0] = t1 + t2

}
for (j in 0 until 8) h[j] += r[j]
}

override fun coreDigest(out: ByteArray) {
for (n in out.indices) out[n] = (h[n / 4] ushr (24 - 8 * (n % 4))).toByte()
}
}

9 changes: 9 additions & 0 deletions mirai-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ kotlin {
api(`kotlinx-serialization-json`)
api(`kotlinx-coroutines-core`)

implementation(`kt-bignum`)
implementation(project(":mirai-core-utils"))
implementation(`kotlinx-serialization-protobuf`)
implementation(`kotlinx-atomicfu`)
Expand Down Expand Up @@ -108,6 +109,14 @@ kotlin {
}


// Kt bignum
findByName("jvmBaseMain")?.apply {
dependencies {
relocateImplementation(`kt-bignum_relocated`)
}
}


// Ktor

findByName("commonMain")?.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ internal open class QQAndroidClient(
var reserveUinInfo: ReserveUinInfo? = null
var t402: ByteArray? = null
lateinit var t104: ByteArray
var t547: ByteArray? = null
}

internal val QQAndroidClient.apkId: ByteArray get() = "com.tencent.mobileqq".toByteArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,15 @@ internal fun BytePacketBuilder.t104(
}
}

internal fun BytePacketBuilder.t547(
t547Data: ByteArray
) {
writeShort(0x547)
writeShortLVPacket {
writeFully(t547Data)
}
}

internal fun BytePacketBuilder.t174(
t174Data: ByteArray
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ internal class WtLogin {
tlvMap[0x161]?.let { bot.client.analysisTlv161(it) }
tlvMap[0x403]?.let { bot.client.randSeed = it }
tlvMap[0x402]?.let { bot.client.t402 = it }
tlvMap[0x546]?.let { bot.client.analysisTlv546(it) }
// tlvMap[0x402]?.let { t402 ->
// bot.client.G = buildPacket {
// writeFully(bot.client.device.guid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal object WtLogin10 : WtLoginExt {
0x0810
) {
writeShort(11) // subCommand
writeShort(17)
writeShort(18)
t100(appId, subAppId, client.appClientVersion, client.ssoVersion, mainSigMap)
t10a(client.wLoginSigInfo.tgt)
t116(client.miscBitMap, client.subSigMap)
Expand Down Expand Up @@ -80,6 +80,7 @@ internal object WtLogin10 : WtLoginExt {
t188(client.device.androidId)
t194(client.device.imsiMd5)
t511()
t202(client.device.wifiBSSID, client.device.wifiSSID)
//t544()

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,20 @@ internal object WtLogin2 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand
writeShort(4) // count of TLVs
writeShort(
if (client.t547 == null) {
4
} else {
5
}
) // count of TLVs
t193(ticket)
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
client.t547?.let {
t547(it)
}
}
}
}
Expand All @@ -43,11 +52,20 @@ internal object WtLogin2 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand
writeShort(4) // count of TLVs
writeShort(
if (client.t547 == null) {
4
} else {
5
}
) // count of TLVs
t2(captchaAnswer, captchaSign, 0)
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
client.t547?.let {
t547(it)
}
}
}
}
Expand Down
Loading