Commit 59fbbd5c authored by liujiahua123123's avatar liujiahua123123

Merge remote-tracking branch 'origin/master'

parents 5cb0ebfe 8ccf931a
...@@ -508,7 +508,7 @@ license to downstream recipients. "Knowingly relying" means you have ...@@ -508,7 +508,7 @@ license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid. country that you have state to believe are valid.
If, pursuant to or in connection with a single transaction or If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a arrangement, you convey, or propagate by procuring conveyance of, a
......
...@@ -15,7 +15,11 @@ import net.mamoe.mirai.network.packet.client.login.ClientPasswordSubmissionPacke ...@@ -15,7 +15,11 @@ import net.mamoe.mirai.network.packet.client.login.ClientPasswordSubmissionPacke
import net.mamoe.mirai.network.packet.client.login.ClientServerRedirectionPacket import net.mamoe.mirai.network.packet.client.login.ClientServerRedirectionPacket
import net.mamoe.mirai.network.packet.client.writeHex import net.mamoe.mirai.network.packet.client.writeHex
import net.mamoe.mirai.network.packet.server.ServerPacket import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.ServerTouchResponsePacket import net.mamoe.mirai.network.packet.server.login.ServerLoginFailedResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginResendResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginSucceedResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginVerificationCodeResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import java.net.DatagramPacket import java.net.DatagramPacket
import java.net.InetSocketAddress import java.net.InetSocketAddress
...@@ -26,37 +30,60 @@ import java.net.InetSocketAddress ...@@ -26,37 +30,60 @@ import java.net.InetSocketAddress
* @author Him188moe @ Mirai Project * @author Him188moe @ Mirai Project
*/ */
class Robot(val number: Int, private val password: String) { class Robot(val number: Int, private val password: String) {
private lateinit var channel: Channel private var channel: Channel? = null
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
internal fun onPacketReceived(packet: ServerPacket) { internal fun onPacketReceived(packet: ServerPacket) {
packet.decode() packet.decode()
if (packet is ServerTouchResponsePacket) { when (packet) {
if (packet.serverIP != null) {//redirection is ServerTouchResponsePacket -> {
connect(packet.serverIP!!) if (packet.serverIP != null) {//redirection
sendPacket(ClientServerRedirectionPacket( connect(packet.serverIP!!)
serverIP = packet.serverIP!!, sendPacket(ClientServerRedirectionPacket(
qq = number serverIP = packet.serverIP!!,
)) qq = number
} else {//password submission ))
sendPacket(ClientPasswordSubmissionPacket( } else {//password submission
qq = this.number, sendPacket(ClientPasswordSubmissionPacket(
password = this.password, qq = this.number,
loginTime = packet.loginTime, password = this.password,
loginIP = packet.loginIP, loginTime = packet.loginTime,
token0825 = packet.token, loginIP = packet.loginIP,
tgtgtKey = packet.tgtgtKey token0825 = packet.token,
)) tgtgtKey = packet.tgtgtKey
))
}
} }
is ServerLoginFailedResponsePacket -> {
channel = null
println("Login failed: " + packet.state.toString())
return
}
is ServerLoginVerificationCodeResponsePacket -> {
}
is ServerLoginSucceedResponsePacket -> {
}
is ServerLoginResendResponsePacket -> {
}
else -> throw IllegalStateException()
} }
} }
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
private fun sendPacket(packet: ClientPacket) { private fun sendPacket(packet: ClientPacket) {
packet.encode() packet.encode()
packet.writeHex(Protocol.tail); packet.writeHex(Protocol.tail);
channel.writeAndFlush(DatagramPacket(packet.toByteArray())) channel!!.writeAndFlush(DatagramPacket(packet.toByteArray()))
} }
companion object { companion object {
...@@ -106,7 +133,7 @@ class Robot(val number: Int, private val password: String) { ...@@ -106,7 +133,7 @@ class Robot(val number: Int, private val password: String) {
}) })
channel = b.connect().sync().channel(); channel = b.connect().sync().channel();
channel.closeFuture().sync() channel!!.closeFuture().sync()
} finally { } finally {
group.shutdownGracefully().sync() group.shutdownGracefully().sync()
} }
......
package net.mamoe.mirai.network.packet.client.login
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.client.ClientPacket
/**
* Dispose_0836
*
* @author Him188moe @ Mirai Project
*/
@PacketId("08 36 31 04")
@ExperimentalUnsignedTypes
class ClientLoginResendPacket3104(val tgtgtKey: ByteArray, val token00BA: ByteArray) : ClientPacket() {
override fun encode() {
}
}
\ No newline at end of file
...@@ -17,7 +17,7 @@ import java.net.InetAddress ...@@ -17,7 +17,7 @@ import java.net.InetAddress
*/ */
@PacketId("08 36 31 03") @PacketId("08 36 31 03")
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
class ClientPasswordSubmissionPacket(private val qq: Int, private val password: String, private val loginTime: ByteArray, private val loginIP: ByteArray, private val tgtgtKey: ByteArray, private val token0825: ByteArray) : ClientPacket() { class ClientPasswordSubmissionPacket(private val qq: Int, private val password: String, private val loginTime: Int, private val loginIP: String, private val tgtgtKey: ByteArray, private val token0825: ByteArray) : ClientPacket() {
@ExperimentalUnsignedTypes @ExperimentalUnsignedTypes
override fun encode() { override fun encode() {
this.writeQQ(qq) this.writeQQ(qq)
...@@ -39,7 +39,11 @@ class ClientPasswordSubmissionPacket(private val qq: Int, private val password: ...@@ -39,7 +39,11 @@ class ClientPasswordSubmissionPacket(private val qq: Int, private val password:
this.writeHex("03 0F");//tag this.writeHex("03 0F");//tag
this.writeShort(hostName.length / 2);//todo check that this.writeShort(hostName.length / 2);//todo check that
this.writeShort(hostName.length); this.writeShort(hostName.length);
this.writeBytes(hostName) this.writeBytes(hostName)//todo 这个对吗?
/*易语言源码: PCName就是HostName
PCName = BytesToStr (Ansi转Utf8 (取主机名 ()))
PCName = 取文本左边 (PCName, 取文本长度 (PCName) - 3)*/
this.writeHex("00 05 00 06 00 02") this.writeHex("00 05 00 06 00 02")
this.writeQQ(qq) this.writeQQ(qq)
this.writeHex("00 06")//tag this.writeHex("00 06")//tag
......
package net.mamoe.mirai.network.packet.client.login package net.mamoe.mirai.network.packet.client.touch
import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.network.packet.PacketId
......
package net.mamoe.mirai.network.packet.client.login package net.mamoe.mirai.network.packet.client.touch
import net.mamoe.mirai.network.Protocol import net.mamoe.mirai.network.Protocol
import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.network.packet.PacketId
......
package net.mamoe.mirai.network.packet.server package net.mamoe.mirai.network.packet.server
import net.mamoe.mirai.network.packet.Packet import net.mamoe.mirai.network.packet.Packet
import net.mamoe.mirai.network.packet.client.toHexString import net.mamoe.mirai.network.packet.server.login.ServerLoginFailedResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginResendResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginSucceedResponsePacket
import net.mamoe.mirai.network.packet.server.login.ServerLoginVerificationCodeResponsePacket
import net.mamoe.mirai.network.packet.server.touch.ServerTouchResponsePacket
import net.mamoe.mirai.util.toHexString import net.mamoe.mirai.util.toHexString
import java.io.DataInputStream import java.io.DataInputStream
/** /**
...@@ -25,13 +28,36 @@ abstract class ServerPacket(val input: DataInputStream) : Packet { ...@@ -25,13 +28,36 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
return when (idBytes.joinToString("") { it.toString(16) }) { return when (idBytes.joinToString("") { it.toString(16) }) {
"08 25 31 01" -> ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, stream) "08 25 31 01" -> ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_01, stream)
"08 25 31 02" -> ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_02, stream) "08 25 31 02" -> ServerTouchResponsePacket(ServerTouchResponsePacket.Type.TYPE_08_25_31_02, stream)
"08 36 31 03", "08 36 31 04", "08 36 31 05", "08 36 31 06" -> {
when (bytes.size) {
271, 207 -> {
ServerLoginResendResponsePacket(stream)
}
871 -> return ServerLoginVerificationCodeResponsePacket(stream)
}
if (bytes.size > 700) {
return ServerLoginSucceedResponsePacket(stream)
}
else -> throw UnsupportedOperationException() return ServerLoginFailedResponsePacket(when (bytes.size) {
319 -> ServerLoginFailedResponsePacket.State.WRONG_PASSWORD
135 -> ServerLoginFailedResponsePacket.State.RETYPE_PASSWORD
279 -> ServerLoginFailedResponsePacket.State.BLOCKED
263 -> ServerLoginFailedResponsePacket.State.UNKNOWN_QQ_NUMBER
551, 487 -> ServerLoginFailedResponsePacket.State.DEVICE_LOCK
359 -> ServerLoginFailedResponsePacket.State.TAKEN_BACK
else -> throw IllegalStateException()
}, stream)
}
else -> throw IllegalStateException()
} }
} }
} }
} }
fun DataInputStream.skipUntil(byte: Byte) { fun DataInputStream.skipUntil(byte: Byte) {
while (readByte() != byte); while (readByte() != byte);
} }
...@@ -53,8 +79,8 @@ fun DataInputStream.readIP(): String { ...@@ -53,8 +79,8 @@ fun DataInputStream.readIP(): String {
for (i in 0..3) { for (i in 0..3) {
val byte = readByte(); val byte = readByte();
buff += (byte.toUByte().toString()) buff += (byte.toUByte().toString())
if(i !=3)buff+="." if (i != 3) buff += "."
System.out.println(byte.toHexString()) println(byte.toHexString())
} }
return buff return buff
} }
package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.io.DataInputStream
/**
* @author Him188moe @ Mirai Project
*/
class ServerLoginFailedResponsePacket(val state: State, input: DataInputStream) : ServerPacket(input) {
enum class State {
WRONG_PASSWORD,
// UNKNOWN,//? 要再次发送某数据包
RETYPE_PASSWORD,//similar to [WRONG_PASSWORD]
BLOCKED,//你的帐号存在被盗风险,已进入保护模式
UNKNOWN_QQ_NUMBER,//你输入的帐号不存在
DEVICE_LOCK,//设备锁
TAKEN_BACK,//被回收
// VERIFICATION_CODE,//需要验证码
// SUCCEED,
}
override fun decode() {
}
}
\ No newline at end of file
package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.io.DataInputStream
/**
* @author Him188moe @ Mirai Project
*/
@PacketId("08 36 31 03")
class ServerLoginResendResponsePacket(input: DataInputStream, private val flag: Flag) : ServerPacket(input) {
enum class Flag {
`08 36 31 03`,
OTHER,
}
lateinit var _0836_tlv0006_encr: ByteArray;
lateinit var token: ByteArray
lateinit var tgtgtKey: ByteArray
override fun decode() {
_0836_tlv0006_encr = 取文本中间(data, 76, 359)
when (flag) {
Flag.`08 36 31 03` -> {
token = 取文本中间(data, 460, 167)
}
Flag.OTHER -> {
//do nothing in this packet.
//[this.token] will be set in [Robot]
}
}
m_tgtgtKey = 取文本中间(data, 16, 47)
}
}
\ No newline at end of file
# ServerLoginResendResponsePacket
## Dispose_0836
data = TeaDecrypt (取文本中间 (data, 43, 取文本长度 (data) - 45), #shareKey)
data = TeaDecrypt (data, m_tgtgtKey)
.如果真 (data ≠ “”)
_0836_tlv0006_encr = 取文本中间 (data, 76, 359)
token = 选择 (flag = “08 36 31 03”, 取文本中间 (data, 460, 167), m_00BaToken) ' token
m_tgtgtKey = 取文本中间 (data, 16, 47) ' tgtgtKey
SetTips (“正在获取帐号信息...”, 9)
.如果 (flag = “08 36 31 03”)
SendUdp (Construct_0836_686 (“31 04”, 假, token, _0836_tlv0006_encr)) ' 正常发送
.否则
SendUdp (Construct_0836_686 (“31 06”, 假, token, _0836_tlv0006_encr)) ' 第二次发送
.如果结束
.如果真结束
## Construct_0836_686(
.参数 seq, 文本型
.参数 isVerify, 逻辑型, , 是否需要验证码登录
.参数 token, 文本型
.参数 tlv_0006_encr, 文本型, 可空)
fix1 = “03 00 00 00 01 01 01 00 00 68 20 00 00 00 00 00 01 01 03 00 19 ”
fix2 = “00 15 00 30 00 01 01 27 9B C7 F5 00 10 65 03 FD 8B 00 00 00 00 00 00 00 00 00 00 00 00 02 90 49 55 33 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B ”
qd = “00 32 00 63 3E 00 63 02 04 03 06 02 00 04 00 52 D9 00 00 00 00 A9 58 3E 6D 6D 49 AA F6 A6 D9 33 0A E7 7E 36 84 03 01 00 00 68 20 15 8B 00 00 01 02 00 00 03 00 07 DF 00 0A 00 0C 00 01 00 04 00 03 00 04 20 5C 00 ” + MD5_32 + “68 ” ' 修改
_0836key1 = “EF 4A 36 6A 16 A8 E6 3D 2E EA BD 1F 98 C1 3C DA ”
PCName = BytesToStr (Ansi转Utf8 (取主机名 ()))
PCName = 取文本左边 (PCName, 取文本长度 (PCName) - 3)
MD51 = 删尾空 (StrSplit (取数据摘要 (到字节集 (g_pass))))
MD52 = 删尾空 (StrSplit (取数据摘要 (HexToBytes (MD51 + “ 00 00 00 00 ” + g_QQ))))
crc32_code = GetRandomKey (16)
crc32_data = 取Crc32 (crc32_code)
.如果真 (isVerify)
tlv_0006_encr = Get_tlv_0006 ()
.如果真结束
pack.Empty ()
pack.PutTag (“01 12”)
pack.PutLength (“00 38”)
pack.PutValue (m_0825token)
pack.PutTag (“03 0F”)
pack.putDwordLength (GetDataLength (PCName) + 2)
pack.putDwordLength (GetDataLength (PCName))
pack.PutValue (PCName)
pack.PutFix (“00 05 00 06 00 02”)
pack.PutQQ ()
pack.PutTag (“00 06”)
pack.PutLength (“00 78”)
pack.PutValue (tlv_0006_encr)
pack.PutKey (fix2)
pack.PutTag (“00 1A”)
pack.PutLength (“00 40”)
pack.PutValue (TeaEncrypt (fix2, m_tgtgtKey))
pack.PutValue (#_0825data0)
pack.PutValue (#_0825date2)
pack.PutQQ ()
pack.PutZero (4)
pack.PutTag (“01 03”)
pack.PutLength (“00 14”)
pack.PutTag (“00 01”)
pack.PutLength (“00 10”)
pack.PutKey (“60 C9 5D A7 45 70 04 7F 21 7D 84 50 5C 66 A5 C6”)
' ****************
' 多出来的167字节
pack.PutTag (“01 10”)
pack.PutLength (“00 3C”)
pack.PutTag (“00 01”)
pack.PutLength (“00 38”)
pack.PutValue (token)
' ****************
pack.PutTag (“03 12”)
pack.PutLength (“00 05”)
pack.PutValue (“01 00 00 00 01”)
pack.PutTag (“05 08”)
pack.PutLength (“00 05”)
pack.PutValue (“01 00 00 00 00”)
pack.PutTag (“03 13”)
pack.PutLength (“00 19”)
pack.PutByte (“01”)
pack.PutTag (“01 02”)
pack.PutLength (“00 10”)
pack.PutKey (“04 EA 78 D1 A4 FF CD CC 7C B8 D4 12 7D BB 03 AA”) ' 两次0836包相同
pack.PutZero (3)
pack.PutByte (“00”) ' 可能为00,0F,1F
pack.PutTag (“01 02”)
pack.PutLength (“00 62”)
pack.PutWord (“00 01”)
pack.PutKey (“04 EB B7 C1 86 F9 08 96 ED 56 84 AB 50 85 2E 48”) ' 两次0836包不同
pack.PutLength (“00 38”)
pack.PutValue (“E9 AA 2B 4D 26 4C 76 18 FE 59 D5 A9 82 6A 0C 04 B4 49 50 D7 9B B1 FE 5D 97 54 8D 82 F3 22 C2 48 B9 C9 22 69 CA 78 AD 3E 2D E9 C9 DF A8 9E 7D 8C 8D 6B DF 4C D7 34 D0 D3”)
pack.PutLength (“00 14”)
pack.PutKey (crc32_code)
pack.PutDword (crc32_data)
调试输出 (pack.GetPacket ())
ret = #head + “37 13 08 36 ” + seq + “ ” + g_QQ + fix1 + #publicKey + “ 00 00 00 10 ” + _0836key1 + TeaEncrypt (pack.GetPacket (), #shareKey) + #tail
返回 (ret)
package net.mamoe.mirai.network.packet.server package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.io.DataInputStream import java.io.DataInputStream
/** /**
* @author Him188moe @ Mirai Project * @author Him188moe @ Mirai Project
*/ */
class ServerLoginSucceedPacket(inputStream: DataInputStream) : ServerPacket(inputStream) { class ServerLoginSucceedResponsePacket(input: DataInputStream) : ServerPacket(input) {
override fun decode() { override fun decode() {
TODO()
} }
} }
\ No newline at end of file
package net.mamoe.mirai.network.packet.server.login
import net.mamoe.mirai.network.packet.server.ServerPacket
import java.io.DataInputStream
/**
* @author Him188moe @ Mirai Project
*/
class ServerLoginVerificationCodeResponsePacket(input: DataInputStream) : ServerPacket(input) {
private var verifyCodeLength: Int = 0
private lateinit var verifyCode: String
private lateinit var token00BA: ByteArray
override fun decode() {
TODO()
}
}
\ No newline at end of file
package net.mamoe.mirai.network.packet.server package net.mamoe.mirai.network.packet.server.touch
import net.mamoe.mirai.network.packet.server.ServerPacket
import net.mamoe.mirai.network.packet.server.readIP
import net.mamoe.mirai.util.getRandomKey import net.mamoe.mirai.util.getRandomKey
import java.io.DataInputStream import java.io.DataInputStream
......
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