1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-17 09:09:23 +08:00

Tlv writer ()

* [core] TlvMapWriter

* [core] bind tlv writing with writer

* [core] Add checking to avoid wrong nest writing

* [core] Drop Int.invoke

* [core] Merge with dev

* [core] Update style
This commit is contained in:
微莹·纤绫 2023-03-26 23:51:03 +08:00 committed by GitHub
parent 48db1a022f
commit 434ef0cc39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 811 additions and 569 deletions
mirai-core-utils/src
commonMain/kotlin
commonTest/kotlin/net/mamoe/mirai/utils
mirai-core/src/commonMain/kotlin/network/protocol/packet

View File

@ -75,82 +75,6 @@ public inline fun ByteReadPacket.readPacketExact(
): ByteReadPacket = this.readBytes(n).toReadPacket()
public typealias TlvMap = MutableMap<Int, ByteArray>
public inline fun TlvMap.getOrFail(tag: Int): ByteArray {
return this[tag] ?: error("cannot find tlv 0x${tag.toUHexString("")}($tag)")
}
public inline fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String): ByteArray {
return this[tag] ?: error(lazyMessage(tag))
}
@Suppress("FunctionName")
public inline fun Input._readTLVMap(tagSize: Int = 2, suppressDuplication: Boolean = true): TlvMap =
_readTLVMap(true, tagSize, suppressDuplication)
@Suppress("DuplicatedCode", "FunctionName")
public fun Input._readTLVMap(
expectingEOF: Boolean = true,
tagSize: Int,
suppressDuplication: Boolean = true
): TlvMap {
val map = mutableMapOf<Int, ByteArray>()
var key = 0
while (kotlin.run {
try {
key = when (tagSize) {
1 -> readUByte().toInt()
2 -> readUShort().toInt()
4 -> readUInt().toInt()
else -> error("Unsupported tag size: $tagSize")
}
} catch (e: Exception) { // java.nio.BufferUnderflowException is not a EOFException...
if (expectingEOF) {
return map
}
throw e
}
key
}.toUByte() != UByte.MAX_VALUE) {
if (map.containsKey(key)) {
@Suppress("ControlFlowWithEmptyBody")
if (!suppressDuplication) {
/*
@Suppress("DEPRECATION")
MiraiLogger.error(
@Suppress("IMPLICIT_CAST_TO_ANY")
"""
Error readTLVMap:
duplicated key ${when (tagSize) {
1 -> key.toByte()
2 -> key.toShort()
4 -> key
else -> error("unreachable")
}.contentToString()}
map=${map.contentToString()}
duplicating value=${this.readUShortLVByteArray().toUHexString()}
""".trimIndent()
)*/
} else {
this.discardExact(this.readShort().toInt() and 0xffff)
}
} else {
try {
map[key] = this.readBytes(readUShort().toInt())
} catch (e: Exception) { // BufferUnderflowException, java.io.EOFException
// if (expectingEOF) {
// return map
// }
throw e
}
}
}
return map
}
public fun Input.readAllText(): String = Charsets.UTF_8.newDecoder().decode(this)
public inline fun Input.readString(length: Int, charset: Charset = Charsets.UTF_8): String =

View File

@ -0,0 +1,225 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
import io.ktor.utils.io.core.*
import kotlin.jvm.JvmField
public typealias TlvMap = MutableMap<Int, ByteArray>
public fun TlvMap(): TlvMap = linkedMapOf()
@Suppress("FunctionName")
public fun Output._writeTlvMap(
tagSize: Int,
includeCount: Boolean = true,
map: TlvMap,
) {
if (includeCount) {
when (tagSize) {
1 -> writeByte(map.size.toByte())
2 -> writeShort(map.size.toShort())
4 -> writeInt(map.size)
else -> error("Unsupported tag size: $tagSize")
}
}
map.forEach { (key, value) ->
when (tagSize) {
1 -> writeByte(key.toByte())
2 -> writeShort(key.toShort())
4 -> writeInt(key)
else -> error("Unsupported tag size: $tagSize")
}
writeShort(value.size.toShort())
writeFully(value)
}
}
@Suppress("MemberVisibilityCanBePrivate")
public class TlvMapWriter
internal constructor(
private val tagSize: Int,
) {
@JvmField
internal val buffer = BytePacketBuilder()
@JvmField
internal var counter: Int = 0
@PublishedApi
@JvmField
internal var isWriting: Boolean = false
private fun writeKey(key: Int) {
when (tagSize) {
1 -> buffer.writeByte(key.toByte())
2 -> buffer.writeShort(key.toShort())
4 -> buffer.writeInt(key)
else -> error("Unsupported tag size: $tagSize")
}
counter++
}
@PublishedApi
internal fun ensureNotWriting() {
if (isWriting) error("Cannot write a new Tlv when writing Tlv")
}
public fun tlv(key: Int, data: ByteArray) {
ensureNotWriting()
tlv0(key, data)
}
private fun tlv0(key: Int, data: ByteArray) {
writeKey(key)
buffer.writeShort(data.size.toShort())
buffer.writeFully(data)
// println("Writing [${key.toUHexString()}](${data.size}) => " + data.toUHexString())
}
public fun tlv(key: Int, data: ByteReadPacket) {
ensureNotWriting()
tlv0(key, data)
}
@PublishedApi
internal fun tlv0(key: Int, data: ByteReadPacket) {
writeKey(key)
buffer.writeShort(data.remaining.toShort())
// println("Writing [${key.toUHexString()}](${data.remaining}) => " + data.copy()
// .use { d1 -> d1.readBytes().toUHexString() })
buffer.writePacket(data)
}
public inline fun tlv(
key: Int,
crossinline builder: BytePacketBuilder.() -> Unit,
) {
ensureNotWriting()
try {
isWriting = true
buildPacket(builder).use { tlv0(key, it) }
} finally {
isWriting = false
}
}
}
public fun Output._writeTlvMap(
tagSize: Int = 2,
includeCount: Boolean = true,
block: TlvMapWriter.() -> Unit
) {
val writer = TlvMapWriter(tagSize)
try {
block(writer)
if (includeCount) {
when (tagSize) {
1 -> writeByte(writer.counter.toByte())
2 -> writeShort(writer.counter.toShort())
4 -> writeInt(writer.counter)
else -> error("Unsupported tag size: $tagSize")
}
}
writer.buffer.build().use {
// println(it.copy().use { it.readBytes().toUHexString() })
writePacket(it)
}
} finally {
writer.buffer.release()
}
}
public fun TlvMap.getOrFail(tag: Int): ByteArray {
return this[tag] ?: error("cannot find tlv 0x${tag.toUHexString("")}($tag)")
}
public fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String): ByteArray {
return this[tag] ?: error(lazyMessage(tag))
}
@Suppress("FunctionName")
public fun Input._readTLVMap(tagSize: Int = 2, suppressDuplication: Boolean = true): TlvMap =
_readTLVMap(true, tagSize, suppressDuplication)
@Suppress("DuplicatedCode", "FunctionName")
public fun Input._readTLVMap(
expectingEOF: Boolean = true,
tagSize: Int,
suppressDuplication: Boolean = true
): TlvMap {
val map = linkedMapOf<Int, ByteArray>()
var key = 0
while (kotlin.run {
try {
key = when (tagSize) {
1 -> readUByte().toInt()
2 -> readUShort().toInt()
4 -> readUInt().toInt()
else -> error("Unsupported tag size: $tagSize")
}
} catch (e: Exception) { // java.nio.BufferUnderflowException is not a EOFException...
if (expectingEOF) {
return map
}
throw e
}
key
}.toUByte() != UByte.MAX_VALUE) {
if (map.containsKey(key)) {
// println("reading ${key.toUHexString()}")
if (!suppressDuplication) {
/*
@Suppress("DEPRECATION")
MiraiLogger.error(
@Suppress("IMPLICIT_CAST_TO_ANY")
"""
Error readTLVMap:
duplicated key ${when (tagSize) {
1 -> key.toByte()
2 -> key.toShort()
4 -> key
else -> error("unreachable")
}.contentToString()}
map=${map.contentToString()}
duplicating value=${this.readUShortLVByteArray().toUHexString()}
""".trimIndent()
)*/
} else {
this.discardExact(this.readShort().toInt() and 0xffff)
}
} else {
try {
val len = readUShort().toInt()
val data = this.readBytes(len)
// println("Writing [${key.toUHexString()}]($len) => ${data.toUHexString()}")
map[key] = data
} catch (e: Exception) { // BufferUnderflowException, java.io.EOFException
// if (expectingEOF) {
// return map
// }
throw e
}
}
}
return map
}

View File

@ -0,0 +1,135 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
import io.ktor.utils.io.core.*
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertContentEquals
import kotlin.test.assertEquals
import kotlin.test.assertTrue
internal class TlvMapTest {
private fun dumpTlvMap(map: TlvMap) = buildString {
append("tlvMap {\n")
map.forEach { (k, v) ->
append(" ").append(k.toUHexString()).append(" = ").append(v.toUHexString()).append("\n")
}
append("}")
}
private fun assertTlvMapEquals(
expected: TlvMap, actual: TlvMap,
) {
assertEquals(expected.size, actual.size, "map size not match")
expected.keys.forEach { key ->
assertTrue("Missing key[$key] in actual") { actual.containsKey(key) }
}
actual.keys.forEach { key ->
assertTrue("Missing key[$key] in expected") { expected.containsKey(key) }
}
expected.forEach { (key, value) ->
assertContentEquals(value, actual[key])
}
}
@Test
fun testTlvWriterNoLength() {
testTlvWriter(true)
}
@Test
fun testTlvWriterWithCount() {
testTlvWriter(false)
}
private fun testTlvWriter(withCount: Boolean) {
repeat(500) {
val tlvMap = TlvMap()
val rand = buildPacket {
_writeTlvMap(Short.SIZE_BYTES, includeCount = withCount) {
repeat(Random.nextInt().and(0xFF).coerceAtLeast(20)) {
val nextKey = Random.nextInt().and(0xFF0)
if (!tlvMap.containsKey(nextKey)) {
val randData = ByteArray(Random.nextInt().and(0xFFF))
Random.nextBytes(randData)
tlvMap[nextKey] = randData
tlv(nextKey, randData)
}
}
}
}.also { pkg ->
if (withCount) pkg.discardExact(2)
}._readTLVMap()
try {
assertTlvMapEquals(tlvMap, rand)
} catch (e: Throwable) {
println("gen: " + dumpTlvMap(tlvMap))
println("read: " + dumpTlvMap(rand))
throw e
}
}
}
@Test
fun testTlvWriterWithCounter() {
val expected = buildPacket {
writeShort(4) // count of TLVs
writeShort(0x01)
writeHexWithLength("66ccff")
writeShort(0x04)
writeHexWithLength("114514")
writeShort(0x19)
writeHexWithLength("198100")
writeShort(0x233)
writeHexWithLength("666666")
}.readBytes()
val actual = buildPacket {
_writeTlvMap {
tlv(0x001) { writeHex("66ccff") }
tlv(0x004) { writeHex("114514") }
tlv(0x019) { writeHex("198100") }
tlv(0x233) { writeHex("666666") }
println("counter = $counter")
}
}.readBytes()
println(expected.toUHexString())
println(actual.toUHexString())
assertContentEquals(expected, actual)
}
private fun Output.writeHex(data: String) {
writeFully(data.hexToBytes())
}
private fun Output.writeHexWithLength(data: String) {
val hxd = data.hexToBytes()
writeShort(hxd.size.toShort())
writeFully(hxd)
}
}

View File

@ -49,40 +49,38 @@ internal fun TlvMap.smartToString(leadingLineBreak: Boolean = true, sorted: Bool
@JvmInline
internal value class Tlv(val value: ByteArray)
internal fun BytePacketBuilder.t1(uin: Long, ip: ByteArray) {
internal fun TlvMapWriter.t1(uin: Long, ip: ByteArray) {
require(ip.size == 4) { "ip.size must == 4" }
writeShort(0x1)
writeShortLVPacket {
tlv(0x01) {
writeShort(1) // _ip_ver
writeInt(Random.nextInt())
writeInt(uin.toInt())
writeInt(currentTimeSeconds().toInt())
writeFully(ip)
writeShort(0)
} shouldEqualsTo 20
}
}
internal fun BytePacketBuilder.t2(captchaCode: String, captchaToken: ByteArray, sigVer: Short = 0) {
writeShort(0x2)
writeShortLVPacket {
internal fun TlvMapWriter.t2(captchaCode: String, captchaToken: ByteArray, sigVer: Short = 0) {
tlv(0x02) {
writeShort(sigVer)
writeShortLVString(captchaCode)
writeShortLVByteArray(captchaToken)
}
}
internal fun BytePacketBuilder.t8(
internal fun TlvMapWriter.t8(
localId: Int = 2052
) {
writeShort(0x8)
writeShortLVPacket {
tlv(0x08) {
writeShort(0)
writeInt(localId) // localId
writeShort(0)
}
}
internal fun BytePacketBuilder.t16(
internal fun TlvMapWriter.t16(
ssoVersion: Int,
subAppId: Long,
guid: ByteArray,
@ -90,8 +88,7 @@ internal fun BytePacketBuilder.t16(
apkVersionName: ByteArray,
apkSignatureMd5: ByteArray
) {
writeShort(0x16)
writeShortLVPacket {
tlv(0x16) {
writeInt(ssoVersion)
writeInt(16)
writeInt(subAppId.toInt())
@ -102,14 +99,13 @@ internal fun BytePacketBuilder.t16(
}
}
internal fun BytePacketBuilder.t18(
internal fun TlvMapWriter.t18(
appId: Long,
appClientVersion: Int = 0,
uin: Long,
constant1_always_0: Int = 0
) {
writeShort(0x18)
writeShortLVPacket {
tlv(0x18) {
writeShort(1) //_ping_version
writeInt(0x00_00_06_00) //_sso_version=1536
writeInt(appId.toInt())
@ -117,10 +113,10 @@ internal fun BytePacketBuilder.t18(
writeInt(uin.toInt())
writeShort(constant1_always_0.toShort())
writeShort(0)
} shouldEqualsTo 22
}
}
internal fun BytePacketBuilder.t1b(
internal fun TlvMapWriter.t1b(
micro: Int = 0,
version: Int = 0,
size: Int = 3,
@ -129,8 +125,7 @@ internal fun BytePacketBuilder.t1b(
ecLevel: Int = 2,
hint: Int = 2
) {
writeShort(0x1b)
writeShortLVPacket {
tlv(0x1b) {
writeInt(micro)
writeInt(version)
writeInt(size)
@ -142,11 +137,10 @@ internal fun BytePacketBuilder.t1b(
}
}
internal fun BytePacketBuilder.t1d(
internal fun TlvMapWriter.t1d(
miscBitmap: Int,
) {
writeShort(0x1d)
writeShortLVPacket {
tlv(0x1d) {
writeByte(1)
writeInt(miscBitmap)
writeInt(0)
@ -155,7 +149,7 @@ internal fun BytePacketBuilder.t1d(
}
}
internal fun BytePacketBuilder.t1f(
internal fun TlvMapWriter.t1f(
isRoot: Boolean = false,
osName: ByteArray,
osVersion: ByteArray,
@ -163,8 +157,7 @@ internal fun BytePacketBuilder.t1f(
apn: ByteArray,
networkType: Short = 2,
) {
writeShort(0x1f)
writeShortLVPacket {
tlv(0x1f) {
writeByte(if (isRoot) 1 else 0)
writeShortLVByteArray(osName)
writeShortLVByteArray(osVersion)
@ -175,23 +168,21 @@ internal fun BytePacketBuilder.t1f(
}
}
internal fun BytePacketBuilder.t33(
internal fun TlvMapWriter.t33(
guid: ByteArray,
) {
writeShort(0x33)
writeShortLVByteArray(guid)
tlv(0x33, guid)
}
internal fun BytePacketBuilder.t35(
internal fun TlvMapWriter.t35(
productType: Int
) {
writeShort(0x35)
writeShortLVPacket {
tlv(0x35) {
writeInt(productType)
}
}
internal fun BytePacketBuilder.t106(
internal fun TlvMapWriter.t106(
client: QQAndroidClient,
appId: Long = 16L,
passwordMd5: ByteArray,
@ -213,11 +204,10 @@ internal fun BytePacketBuilder.t106(
)
}
internal fun BytePacketBuilder.t106(
internal fun TlvMapWriter.t106(
encryptA1: ByteArray
) {
writeShort(0x106)
writeShortLVPacket {
tlv(0x106) {
writeFully(encryptA1)
}
}
@ -225,7 +215,7 @@ internal fun BytePacketBuilder.t106(
/**
* A1
*/
internal fun BytePacketBuilder.t106(
internal fun TlvMapWriter.t106(
appId: Long = 16L,
subAppId: Long,
appClientVersion: Int = 0,
@ -240,12 +230,11 @@ internal fun BytePacketBuilder.t106(
loginType: LoginType,
ssoVersion: Int,
) {
writeShort(0x106)
passwordMd5.requireSize(16)
tgtgtKey.requireSize(16)
guid?.requireSize(16)
writeShortLVPacket {
tlv(0x106) {
encryptAndWrite(
(passwordMd5 + ByteArray(4) + (salt.takeIf { it != 0L } ?: uin).toInt()
.toByteArray()).md5()
@ -287,13 +276,12 @@ internal fun BytePacketBuilder.t106(
}
}
internal fun BytePacketBuilder.t116(
internal fun TlvMapWriter.t116(
miscBitmap: Int,
subSigMap: Int,
appIdList: LongArray = longArrayOf(1600000226L)
) {
writeShort(0x116)
writeShortLVPacket {
tlv(0x116) {
writeByte(0) // _ver
writeInt(miscBitmap) // 184024956
writeInt(subSigMap) // 66560
@ -305,131 +293,122 @@ internal fun BytePacketBuilder.t116(
}
internal fun BytePacketBuilder.t100(
internal fun TlvMapWriter.t100(
appId: Long = 16,
subAppId: Long,
appClientVersion: Int,
ssoVersion: Int,
mainSigMap: Int
) {
writeShort(0x100)
writeShortLVPacket {
tlv(0x100) {
writeShort(1)//db_buf_ver
writeInt(ssoVersion)//sso_ver
writeInt(appId.toInt())
writeInt(subAppId.toInt())
writeInt(appClientVersion)
writeInt(mainSigMap) // sigMap, 34869472?
} shouldEqualsTo 22
}
}
internal fun BytePacketBuilder.t10a(
internal fun TlvMapWriter.t10a(
tgt: ByteArray,
) {
writeShort(0x10a)
writeShortLVPacket {
tlv(0x10a) {
writeFully(tgt)
}
}
internal fun BytePacketBuilder.t107(
internal fun TlvMapWriter.t107(
picType: Int,
capType: Int = 0,
picSize: Int = 0,
retType: Int = 1
) {
writeShort(0x107)
writeShortLVPacket {
tlv(0x107) {
writeShort(picType.toShort())
writeByte(capType.toByte())
writeShort(picSize.toShort())
writeByte(retType.toByte())
} shouldEqualsTo 6
}
}
internal fun BytePacketBuilder.t108(
internal fun TlvMapWriter.t108(
ksid: ByteArray
) {
// require(ksid.size == 16) { "ksid should length 16" }
writeShort(0x108)
writeShortLVPacket {
tlv(0x108) {
writeFully(ksid)
}
}
internal fun BytePacketBuilder.t104(
internal fun TlvMapWriter.t104(
t104Data: ByteArray
) {
writeShort(0x104)
writeShortLVPacket {
tlv(0x104) {
writeFully(t104Data)
}
}
internal fun BytePacketBuilder.t547(
internal fun TlvMapWriter.t547(
t547Data: ByteArray
) {
writeShort(0x547)
writeShortLVPacket {
tlv(0x547) {
writeFully(t547Data)
}
}
internal fun BytePacketBuilder.t174(
internal fun TlvMapWriter.t174(
t174Data: ByteArray
) {
writeShort(0x174)
writeShortLVPacket {
tlv(0x174) {
writeFully(t174Data)
}
}
internal fun BytePacketBuilder.t17a(
internal fun TlvMapWriter.t17a(
value: Int = 0
) {
writeShort(0x17a)
writeShortLVPacket {
tlv(0x17a) {
writeInt(value)
}
}
internal fun BytePacketBuilder.t197() {
writeShort(0x197)
writeFully(byteArrayOf(0, 1, 0))
internal fun TlvMapWriter.t197() {
tlv(0x197) {
writeByte(0)
}
}
internal fun BytePacketBuilder.t198() {
writeShort(0x198)
writeFully(byteArrayOf(0, 1, 0))
internal fun TlvMapWriter.t198() {
tlv(0x198) {
writeByte(0)
}
}
internal fun BytePacketBuilder.t19e(
internal fun TlvMapWriter.t19e(
value: Int = 0
) {
writeShort(0x19e)
writeShortLVPacket {
tlv(0x19e) {
writeShort(1)
writeByte(value.toByte())
}
}
internal fun BytePacketBuilder.t17c(
internal fun TlvMapWriter.t17c(
t17cData: ByteArray
) {
writeShort(0x17c)
writeShortLVPacket {
tlv(0x17c) {
writeShort(t17cData.size.toShort())
writeFully(t17cData)
}
}
internal fun BytePacketBuilder.t401(
internal fun TlvMapWriter.t401(
t401Data: ByteArray
) {
writeShort(0x401)
writeShortLVPacket {
tlv(0x401) {
writeFully(t401Data)
}
}
@ -437,35 +416,32 @@ internal fun BytePacketBuilder.t401(
/**
* @param apkId application.getPackageName().getBytes()
*/
internal fun BytePacketBuilder.t142(
internal fun TlvMapWriter.t142(
apkId: ByteArray
) {
writeShort(0x142)
writeShortLVPacket {
tlv(0x142) {
writeShort(0) //_version
writeShortLVByteArrayLimitedLength(apkId, 32)
}
}
internal fun BytePacketBuilder.t143(
internal fun TlvMapWriter.t143(
d2: ByteArray
) {
writeShort(0x143)
writeShortLVPacket {
tlv(0x143) {
writeFully(d2)
}
}
internal fun BytePacketBuilder.t112(
internal fun TlvMapWriter.t112(
nonNumberUin: ByteArray
) {
writeShort(0x112)
writeShortLVPacket {
tlv(0x112) {
writeFully(nonNumberUin)
}
}
internal fun BytePacketBuilder.t144(
internal fun TlvMapWriter.t144(
client: QQAndroidClient
) {
return t144(
@ -488,7 +464,7 @@ internal fun BytePacketBuilder.t144(
)
}
internal fun BytePacketBuilder.t144(
internal fun TlvMapWriter.t144(
// t109
androidId: ByteArray,
@ -515,34 +491,32 @@ internal fun BytePacketBuilder.t144(
// encrypt
tgtgtKey: ByteArray
) {
writeShort(0x144)
writeShortLVPacket {
tlv(0x144) {
encryptAndWrite(tgtgtKey) {
writeShort(5) // tlv count
t109(androidId)
t52d(androidDevInfo)
t124(osType, osVersion, networkType, simInfo, unknown, apn)
t128(isGuidFromFileNull, isGuidAvailable, isGuidChanged, guidFlag, buildModel, guid, buildBrand)
t16e(buildModel)
_writeTlvMap {
t109(androidId)
t52d(androidDevInfo)
t124(osType, osVersion, networkType, simInfo, unknown, apn)
t128(isGuidFromFileNull, isGuidAvailable, isGuidChanged, guidFlag, buildModel, guid, buildBrand)
t16e(buildModel)
}
}
}
}
internal fun BytePacketBuilder.t109(
internal fun TlvMapWriter.t109(
androidId: ByteArray
) {
writeShort(0x109)
writeShortLVPacket {
tlv(0x109) {
writeFully(androidId.md5())
} shouldEqualsTo 16
}
}
internal fun BytePacketBuilder.t52d(
internal fun TlvMapWriter.t52d(
androidDevInfo: ByteArray // oicq.wlogin_sdk.tools.util#get_android_dev_info
) {
writeShort(0x52d)
writeShortLVPacket {
tlv(0x52d) {
writeFully(androidDevInfo)
// 0A 07 75 6E 6B 6E 6F 77 6E 12 7E 4C 69 6E 75 78 20 76 65 72 73 69 6F 6E 20 34 2E 39 2E 33 31 20 28 62 75 69 6C 64 40 42 75 69 6C 64 32 29 20 28 67 63 63 20 76 65 72 73 69 6F 6E 20 34 2E 39 20 32 30 31 35 30 31 32 33 20 28 70 72 65 72 65 6C 65 61 73 65 29 20 28 47 43 43 29 20 29 20 23 31 20 53 4D 50 20 50 52 45 45 4D 50 54 20 54 68 75 20 44 65 63 20 31 32 20 31 35 3A 33 30 3A 35 35 20 49 53 54 20 32 30 31 39 1A 03 52 45 4C 22 03 33 32 37 2A 41 4F 6E 65 50 6C 75 73 2F 4F 6E 65 50 6C 75 73 35 2F 4F 6E 65 50 6C 75 73 35 3A 37 2E 31 2E 31 2F 4E 4D 46 32 36 58 2F 31 30 31 37 31 36 31 37 3A 75 73 65 72 2F 72 65 6C 65 61 73 65 2D 6B 65 79 73 32 24 36 63 39 39 37 36 33 66 2D 66 62 34 32 2D 34 38 38 31 2D 62 37 32 65 2D 63 37 61 61 38 61 36 63 31 63 61 34 3A 10 65 38 63 37 30 35 34 64 30 32 66 33 36 33 64 30 42 0A 6E 6F 20 6D 65 73 73 61 67 65 4A 03 33 32 37
@ -550,7 +524,7 @@ internal fun BytePacketBuilder.t52d(
}
}
internal fun BytePacketBuilder.t124(
internal fun TlvMapWriter.t124(
osType: ByteArray = "android".toByteArray(),
osVersion: ByteArray, // Build.VERSION.RELEASE.toByteArray()
networkType: NetworkType, //oicq.wlogin_sdk.tools.util#get_network_type
@ -558,8 +532,7 @@ internal fun BytePacketBuilder.t124(
address: ByteArray, // always new byte[0]
apn: ByteArray = "wifi".toByteArray() // oicq.wlogin_sdk.tools.util#get_apn_string
) {
writeShort(0x124)
writeShortLVPacket {
tlv(0x124) {
writeShortLVByteArrayLimitedLength(osType, 16)
writeShortLVByteArrayLimitedLength(osVersion, 16)
writeShort(networkType.value.toShort())
@ -569,7 +542,7 @@ internal fun BytePacketBuilder.t124(
}
}
internal fun BytePacketBuilder.t128(
internal fun TlvMapWriter.t128(
isGuidFromFileNull: Boolean = false, // 保存到文件的 GUID 是否为 null
isGuidAvailable: Boolean = true, // GUID 是否可用(计算/读取成功)
isGuidChanged: Boolean = false, // GUID 是否有变动
@ -610,8 +583,7 @@ internal fun BytePacketBuilder.t128(
guid: ByteArray,
buildBrand: ByteArray // android.os.Build.BRAND
) {
writeShort(0x128)
writeShortLVPacket {
tlv(0x128) {
writeShort(0)
writeByte(isGuidFromFileNull.toByte())
writeByte(isGuidAvailable.toByte())
@ -623,71 +595,64 @@ internal fun BytePacketBuilder.t128(
}
}
internal fun BytePacketBuilder.t16e(
internal fun TlvMapWriter.t16e(
buildModel: ByteArray
) {
writeShort(0x16e)
writeShortLVPacket {
tlv(0x16e) {
writeFully(buildModel)
}
}
internal fun BytePacketBuilder.t145(
internal fun TlvMapWriter.t145(
guid: ByteArray
) {
writeShort(0x145)
writeShortLVPacket {
tlv(0x145) {
writeFully(guid)
}
}
internal fun BytePacketBuilder.t147(
internal fun TlvMapWriter.t147(
appId: Long,
apkVersionName: ByteArray,
apkSignatureMd5: ByteArray
) {
writeShort(0x147)
writeShortLVPacket {
tlv(0x147) {
writeInt(appId.toInt())
writeShortLVByteArrayLimitedLength(apkVersionName, 32)
writeShortLVByteArrayLimitedLength(apkSignatureMd5, 32)
}
}
internal fun BytePacketBuilder.t166(
internal fun TlvMapWriter.t166(
imageType: Int
) {
writeShort(0x166)
writeShortLVPacket {
tlv(0x166) {
writeByte(imageType.toByte())
}
}
internal fun BytePacketBuilder.t16a(
internal fun TlvMapWriter.t16a(
noPicSig: ByteArray // unknown source
) {
writeShort(0x16a)
writeShortLVPacket {
tlv(0x16a) {
writeFully(noPicSig)
}
}
internal fun BytePacketBuilder.t154(
internal fun TlvMapWriter.t154(
ssoSequenceId: Int // starts from 0
) {
writeShort(0x154)
writeShortLVPacket {
tlv(0x154) {
writeInt(ssoSequenceId)
}
}
internal fun BytePacketBuilder.t141(
internal fun TlvMapWriter.t141(
simInfo: ByteArray,
networkType: NetworkType,
apn: ByteArray
) {
writeShort(0x141)
writeShortLVPacket {
tlv(0x141) {
writeShort(1) // version
writeShortLVByteArray(simInfo)
writeShort(networkType.value.toShort())
@ -695,7 +660,7 @@ internal fun BytePacketBuilder.t141(
}
}
internal fun BytePacketBuilder.t511(
internal fun TlvMapWriter.t511(
domains: List<String> = listOf(
"tenpay.com",
"openmobile.qq.com",
@ -713,8 +678,7 @@ internal fun BytePacketBuilder.t511(
"mma.qq.com",
)
) {
writeShort(0x511)
writeShortLVPacket {
tlv(0x511) {
val list = domains.filter { it.isNotEmpty() }
writeShort(list.size.toShort())
list.forEach { element ->
@ -737,24 +701,22 @@ internal fun BytePacketBuilder.t511(
}
}
internal fun BytePacketBuilder.t172(
internal fun TlvMapWriter.t172(
rollbackSig: ByteArray // 由服务器发来的 tlv_t172 获得
) {
writeShort(0x172)
writeShortLVPacket {
tlv(0x172) {
writeFully(rollbackSig)
}
}
internal fun BytePacketBuilder.t185() {
writeShort(0x185)
writeShortLVPacket {
internal fun TlvMapWriter.t185() {
tlv(0x185) {
writeByte(1)
writeByte(1)
}
}
internal fun BytePacketBuilder.t400(
internal fun TlvMapWriter.t400(
/**
* if (var1[2] != null && var1[2].length > 0) {
this._G = (byte[])var1[2].clone();
@ -768,8 +730,7 @@ internal fun BytePacketBuilder.t400(
subAppId: Long,
randomSeed: ByteArray
) {
writeShort(0x400)
writeShortLVPacket {
tlv(0x400) {
encryptAndWrite(g) {
writeByte(1) // version
writeLong(uin)
@ -784,62 +745,56 @@ internal fun BytePacketBuilder.t400(
}
internal fun BytePacketBuilder.t187(
internal fun TlvMapWriter.t187(
macAddress: ByteArray
) {
writeShort(0x187)
writeShortLVPacket {
tlv(0x187) {
writeFully(macAddress.md5()) // may be md5
}
}
internal fun BytePacketBuilder.t188(
internal fun TlvMapWriter.t188(
androidId: ByteArray
) {
writeShort(0x188)
writeShortLVPacket {
tlv(0x188) {
writeFully(androidId.md5())
} shouldEqualsTo 16
}
}
internal fun BytePacketBuilder.t193(
internal fun TlvMapWriter.t193(
ticket: String
) {
writeShort(0x193)
writeShortLVPacket {
tlv(0x193) {
writeFully(ticket.toByteArray())
}
}
internal fun BytePacketBuilder.t194(
internal fun TlvMapWriter.t194(
imsiMd5: ByteArray
) {
imsiMd5 requireSize 16
writeShort(0x194)
writeShortLVPacket {
tlv(0x194) {
writeFully(imsiMd5)
} shouldEqualsTo 16
}
}
internal fun BytePacketBuilder.t191(
internal fun TlvMapWriter.t191(
K: Int = 0x82
) {
writeShort(0x191)
writeShortLVPacket {
tlv(0x191) {
writeByte(K.toByte())
}
}
internal fun BytePacketBuilder.t201(
internal fun TlvMapWriter.t201(
L: ByteArray = byteArrayOf(), // unknown
channelId: ByteArray = byteArrayOf(),
clientType: ByteArray = "qq".toByteArray(),
N: ByteArray
) {
writeShort(0x201)
writeShortLVPacket {
tlv(0x201) {
writeShortLVByteArray(L)
writeShortLVByteArray(channelId)
writeShortLVByteArray(clientType)
@ -847,73 +802,66 @@ internal fun BytePacketBuilder.t201(
}
}
internal fun BytePacketBuilder.t202(
internal fun TlvMapWriter.t202(
wifiBSSID: ByteArray,
wifiSSID: ByteArray
) {
writeShort(0x202)
writeShortLVPacket {
tlv(0x202) {
writeShortLVByteArrayLimitedLength(wifiBSSID, 16)
writeShortLVByteArrayLimitedLength(wifiSSID, 32)
}
}
internal fun BytePacketBuilder.t177(
internal fun TlvMapWriter.t177(
buildTime: Long = 1571193922L, // wtLogin BuildTime
buildVersion: String = "6.0.0.2413" // wtLogin SDK Version
) {
writeShort(0x177)
writeShortLVPacket {
tlv(0x177) {
writeByte(1)
writeInt(buildTime.toInt())
writeShortLVString(buildVersion)
} // shouldEqualsTo 0x11
}
internal fun BytePacketBuilder.t516( // 1302
internal fun TlvMapWriter.t516( // 1302
sourceType: Int = 0 // always 0
) {
writeShort(0x516)
writeShortLVPacket {
tlv(0x516) {
writeInt(sourceType)
} shouldEqualsTo 4
}
}
internal fun BytePacketBuilder.t521( // 1313
internal fun TlvMapWriter.t521( // 1313
productType: Int = 0, // coz setProductType is never used
unknown: Short = 0 // const
) {
writeShort(0x521)
writeShortLVPacket {
tlv(0x521) {
writeInt(productType)
writeShort(unknown)
} shouldEqualsTo 6
}
}
internal fun BytePacketBuilder.t52c(
internal fun TlvMapWriter.t52c(
// ?
) {
writeShort(0x52c)
writeShortLVPacket {
tlv(0x52c) {
writeByte(1)
writeLong(-1)
}
}
internal fun BytePacketBuilder.t536( // 1334
internal fun TlvMapWriter.t536( // 1334
loginExtraData: ByteArray
) {
writeShort(0x536)
writeShortLVPacket {
tlv(0x536) {
writeFully(loginExtraData)
}
}
internal fun BytePacketBuilder.t536( // 1334
internal fun TlvMapWriter.t536( // 1334
loginExtraData: Collection<LoginExtraData>
) {
writeShort(0x536)
writeShortLVPacket {
tlv(0x536) {
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
writeByte(1) // const
writeByte(loginExtraData.size.toByte()) // data count
@ -923,45 +871,44 @@ internal fun BytePacketBuilder.t536( // 1334
}
}
internal fun BytePacketBuilder.t525(
internal fun TlvMapWriter.t525(
loginExtraData: Collection<LoginExtraData>,
) {
writeShort(0x525)
writeShortLVPacket {
writeShort(1)
t536(loginExtraData)
tlv(0x525) {
_writeTlvMap {
t536(loginExtraData)
}
}
}
internal fun BytePacketBuilder.t525(
internal fun TlvMapWriter.t525(
t536: ByteReadPacket = buildPacket {
t536(buildPacket {
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
writeByte(1) // const
writeByte(0) // data count
}.readBytes())
_writeTlvMap(includeCount = false) {
t536(buildPacket {
//com.tencent.loginsecsdk.ProtocolDet#packExtraData
writeByte(1) // const
writeByte(0) // data count
}.readBytes())
}
}
) {
writeShort(0x525)
writeShortLVPacket {
tlv(0x525) {
writeShort(1)
writePacket(t536)
}
}
internal fun BytePacketBuilder.t544( // 1334
internal fun TlvMapWriter.t544( // 1334
) {
writeShort(0x544)
writeShortLVPacket {
tlv(0x544) {
writeFully(byteArrayOf(0, 0, 0, 11)) // means native throws exception
}
}
internal fun BytePacketBuilder.t318(
internal fun TlvMapWriter.t318(
tgtQR: ByteArray // unknown
) {
writeShort(0x318)
writeShortLVPacket {
tlv(0x318) {
writeFully(tgtQR)
}
}

View File

@ -125,20 +125,21 @@ internal class WtLogin {
) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(17) // subCommand
writeShort(12)
t100(16, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t108(client.ksid)
t109(client.device.androidId)
t8(2052)
t142(client.apkId)
t145(client.device.guid)
t154(0)
// 需要 t112, 但在实现 QR 时删除了 phoneNumber
// t112(client.account.phoneNumber.encodeToByteArray())
t116(client.miscBitMap, client.subSigMap)
t521()
t52c()
t52d(client.device.generateDeviceInfoData())
_writeTlvMap {
t100(16, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t108(client.ksid)
t109(client.device.androidId)
t8(2052)
t142(client.apkId)
t145(client.device.guid)
t154(0)
// 需要 t112, 但在实现 QR 时删除了 phoneNumber
//t112(client.account.phoneNumber.encodeToByteArray())
t116(client.miscBitMap, client.subSigMap)
t521()
t52c()
t52d(client.device.generateDeviceInfoData())
}
}
}
}
@ -677,53 +678,54 @@ internal class WtLogin {
writeByte(8)
writeShortLVPacket { }
writeShort(6)
t16(
client.ssoVersion,
client.subAppId,
client.device.guid,
client.apkId,
client.apkVersionName,
client.apkSignatureMd5
)
t1b(
size = size,
margin = margin,
ecLevel = ecLevel
)
t1d(client.miscBitMap)
val protocol = client.bot.configuration.protocol
when (protocol) {
BotConfiguration.MiraiProtocol.MACOS -> t1f(
false,
"Mac OSX".toByteArray(),
"10".toByteArray(),
"mac carrier".toByteArray(),
client.device.apn,
2
_writeTlvMap {
t16(
client.ssoVersion,
client.subAppId,
client.device.guid,
client.apkId,
client.apkVersionName,
client.apkSignatureMd5
)
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> t1f(
false,
client.device.osType,
"7.1.2".toByteArray(),
"China Mobile GSM".toByteArray(),
client.device.apn,
2
t1b(
size = size,
margin = margin,
ecLevel = ecLevel
)
t1d(client.miscBitMap)
else -> error("protocol $protocol doesn't support qrcode login.")
}
t33(client.device.guid)
t35(
val protocol = client.bot.configuration.protocol
when (protocol) {
BotConfiguration.MiraiProtocol.MACOS -> 5
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> 8
else -> error("assertion")
BotConfiguration.MiraiProtocol.MACOS -> t1f(
false,
"Mac OSX".toByteArray(),
"10".toByteArray(),
"mac carrier".toByteArray(),
client.device.apn,
2
)
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> t1f(
false,
client.device.osType,
"7.1.2".toByteArray(),
"China Mobile GSM".toByteArray(),
client.device.apn,
2
)
else -> error("protocol $protocol doesn't support qrcode login.")
}
)
t33(client.device.guid)
t35(
when (protocol) {
BotConfiguration.MiraiProtocol.MACOS -> 5
BotConfiguration.MiraiProtocol.ANDROID_WATCH -> 8
else -> error("assertion")
}
)
}
}
writeByte(0)
writeShort(code2dPacket.remaining.toShort())

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.utils.GuidSource
import net.mamoe.mirai.internal.utils.MacOrAndroidIdChangeFlag
import net.mamoe.mirai.internal.utils.guidFlag
import net.mamoe.mirai.utils._writeTlvMap
import net.mamoe.mirai.utils.generateDeviceInfoData
import net.mamoe.mirai.utils.md5
import net.mamoe.mirai.utils.toReadPacket
@ -44,45 +45,47 @@ internal object WtLogin10 : WtLoginExt {
0x0810
) {
writeShort(11) // subCommand
writeShort(18)
t100(appId, subAppId, client.appClientVersion, client.ssoVersion, mainSigMap)
t10a(client.wLoginSigInfo.tgt)
t116(client.miscBitMap, client.subSigMap)
t108(client.ksid)
t144(
androidId = client.device.androidId,
androidDevInfo = client.device.generateDeviceInfoData(),
osType = client.device.osType,
osVersion = client.device.version.release,
networkType = client.networkType,
simInfo = client.device.simInfo,
unknown = byteArrayOf(),
apn = client.device.apn,
isGuidFromFileNull = false,
isGuidAvailable = true,
isGuidChanged = false,
guidFlag = guidFlag(GuidSource.FROM_STORAGE, MacOrAndroidIdChangeFlag(0)),
buildModel = client.device.model,
guid = client.device.guid,
buildBrand = client.device.brand,
tgtgtKey = client.wLoginSigInfo.d2Key.md5()
)
//t112(client.account.phoneNumber.encodeToByteArray())
t143(client.wLoginSigInfo.d2.data)
t142(client.apkId)
t154(sequenceId)
t18(appId, uin = client.uin)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
//t511()
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t177(client.buildTime, client.sdkVersion)
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t511()
t202(client.device.wifiBSSID, client.device.wifiSSID)
//t544()
_writeTlvMap(Short.SIZE_BYTES) {
t100(appId, subAppId, client.appClientVersion, client.ssoVersion, mainSigMap)
t10a(client.wLoginSigInfo.tgt)
t116(client.miscBitMap, client.subSigMap)
t108(client.ksid)
t144(
androidId = client.device.androidId,
androidDevInfo = client.device.generateDeviceInfoData(),
osType = client.device.osType,
osVersion = client.device.version.release,
networkType = client.networkType,
simInfo = client.device.simInfo,
unknown = byteArrayOf(),
apn = client.device.apn,
isGuidFromFileNull = false,
isGuidAvailable = true,
isGuidChanged = false,
guidFlag = guidFlag(GuidSource.FROM_STORAGE, MacOrAndroidIdChangeFlag(0)),
buildModel = client.device.model,
guid = client.device.guid,
buildBrand = client.device.brand,
tgtgtKey = client.wLoginSigInfo.d2Key.md5()
)
//t112(client.account.phoneNumber.encodeToByteArray())
t143(client.wLoginSigInfo.d2.data)
t142(client.apkId)
t154(sequenceId)
t18(appId, uin = client.uin)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
//t511()
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t177(client.buildTime, client.sdkVersion)
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t511()
t202(client.device.wifiBSSID, client.device.wifiSSID)
//t544()
}
}
}

View File

@ -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.utils._writeTlvMap
import kotlin.math.abs
import kotlin.random.Random
@ -36,7 +37,8 @@ internal object WtLogin15 : WtLoginExt {
commandId = 0x0810
) {
writeShort(subCommand) // subCommand
writeShort(24)
_writeTlvMap {
// writeFully(("00 18 00 16 00 01 00 00 06 00 00 00 00 10 00 00 00 00 76 E4 B8 DD 00 00 00 00 00 01 00 14 00 01 5A 11 60 11 76 E4 B8 DD 60 0D 44 35 90 E8 11 1B 00 00 " +
@ -51,11 +53,11 @@ internal object WtLogin15 : WtLoginExt {
// "").hexToBytes())
// return@writeOicqRequestPacket
t18(appId, uin = client.uin)
t1(client.uin, ByteArray(4))
t18(appId, uin = client.uin)
t1(client.uin, ByteArray(4))
// t106(client = client)
t106(client.wLoginSigInfo.encryptA1!!)
// t106(client = client)
t106(client.wLoginSigInfo.encryptA1!!)
// kotlin.run {
// val key = (client.account.passwordMd5 + ByteArray(4) + client.uin.toInt().toByteArray()).md5()
// kotlin.runCatching {
@ -63,67 +65,68 @@ internal object WtLogin15 : WtLoginExt {
// }.soutv("DEC") // success
// }
// val a1 = kotlin.runCatching {
// TEA.decrypt(encryptA1, buildPacket {
// writeFully(client.device.guid)
// writeFully(client.dpwd)
// writeFully(client.randSeed)
// }.readBytes().md5())
// }.recoverCatching {
// client.tryDecryptOrNull(encryptA1) { it }!!
// }.getOrElse {
// encryptA1.soutv("ENCRYPT A1")
// client.soutv("CLIENT")
// // exitProcess(1)
// // error("Failed to decrypt A1")
// encryptA1
// }
// val a1 = kotlin.runCatching {
// TEA.decrypt(encryptA1, buildPacket {
// writeFully(client.device.guid)
// writeFully(client.dpwd)
// writeFully(client.randSeed)
// }.readBytes().md5())
// }.recoverCatching {
// client.tryDecryptOrNull(encryptA1) { it }!!
// }.getOrElse {
// encryptA1.soutv("ENCRYPT A1")
// client.soutv("CLIENT")
// // exitProcess(1)
// // error("Failed to decrypt A1")
// encryptA1
// }
t116(client.miscBitMap, client.subSigMap)
//t116(0x08F7FF7C, 0x00010400)
t116(client.miscBitMap, client.subSigMap)
//t116(0x08F7FF7C, 0x00010400)
//t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
//t100(appId, 1, client.appClientVersion, client.ssoVersion, mainSigMap = 1048768)
t100(appId, 2, client.appClientVersion, client.ssoVersion, client.mainSigMap)
//t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
//t100(appId, 1, client.appClientVersion, client.ssoVersion, mainSigMap = 1048768)
t100(appId, 2, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t107(0)
t107(0)
//t108(client.ksid) // 第一次 exchange 没有 108
t144(client)
t142(client.apkId)
t145(client.device.guid)
//t108(client.ksid) // 第一次 exchange 没有 108
t144(client)
t142(client.apkId)
t145(client.device.guid)
val noPicSig =
client.wLoginSigInfo.noPicSig ?: error("Internal error: doing exchange emp 15 while noPicSig=null")
t16a(noPicSig)
val noPicSig =
client.wLoginSigInfo.noPicSig ?: error("Internal error: doing exchange emp 15 while noPicSig=null")
t16a(noPicSig)
t154(0)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t511()
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t177(buildTime = client.buildTime, buildVersion = client.sdkVersion)
t154(0)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t511()
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t177(buildTime = client.buildTime, buildVersion = client.sdkVersion)
// new
t400(
g = client.G,
uin = client.uin,
guid = client.device.guid,
dpwd = client.dpwd,
appId = 1,
subAppId = 16,
randomSeed = client.randSeed
)
// new
t400(
g = client.G,
uin = client.uin,
guid = client.device.guid,
dpwd = client.dpwd,
appId = 1,
subAppId = 16,
randomSeed = client.randSeed
)
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t202(client.device.wifiBSSID, client.device.wifiSSID)
t516()
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t202(client.device.wifiBSSID, client.device.wifiSSID)
t516()
t521() // new
t525(client.loginExtraData) // new
//t544() // new
t521() // new
t525(client.loginExtraData) // new
//t544() // new
}
}
// }

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.*
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.subAppId
import net.mamoe.mirai.internal.network.subSigMap
import net.mamoe.mirai.utils._writeTlvMap
internal object WtLogin2 : WtLoginExt {
@ -26,19 +27,13 @@ internal object WtLogin2 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand
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)
_writeTlvMap {
t193(ticket)
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
client.t547?.let { t547(it) }
}
}
}
@ -52,19 +47,13 @@ internal object WtLogin2 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(2) // subCommand
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)
_writeTlvMap {
t2(captchaAnswer, captchaSign, 0)
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
client.t547?.let { t547(it) }
}
}
}

View File

@ -16,6 +16,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.*
import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.subAppId
import net.mamoe.mirai.internal.network.subSigMap
import net.mamoe.mirai.utils._writeTlvMap
internal object WtLogin20 : WtLoginExt {
operator fun invoke(
@ -24,11 +25,12 @@ internal object WtLogin20 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(20) // subCommand
writeShort(4) // count of TLVs, probably ignored by server?
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t401(client.G) // (client.device.guid + "stMNokHgxZUGhsYp".toByteArray() + t402).md5()
_writeTlvMap {
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t401(client.G) // (client.device.guid + "stMNokHgxZUGhsYp".toByteArray() + t402).md5()
}
}
}
}

View File

@ -17,6 +17,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.subAppId
import net.mamoe.mirai.internal.network.subSigMap
import net.mamoe.mirai.utils.DeviceVerificationRequests
import net.mamoe.mirai.utils._writeTlvMap
/**
* Submit SMS.
@ -33,15 +34,17 @@ internal object WtLogin7 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(7) // subCommand
writeShort(7) // count of TLVs
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t174(client.t174 ?: t174)
t17c(code.encodeToByteArray())
t401(client.G)
t198()
_writeTlvMap {
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t174(client.t174 ?: t174)
t17c(code.encodeToByteArray())
t401(client.G)
t198()
}
}
}
}

View File

@ -17,6 +17,7 @@ import net.mamoe.mirai.internal.network.protocol.packet.login.WtLogin
import net.mamoe.mirai.internal.network.subAppId
import net.mamoe.mirai.internal.network.subSigMap
import net.mamoe.mirai.utils.DeviceVerificationRequests
import net.mamoe.mirai.utils._writeTlvMap
/**
* Request SMS.
@ -33,14 +34,17 @@ internal object WtLogin8 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(subCommand) // subCommand
writeShort(6) // count of TLVs
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t174(t174)
t17a(9)
t197()
_writeTlvMap {
t8(2052)
t104(client.t104)
t116(client.miscBitMap, client.subSigMap)
t174(t174)
t17a(9)
t197()
}
}
}
}

View File

@ -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.utils._writeTlvMap
internal object WtLogin9 : WtLoginExt {
private const val appId = 16L
@ -35,19 +36,21 @@ internal object WtLogin9 : WtLoginExt {
if (useEncryptA1AndNoPicSig) {
tlvCount++;
}
writeShort(tlvCount.toShort()) // count of TLVs, probably ignored by server?
// writeShort(tlvCount.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)
_writeTlvMap {
if (useEncryptA1AndNoPicSig) {
t106(client.wLoginSigInfo.encryptA1!!)
} else {
t106(client, appId, passwordMd5)
}
t18(appId, client.appClientVersion, client.uin)
t1(client.uin, client.device.ipAddress)
/* // from GetStWithPasswd
if (useEncryptA1AndNoPicSig) {
t106(client.wLoginSigInfo.encryptA1!!)
} else {
t106(client, appId, passwordMd5)
}
/* // from GetStWithPasswd
int mMiscBitmap = this.mMiscBitmap;
if (t.uinDeviceToken) {
mMiscBitmap = (this.mMiscBitmap | 0x2000000);
@ -57,65 +60,66 @@ internal object WtLogin9 : WtLoginExt {
// defaults true
if (ConfigManager.get_loginWithPicSt()) appIdList = longArrayOf(1600000226L)
*/
t116(client.miscBitMap, client.subSigMap)
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t107(0)
t108(client.device.imei.toByteArray())
t116(client.miscBitMap, client.subSigMap)
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t107(0)
t108(client.device.imei.toByteArray())
// t108(byteArrayOf())
// ignored: t104()
t142(client.apkId)
// t108(byteArrayOf())
// ignored: t104()
t142(client.apkId)
// if login with non-number uin
// t112()
t144(client)
// if login with non-number uin
// t112()
t144(client)
//this.build().debugPrint("傻逼")
t145(client.device.guid)
t147(appId, client.apkVersionName, client.apkSignatureMd5)
//this.build().debugPrint("傻逼")
t145(client.device.guid)
t147(appId, client.apkVersionName, client.apkSignatureMd5)
/*
/*
if (client.miscBitMap and 0x80 != 0) {
t166(1)
}
*/
if (useEncryptA1AndNoPicSig) {
t16a(client.wLoginSigInfo.noPicSig!!)
}
if (useEncryptA1AndNoPicSig) {
t16a(client.wLoginSigInfo.noPicSig!!)
}
t154(sequenceId)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t154(sequenceId)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t511()
t511()
// ignored t172 because rollbackSig is null
// ignored t185 because loginType is not SMS
// ignored t400 because of first login
// ignored t172 because rollbackSig is null
// ignored t185 because loginType is not SMS
// ignored t400 because of first login
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
if (allowSlider) {
t191()
}
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
if (allowSlider) {
t191()
}
/*
/*
t201(N = byteArrayOf())*/
t202(client.device.wifiBSSID, client.device.wifiSSID)
t202(client.device.wifiBSSID, client.device.wifiSSID)
t177(
buildTime = client.buildTime,
buildVersion = client.sdkVersion,
)
t516()
t521()
t177(
buildTime = client.buildTime,
buildVersion = client.sdkVersion,
)
t516()
t521()
t525()
// this.build().debugPrint("傻逼")
t525()
// this.build().debugPrint("傻逼")
// ignored t318 because not logging in by QR
// ignored t318 because not logging in by QR
}
}
}
}
@ -130,44 +134,46 @@ internal object WtLogin9 : WtLoginExt {
writeSsoPacket(client, client.subAppId, WtLogin.Login.commandName, sequenceId = sequenceId) {
writeOicqRequestPacket(client, commandId = 0x0810) {
writeShort(9) // subCommand
writeShort(0x19) // count of TLVs, probably ignored by server?
// writeShort(0x19) // count of TLVs, probably ignored by server?
t18(appId, client.appClientVersion, client.uin)
t1(client.uin, client.device.ipAddress)
_writeTlvMap {
t18(appId, client.appClientVersion, client.uin)
t1(client.uin, client.device.ipAddress)
t106(data.tmpPwd)
t106(data.tmpPwd)
t116(client.miscBitMap, client.subSigMap)
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t107(0)
t108(client.device.imei.toByteArray())
t116(client.miscBitMap, client.subSigMap)
t100(appId, client.subAppId, client.appClientVersion, client.ssoVersion, client.mainSigMap)
t107(0)
t108(client.device.imei.toByteArray())
t142(client.apkId)
t142(client.apkId)
t144(client)
t144(client)
t145(client.device.guid)
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t145(client.device.guid)
t147(appId, client.apkVersionName, client.apkSignatureMd5)
t16a(data.noPicSig)
t16a(data.noPicSig)
t154(sequenceId)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t154(sequenceId)
t141(client.device.simInfo, client.networkType, client.device.apn)
t8(2052)
t511()
t511()
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t191(0x00)
t187(client.device.macAddress)
t188(client.device.androidId)
t194(client.device.imsiMd5)
t191(0x00)
t202(client.device.wifiBSSID, client.device.wifiSSID)
t202(client.device.wifiBSSID, client.device.wifiSSID)
t177(client.buildTime, client.sdkVersion)
t516()
t521(8)
t318(data.tgtQR)
t177(client.buildTime, client.sdkVersion)
t516()
t521(8)
t318(data.tgtQR)
}
}
}
}

View File

@ -86,19 +86,18 @@ internal interface WtLoginExt { // so as not to register to global extension
return buildPacket {
writeByte(64)
writeShort(4)
// TLV
writeShort(0x106)
writeShortLVByteArray(t106)
_writeTlvMap {
writeShort(0x10c)
writeShortLVByteArray(t10c)
// TLV
tlv(0x106, t106)
writeShort(0x16a)
writeShortLVByteArray(t16a)
tlv(0x10c, t10c)
t145(device.guid)
tlv(0x16a, t16a)
t145(device.guid)
}
}
}