diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt index e22686018..a12e7d957 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0825ResponsePacket.kt @@ -10,7 +10,7 @@ import java.io.IOException * @author Him188moe @ Mirai Project */ @ExperimentalUnsignedTypes -@PacketId(0x08_25_31_02) +@PacketId("08 25 31 02") class Client0825ResponsePacket(private val serverIP: String, private val qq: Int) : ClientPacket() { @ExperimentalUnsignedTypes override fun encode() { diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0836_622Packet.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0836_622Packet.kt index 06ef7c89f..b4827f50c 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0836_622Packet.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/Client0836_622Packet.kt @@ -14,10 +14,15 @@ import java.net.InetAddress */ @PacketId("08 36") @ExperimentalUnsignedTypes -class Client0836_622Packet(private val qq: Int, private val password: String, private val tgtgtKey: ByteArray, private val seq: String, private val token0825: ByteArray) : ClientPacket() { +class Client0836_622Packet(private val qq: Int, private val password: String, private val loginTime: ByteArray, private val loginIP: ByteArray, private val tgtgtKey: ByteArray, private val seq: String, private val token0825: ByteArray) : ClientPacket() { @ExperimentalUnsignedTypes override fun encode() { - + this.writeHex(seq) + this.writeQQ(qq) + this.writeHex(Protocol._0836_622_fix1) + this.writeHex(Protocol.publicKey) + this.writeHex("00 00 00 10") + this.writeHex(Protocol._0836key1) //TEA 加密 this.write(TEACryptor.encrypt(object : ClientPacket() { @@ -37,7 +42,7 @@ class Client0836_622Packet(private val qq: Int, private val password: String, pr this.writeQQ(qq) this.writeHex("00 06")//tag this.writeHex("00 78")//length - this.writeTLV0006(qq, password,) + this.writeTLV0006(qq, password, loginTime, loginIP, tgtgtKey) //fix this.writeHex(Protocol._0836_622_fix2) this.writeHex("00 1A")//tag @@ -88,7 +93,7 @@ class Client0836_622Packet(private val qq: Int, private val password: String, pr writeLong(getCrc32(it))//todo may be int? check that. } } - }.encodeToByteArray(), Protocol.redirectionKey.hexToBytes())) + }.encodeToByteArray(), Protocol.shareKey.hexToBytes())) } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientHeartbeatPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientHeartbeatPacket.kt index f2241dd78..31904d469 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientHeartbeatPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientHeartbeatPacket.kt @@ -8,7 +8,8 @@ import java.io.IOException /** * @author Him188moe @ Mirai Project */ -@PacketId(0x00_58) +@ExperimentalUnsignedTypes +@PacketId("00 58") class ClientHeartbeatPacket : ClientPacket() { var qq: Int = 0 var sessionKey: ByteArray? = null//登录后获得 diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientLoginPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientLoginPacket.kt index dff281d84..1f97c6adc 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientLoginPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientLoginPacket.kt @@ -11,7 +11,7 @@ import java.io.IOException * @author Him188moe @ Mirai Project */ @ExperimentalUnsignedTypes -@PacketId(0x08_25_31_01) +@PacketId("08 25 31 01") class ClientLoginPacket : ClientPacket() { var qq: Int = 0 diff --git a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt index 734f4ce49..fcd76222c 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt +++ b/mirai-core/src/main/java/net/mamoe/mirai/network/packet/client/ClientPacket.kt @@ -85,11 +85,10 @@ fun DataOutputStream.writeTLV0006(qq: Int, password: String, loginTime: ByteArra it.writeHex(Protocol._0825data2) it.writeHex("00 00 01") - val md5_1: ByteArray = md5(password); - + val md5_1 = md5(password); val md5_2 = md5(md5_1 + "00 00 00 00".hexToBytes() + qq.toBytes()) it.write(md5_1) - it.write(loginTime)//FIXED 12(maybe 11???) bytes + it.write(loginTime)//todo FIXED 12(maybe 11???) bytes??? check that it.writeByte(0); it.writeZero(4 * 3) it.write(loginIP) diff --git a/mirai-native/src/main/c/TeaEncryption.c b/mirai-native/src/main/c/TeaEncryption.c deleted file mode 100644 index 84c2f9767..000000000 --- a/mirai-native/src/main/c/TeaEncryption.c +++ /dev/null @@ -1,356 +0,0 @@ -#include -#include -#include -#include -#include - -//#define CRYPT_ONE_BYTE - -typedef char int8 ; -typedef unsigned char uint8 ; -typedef short int16 ; -typedef unsigned short uint16 ; -typedef long int32 ; -typedef unsigned long uint32 ; - -typedef struct tagTEACTX -{ - uint8 buf[8] ; - uint8 bufPre[8] ; - const uint8 *pKey ; //指向16字节的key - uint8 *pCrypt ; - uint8 *pCryptPre ; -} TEACTX, *LPTEACTX ; - -uint16 Host2NetShort(uint16 usHost) -{ - const uint16 us = 0x1234 ; - return ((uint8 *)&us)[0] == 0x12 ? usHost : ((usHost>>8) | (usHost<<8)) ; -} - -uint16 Net2HostShort(uint16 usNet) -{ - return Host2NetShort(usNet) ; -} - -uint32 Host2NetLong(uint32 ulHost) -{ - const uint16 us = 0x1234 ; - return ((uint8 *)&us)[0] == 0x12 ? ulHost : (((ulHost>>8) & 0xFF00) | - ((ulHost<<8) & 0xFF0000) | (ulHost<<24) | (ulHost>>24)) ; -} - -uint32 Net2HostLong(uint32 ulHost) -{ - return Host2NetLong(ulHost) ; -} - -//TEA加密。v明文8字节。k密钥16字节。w密文输出8字节。 -void EnCipher(const uint32 *const v, const uint32 *const k, uint32 *const w) -{ - register uint32 - y = Host2NetLong(v[0]), - z = Host2NetLong(v[1]), - a = Host2NetLong(k[0]), - b = Host2NetLong(k[1]), - c = Host2NetLong(k[2]), - d = Host2NetLong(k[3]), - n = 0x10, /* do encrypt 16 (0x10) times */ - sum = 0, - delta = 0x9E3779B9; /* 0x9E3779B9 - 0x100000000 = -0x61C88647 */ - - while (n-- > 0) - { - sum += delta; - y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); - z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); - } - - w[0] = Net2HostLong(y); - w[1] = Net2HostLong(z); -} - -//TEA解密。v密文8字节。k密钥16字节。w明文输出8字节。 -void DeCipher(const uint32 *const v, const uint32 *const k, uint32 *const w) -{ - register uint32 - y = Host2NetLong(v[0]), - z = Host2NetLong(v[1]), - a = Host2NetLong(k[0]), - b = Host2NetLong(k[1]), - c = Host2NetLong(k[2]), - d = Host2NetLong(k[3]), - n = 0x10, - sum = 0xE3779B90, - /* why this ? must be related with n value*/ - delta = 0x9E3779B9; - - /* sum = delta<<5, in general sum = delta * n */ - while (n-- > 0) - { - z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d); - y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); - sum -= delta; - } - - w[0] = Net2HostLong(y); - w[1] = Net2HostLong(z); -} - -uint32 Random(void) -{ - return (uint32)rand(); - //return 0xdead ; -} - -//每次8字节加密 -static void EncryptEach8Bytes(TEACTX *pCtx) -{ -#ifdef CRYPT_ONE_BYTE - uint32 i ; - uint8 *pPlain8, *pPlainPre8, *pCrypt8, *pCryptPre8 ; - pPlain8 = (uint8 *)pCtx->buf ; - pPlainPre8 = (uint8 *)pCtx->bufPre ; - pCrypt8 = (uint8 *)pCtx->pCrypt ; - pCryptPre8 = (uint8 *)pCtx->pCryptPre ; - //本轮明文与上一轮的密文异或 - for(i=0; i<8; i++) - pPlain8[i] ^= pCryptPre8[i] ; - //再对异或后的明文加密 - EnCipher((uint32 *)pPlain8, (uint32 *)pCtx->pKey, (uint32 *)pCrypt8) ; - //将加密后的密文与上一轮的明文(其实是上一轮明文与上上轮密文异或结果)异或 - for(i=0; i<8; i++) - pCrypt8[i] ^= pPlainPre8[i] ; - // - for(i=0; i<8; i++) - pPlainPre8[i] = pPlain8[i] ; -#else - uint32 *pPlain8, *pPlainPre8, *pCrypt8, *pCryptPre8 ; - pPlain8 = (uint32 *)pCtx->buf ; - pPlainPre8 = (uint32 *)pCtx->bufPre ; - pCrypt8 = (uint32 *)pCtx->pCrypt ; - pCryptPre8 = (uint32 *)pCtx->pCryptPre ; - pPlain8[0] ^= pCryptPre8[0] ; - pPlain8[1] ^= pCryptPre8[1] ; - EnCipher(pPlain8, (const uint32 *)pCtx->pKey, pCrypt8) ; - pCrypt8[0] ^= pPlainPre8[0] ; - pCrypt8[1] ^= pPlainPre8[1] ; - pPlainPre8[0] = pPlain8[0] ; - pPlainPre8[1] = pPlain8[1] ; -#endif - pCtx->pCryptPre = pCtx->pCrypt ; - pCtx->pCrypt += 8 ; -} - -//加密。pPlain指向待加密的明文。ulPlainLen明文长度。pKey密钥16字节。 -//pOut指向密文输出缓冲区。pOutLen输入输出参数,指示输出缓冲区长度、密文长度。 -uint32 Encrypt(TEACTX *pCtx, const uint8 *pPlain, uint32 ulPlainLen, - const uint8 *pKey, uint8 *pOut, uint32 *pOutLen) -{ - uint32 ulPos, ulPadding, ulOut ; - const uint8 *p ; - if(pPlain == NULL || ulPlainLen == 0 || pOutLen == NULL) - return 0 ; - //计算需要填充的字节数 - //整个加密流程下来,不管明文长度多少,填充10个字节是固定的, - //然后再根据明文的长度计算还需要填充的字节数。 - ulPos = (8 - ((ulPlainLen + 10) & 0x07)) & 0x07 ; - //计算加密后的长度 - ulOut = 1 + ulPos + 2 + ulPlainLen + 7 ; - if(*pOutLen < ulOut) - { - *pOutLen = ulOut ; - return 0 ; - } - *pOutLen = ulOut ; - memset(pCtx, 0, sizeof(TEACTX)) ; - pCtx->pCrypt = pOut ; - pCtx->pCryptPre = pCtx->bufPre ; - pCtx->pKey = pKey ; - //buf[0]的最低3bit位等于所填充的长度 - pCtx->buf[0] = (uint8)((Random() & 0xF8) | ulPos) ; - //用随机数填充上面计算得到的填充长度(每个字节填充的内容是一样的)。 - //这里填充的起始位置是&buf[1]。 - memset(pCtx->buf+1, (uint8)Random(), ulPos++) ; - //至少再填充两字节 - for(ulPadding=0; ulPadding<2; ulPadding++) - { - if(ulPos == 8) - { - EncryptEach8Bytes(pCtx) ; - ulPos = 0 ; - } - pCtx->buf[ulPos++] = (uint8)Random() ; - } - p = pPlain ; - while(ulPlainLen > 0) - { - if(ulPos == 8) - { - EncryptEach8Bytes(pCtx) ; - ulPos = 0 ; - } - pCtx->buf[ulPos++] = *(p++) ; - ulPlainLen-- ; - } - //末尾再添加7字节0后加密,在解密过程的时候可以用来判断key是否正确。 - for(ulPadding=0; ulPadding<7; ulPadding++) - pCtx->buf[ulPos++] = 0x00 ; - // - EncryptEach8Bytes(pCtx) ; - return ulOut ; -} - -//每次8字节进行解密 -static void DecryptEach8Bytes(TEACTX *pCtx) -{ -#ifdef CRYPT_ONE_BYTE - uint32 i ; - uint8 bufTemp[8] ; - uint8 *pBuf8, *pBufPre8, *pCrypt8, *pCryptPre8 ; - pBuf8 = (uint8 *)pCtx->buf ; - pBufPre8 = (uint8 *)pCtx->bufPre ; - pCrypt8 = (uint8 *)pCtx->pCrypt ; - pCryptPre8 = (uint8 *)pCtx->pCryptPre ; - //当前的密文与前一轮明文(实际是前一轮明文与前前轮密文异或结果)异或 - for(i=0; i<8; i++) - bufTemp[i] = pCrypt8[i] ^ pBufPre8[i] ; - //异或后的结果再解密(解密后得到当前名文与前一轮密文异或的结果,并非真正明文) - DeCipher((uint32 *)bufTemp, (uint32 *)pCtx->pKey, (uint32 *)pBufPre8) ; - //解密后的结果与前一轮的密文异或,得到真正的明文 - for(i=0; i<8; i++) - pBuf8[i] = pBufPre8[i] ^ pCryptPre8[i] ; -#else - uint32 bufTemp[2] ; - uint32 *pBuf8, *pBufPre8, *pCrypt8, *pCryptPre8 ; - pBuf8 = (uint32 *)pCtx->buf ; - pBufPre8 = (uint32 *)pCtx->bufPre ; - pCrypt8 = (uint32 *)pCtx->pCrypt ; - pCryptPre8 = (uint32 *)pCtx->pCryptPre ; - bufTemp[0] = pCrypt8[0] ^ pBufPre8[0] ; - bufTemp[1] = pCrypt8[1] ^ pBufPre8[1] ; - DeCipher(bufTemp, (const uint32 *)pCtx->pKey, pBufPre8) ; - pBuf8[0] = pBufPre8[0] ^ pCryptPre8[0] ; - pBuf8[1] = pBufPre8[1] ^ pCryptPre8[1] ; -#endif - pCtx->pCryptPre = pCtx->pCrypt ; - pCtx->pCrypt += 8 ; -} - -//解密。pCipher指向待解密密文。ulCipherLen密文长度。pKey密钥16字节。 -//pOut指向明文输出缓冲区。pOutLen输入输出参数,指示输出缓冲区长度、明文长度。 -uint32 Decrypt(TEACTX *pCtx, const uint8 *pCipher, uint32 ulCipherLen, - const uint8 *pKey, uint8 *pOut, uint32 *pOutLen) -{ - uint32 ulPos, ulPadding, ulOut, ul ; - // 待解密的数据长度最少16字节,并且长度满足是8的整数倍。 - if(pCipher == NULL || pOutLen == NULL || - ulCipherLen < 16 || (ulCipherLen & 0x07) != 0) - return 0 ; - pCtx->pKey = pKey ; //***2016-06-15 这个忘记加了,补上*** - // 先解密头8字节,以便获取第一轮加密时填充的长度。 - DeCipher((const uint32 *)pCipher, (const uint32 *)pKey, (uint32 *)pCtx->bufPre) ; - for(ul=0; ul<8; ul++) - pCtx->buf[ul] = pCtx->bufPre[ul] ; - ulPos = pCtx->buf[0] & 0x07 ; //第一轮加密时填充的长度 - if(ulPos > 1) - { - for(ulOut=2; ulOut<=ulPos; ulOut++) - { - if(pCtx->buf[1] != pCtx->buf[ulOut]) - { - *pOutLen = 0 ; - return 0 ; //解密失败 - } - } - } - ulOut = ulCipherLen - ulPos - 10 ; - if(ulPos + 10 > ulCipherLen || *pOutLen < ulOut) - return 0 ; - pCtx->pCryptPre = (uint8 *)pCipher ; - pCtx->pCrypt = (uint8 *)pCipher + 8 ; - ulPos++ ; - for(ulPadding=0; ulPadding<2; ulPadding++) - { - if(ulPos == 8) - { - DecryptEach8Bytes(pCtx) ; - ulPos = 0 ; - } - ulPos++ ; - } - // - for(ul=0; ulbuf[ulPos] ; - ulPos++ ; - } - // - for(ulPadding=0; ulPadding<7; ulPadding++) - { - if(ulPos < 8) - { - if(pCtx->buf[ulPos] != 0x00) - { - *pOutLen = 0 ; - return 0 ; - } - } - ulPos++ ; - } - *pOutLen = ulOut ; - return 1 ; -} - -void PrintBuffer(const uint8 *buf, uint32 ulLen) -{ - uint32 i ; - for(i=0; i