Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
Mirai
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
Mirai
Commits
db831568
Commit
db831568
authored
Oct 08, 2019
by
Him188
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/master'
parents
7749c116
97f47b54
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
650 additions
and
678 deletions
+650
-678
README.md
README.md
+1
-1
mirai-core/build.gradle
mirai-core/build.gradle
+3
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.java
...re/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.java
+0
-174
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.kt
...core/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.kt
+167
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Face.kt
...c/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Face.kt
+6
-2
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Image.kt
.../jvmMain/kotlin/net/mamoe/mirai/message/defaults/Image.kt
+6
-2
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/MessageChain.kt
...n/kotlin/net/mamoe/mirai/message/defaults/MessageChain.kt
+70
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/PlainText.kt
...Main/kotlin/net/mamoe/mirai/message/defaults/PlainText.kt
+1
-1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/TIMProtocol.kt
...otlin/net/mamoe/mirai/network/protocol/tim/TIMProtocol.kt
+2
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/ServerEvent.kt
...et/mamoe/mirai/network/protocol/tim/packet/ServerEvent.kt
+4
-65
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/action/ClientSendFriendMessagePacket.kt
...otocol/tim/packet/action/ClientSendFriendMessagePacket.kt
+14
-7
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/image/UploadGroupImage.kt
...rai/network/protocol/tim/packet/image/UploadGroupImage.kt
+9
-5
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Utils.kt
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Utils.kt
+5
-0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Varint.kt
...i-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Varint.kt
+0
-1
mirai-debug/build.gradle
mirai-debug/build.gradle
+4
-3
mirai-debug/src/main/java/HexComparator.java
mirai-debug/src/main/java/HexComparator.java
+0
-373
mirai-debug/src/main/java/HexComparator.kt
mirai-debug/src/main/java/HexComparator.kt
+291
-0
mirai-debug/src/main/java/PacketDebuger.kt
mirai-debug/src/main/java/PacketDebuger.kt
+67
-44
No files found.
README.md
View file @
db831568
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
项目处于开发阶段,学生无法每日大量更新。
项目处于开发阶段,学生无法每日大量更新。
项目还有很多未完善的地方, 欢迎任何的代码贡献, 或是 issue.
项目还有很多未完善的地方, 欢迎任何的代码贡献, 或是 issue.
部分协议来自网络上开源项目
部分协议来自网络上开源项目
一切开发旨在学习,请勿用于非法用途
**一切开发旨在学习,请勿用于非法用途**
## 抢先体验
## 抢先体验
核心框架结构已经开发完毕,一些核心功能也测试完成。
核心框架结构已经开发完毕,一些核心功能也测试完成。
...
...
mirai-core/build.gradle
View file @
db831568
...
@@ -17,6 +17,8 @@ kotlin {
...
@@ -17,6 +17,8 @@ kotlin {
}
}
}
}
jvmMain
{
jvmMain
{
apply
plugin:
'java'
dependencies
{
dependencies
{
implementation
rootProject
.
ext
.
kotlinJvm
implementation
rootProject
.
ext
.
kotlinJvm
implementation
rootProject
.
ext
.
reflect
implementation
rootProject
.
ext
.
reflect
...
@@ -28,6 +30,7 @@ kotlin {
...
@@ -28,6 +30,7 @@ kotlin {
implementation
'org.jsoup:jsoup:1.12.1'
implementation
'org.jsoup:jsoup:1.12.1'
implementation
'org.ini4j:ini4j:0.5.2'
implementation
'org.ini4j:ini4j:0.5.2'
implementation
project
(
":mirai-protocol-timpc"
)
}
}
}
}
jvmTest
{
jvmTest
{
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.java
deleted
100644 → 0
View file @
7749c116
package
net.mamoe.mirai.message
;
/**
* @author LamGC
* @author Him188moe
*/
public
enum
FaceID
{
unknown
(
0xff
),
Face_jingya
(
0
),
Face_piezui
(
1
),
Face_se
(
2
),
Face_fadai
(
3
),
Face_deyi
(
4
),
Face_liulei
(
5
),
Face_haixiu
(
6
),
Face_bizui
(
7
),
Face_shui
(
8
),
Face_daku
(
9
),
Face_ganga
(
10
),
Face_fanu
(
11
),
Face_tiaopi
(
12
),
Face_ciya
(
13
),
Face_weixiao
(
14
),
Face_nanguo
(
15
),
Face_ku
(
16
),
Face_zhuakuang
(
18
),
Face_tu
(
19
),
Face_touxiao
(
20
),
Face_keai
(
21
),
Face_baiyan
(
22
),
Face_aoman
(
23
),
Face_ji_e
(
24
),
Face_kun
(
25
),
Face_jingkong
(
26
),
Face_liuhan
(
27
),
Face_hanxiao
(
28
),
Face_dabing
(
29
),
Face_fendou
(
30
),
Face_zhouma
(
31
),
Face_yiwen
(
32
),
Face_yun
(
34
),
Face_zhemo
(
35
),
Face_shuai
(
36
),
Face_kulou
(
37
),
Face_qiaoda
(
38
),
Face_zaijian
(
39
),
Face_fadou
(
41
),
Face_aiqing
(
42
),
Face_tiaotiao
(
43
),
Face_zhutou
(
46
),
Face_yongbao
(
49
),
Face_dan_gao
(
53
),
Face_shandian
(
54
),
Face_zhadan
(
55
),
Face_dao
(
56
),
Face_zuqiu
(
57
),
Face_bianbian
(
59
),
Face_kafei
(
60
),
Face_fan
(
61
),
Face_meigui
(
63
),
Face_diaoxie
(
64
),
Face_aixin
(
66
),
Face_xinsui
(
67
),
Face_liwu
(
69
),
Face_taiyang
(
74
),
Face_yueliang
(
75
),
Face_qiang
(
76
),
Face_ruo
(
77
),
Face_woshou
(
78
),
Face_shengli
(
79
),
Face_feiwen
(
85
),
Face_naohuo
(
86
),
Face_xigua
(
89
),
Face_lenghan
(
96
),
Face_cahan
(
97
),
Face_koubi
(
98
),
Face_guzhang
(
99
),
Face_qiudale
(
100
),
Face_huaixiao
(
101
),
Face_zuohengheng
(
102
),
Face_youhengheng
(
103
),
Face_haqian
(
104
),
Face_bishi
(
105
),
Face_weiqu
(
106
),
Face_kuaikule
(
107
),
Face_yinxian
(
108
),
Face_qinqin
(
109
),
Face_xia
(
110
),
Face_kelian
(
111
),
Face_caidao
(
112
),
Face_pijiu
(
113
),
Face_lanqiu
(
114
),
Face_pingpang
(
115
),
Face_shiai
(
116
),
Face_piaochong
(
117
),
Face_baoquan
(
118
),
Face_gouyin
(
119
),
Face_quantou
(
120
),
Face_chajin
(
121
),
Face_aini
(
122
),
Face_bu
(
123
),
Face_hao
(
124
),
Face_zhuanquan
(
125
),
Face_ketou
(
126
),
Face_huitou
(
127
),
Face_tiaosheng
(
128
),
Face_huishou
(
129
),
Face_jidong
(
130
),
Face_jiewu
(
131
),
Face_xianwen
(
132
),
Face_zuotaiji
(
133
),
Face_youtaiji
(
134
),
Face_shuangxi
(
136
),
Face_bianpao
(
137
),
Face_denglong
(
138
),
Face_facai
(
139
),
Face_K_ge
(
140
),
Face_gouwu
(
141
),
Face_youjian
(
142
),
Face_shuai_qi
(
143
),
Face_hecai
(
144
),
Face_qidao
(
145
),
Face_baojin
(
146
),
Face_bangbangtang
(
147
),
Face_he_nai
(
148
),
Face_xiamian
(
149
),
Face_xiangjiao
(
150
),
Face_feiji
(
151
),
Face_kaiche
(
152
),
Face_gaotiezuochetou
(
153
),
Face_chexiang
(
154
),
Face_gaotieyouchetou
(
155
),
Face_duoyun
(
156
),
Face_xiayu
(
157
),
Face_chaopiao
(
158
),
Face_xiongmao
(
159
),
Face_dengpao
(
160
),
Face_fengche
(
161
),
Face_naozhong
(
162
),
Face_dasan
(
163
),
Face_caiqiu
(
164
),
Face_zuanjie
(
165
),
Face_shafa
(
166
),
Face_zhijin
(
167
),
Face_yao
(
168
),
Face_shouqiang
(
169
),
Face_qingwa
(
170
),
// TODO: 2019/9/1 添加更多表情
;
private
final
int
id
;
FaceID
(
int
id
)
{
this
.
id
=
id
;
}
public
int
getId
()
{
return
id
;
}
public
static
FaceID
ofId
(
int
id
)
{
for
(
FaceID
value
:
FaceID
.
values
())
{
if
(
value
.
id
==
id
)
{
return
value
;
}
}
return
FaceID
.
unknown
;
}
}
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/FaceID.kt
0 → 100644
View file @
db831568
package
net.mamoe.mirai.message
/**
* @author LamGC
* @author Him188moe
*/
@Suppress
(
"EnumEntryName"
,
"unused"
,
"SpellCheckingInspection"
)
enum
class
FaceID
constructor
(
val
id
:
Int
)
{
unknown
(
0
xff
),
// TODO: 2019/9/1 添加更多表情
jingya
(
0
),
piezui
(
1
),
se
(
2
),
fadai
(
3
),
deyi
(
4
),
liulei
(
5
),
haixiu
(
6
),
bizui
(
7
),
shui
(
8
),
daku
(
9
),
ganga
(
10
),
fanu
(
11
),
tiaopi
(
12
),
ciya
(
13
),
weixiao
(
14
),
nanguo
(
15
),
ku
(
16
),
zhuakuang
(
18
),
tu
(
19
),
touxiao
(
20
),
keai
(
21
),
baiyan
(
22
),
aoman
(
23
),
ji_e
(
24
),
kun
(
25
),
jingkong
(
26
),
liuhan
(
27
),
hanxiao
(
28
),
dabing
(
29
),
fendou
(
30
),
zhouma
(
31
),
yiwen
(
32
),
yun
(
34
),
zhemo
(
35
),
shuai
(
36
),
kulou
(
37
),
qiaoda
(
38
),
zaijian
(
39
),
fadou
(
41
),
aiqing
(
42
),
tiaotiao
(
43
),
zhutou
(
46
),
yongbao
(
49
),
dan_gao
(
53
),
shandian
(
54
),
zhadan
(
55
),
dao
(
56
),
zuqiu
(
57
),
bianbian
(
59
),
kafei
(
60
),
fan
(
61
),
meigui
(
63
),
diaoxie
(
64
),
aixin
(
66
),
xinsui
(
67
),
liwu
(
69
),
taiyang
(
74
),
yueliang
(
75
),
qiang
(
76
),
ruo
(
77
),
woshou
(
78
),
shengli
(
79
),
feiwen
(
85
),
naohuo
(
86
),
xigua
(
89
),
lenghan
(
96
),
cahan
(
97
),
koubi
(
98
),
guzhang
(
99
),
qiudale
(
100
),
huaixiao
(
101
),
zuohengheng
(
102
),
youhengheng
(
103
),
haqian
(
104
),
bishi
(
105
),
weiqu
(
106
),
kuaikule
(
107
),
yinxian
(
108
),
qinqin
(
109
),
xia
(
110
),
kelian
(
111
),
caidao
(
112
),
pijiu
(
113
),
lanqiu
(
114
),
pingpang
(
115
),
shiai
(
116
),
piaochong
(
117
),
baoquan
(
118
),
gouyin
(
119
),
quantou
(
120
),
chajin
(
121
),
aini
(
122
),
bu
(
123
),
hao
(
124
),
zhuanquan
(
125
),
ketou
(
126
),
huitou
(
127
),
tiaosheng
(
128
),
huishou
(
129
),
jidong
(
130
),
jiewu
(
131
),
xianwen
(
132
),
zuotaiji
(
133
),
youtaiji
(
134
),
shuangxi
(
136
),
bianpao
(
137
),
denglong
(
138
),
facai
(
139
),
K_ge
(
140
),
gouwu
(
141
),
youjian
(
142
),
shuai_qi
(
143
),
hecai
(
144
),
qidao
(
145
),
baojin
(
146
),
bangbangtang
(
147
),
he_nai
(
148
),
xiamian
(
149
),
xiangjiao
(
150
),
feiji
(
151
),
kaiche
(
152
),
gaotiezuochetou
(
153
),
chexiang
(
154
),
gaotieyouchetou
(
155
),
duoyun
(
156
),
xiayu
(
157
),
chaopiao
(
158
),
xiongmao
(
159
),
dengpao
(
160
),
fengche
(
161
),
naozhong
(
162
),
dasan
(
163
),
caiqiu
(
164
),
zuanjie
(
165
),
shafa
(
166
),
zhijin
(
167
),
yao
(
168
),
shouqiang
(
169
),
qingwa
(
170
);
override
fun
toString
():
String
{
return
"$name($id)"
}
companion
object
{
fun
ofId
(
id
:
Int
):
FaceID
{
for
(
value
in
values
())
{
if
(
value
.
id
==
id
)
{
return
value
}
}
return
unknown
}
}
}
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Face.kt
View file @
db831568
...
@@ -20,7 +20,11 @@ class Face(val id: FaceID) : Message() {
...
@@ -20,7 +20,11 @@ class Face(val id: FaceID) : Message() {
override
val
type
:
MessageKey
=
Key
override
val
type
:
MessageKey
=
Key
override
fun
toStringImpl
():
String
{
override
fun
toStringImpl
():
String
{
return
String
.
format
(
"[face%d]"
,
id
.
id
)
return
"[face${id.id}]"
}
override
fun
toObjectString
():
String
{
return
"Face[$id]"
}
}
override
fun
toByteArray
():
ByteArray
=
dataEncode
{
section
->
override
fun
toByteArray
():
ByteArray
=
dataEncode
{
section
->
...
@@ -48,7 +52,7 @@ class Face(val id: FaceID) : Message() {
...
@@ -48,7 +52,7 @@ class Face(val id: FaceID) : Message() {
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
internal
object
PacketHelper
{
object
PacketHelper
{
fun
ofByteArray
(
data
:
ByteArray
):
Face
=
dataDecode
(
data
)
{
fun
ofByteArray
(
data
:
ByteArray
):
Face
=
dataDecode
(
data
)
{
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/Image.kt
View file @
db831568
...
@@ -22,7 +22,11 @@ open class Image(val imageId: String) : Message() {
...
@@ -22,7 +22,11 @@ open class Image(val imageId: String) : Message() {
override
val
type
:
MessageKey
=
Key
override
val
type
:
MessageKey
=
Key
override
fun
toStringImpl
():
String
{
override
fun
toStringImpl
():
String
{
return
imageId
return
"[$imageId]"
}
override
fun
toObjectString
():
String
{
return
"Image[$imageId]"
}
}
override
fun
toByteArray
():
ByteArray
=
dataEncode
{
section
->
override
fun
toByteArray
():
ByteArray
=
dataEncode
{
section
->
...
@@ -55,7 +59,7 @@ open class Image(val imageId: String) : Message() {
...
@@ -55,7 +59,7 @@ open class Image(val imageId: String) : Message() {
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
//No string can be contained in a image
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
false
//No string can be contained in a image
internal
object
PacketHelper
{
object
PacketHelper
{
@JvmStatic
@JvmStatic
fun
ofByteArray0x06
(
data
:
ByteArray
):
Image
=
dataDecode
(
data
)
{
fun
ofByteArray0x06
(
data
:
ByteArray
):
Image
=
dataDecode
(
data
)
{
it
.
skip
(
1
)
it
.
skip
(
1
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/MessageChain.kt
View file @
db831568
...
@@ -2,7 +2,12 @@ package net.mamoe.mirai.message.defaults
...
@@ -2,7 +2,12 @@ package net.mamoe.mirai.message.defaults
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.MessageKey
import
net.mamoe.mirai.message.MessageKey
import
net.mamoe.mirai.network.protocol.tim.packet.readLVByteArray
import
net.mamoe.mirai.network.protocol.tim.packet.readNBytes
import
net.mamoe.mirai.utils.dataDecode
import
net.mamoe.mirai.utils.dataEncode
import
net.mamoe.mirai.utils.dataEncode
import
net.mamoe.mirai.utils.toUHexString
import
java.io.DataInputStream
import
java.util.*
import
java.util.*
import
java.util.stream.Collectors
import
java.util.stream.Collectors
import
java.util.stream.Stream
import
java.util.stream.Stream
...
@@ -95,4 +100,69 @@ class MessageChain : Message {
...
@@ -95,4 +100,69 @@ class MessageChain : Message {
operator
fun
component1
():
Message
=
this
.
list
[
0
]
operator
fun
component1
():
Message
=
this
.
list
[
0
]
operator
fun
component2
():
Message
=
this
.
list
[
1
]
operator
fun
component2
():
Message
=
this
.
list
[
1
]
operator
fun
component3
():
Message
=
this
.
list
[
2
]
operator
fun
component3
():
Message
=
this
.
list
[
2
]
object
PacketHelper
{
@JvmStatic
fun
ofByteArray
(
byteArray
:
ByteArray
):
MessageChain
=
dataDecode
(
byteArray
)
{
it
.
readMessageChain
()
}
}
}
}
fun
DataInputStream
.
readMessage
():
Message
?
{
val
messageType
=
this
.
readByte
().
toInt
()
val
sectionLength
=
this
.
readShort
().
toLong
()
//sectionLength: short
val
sectionData
=
this
.
readNBytes
(
sectionLength
)
return
when
(
messageType
)
{
0
x01
->
PlainText
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x02
->
Face
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x03
->
Image
.
PacketHelper
.
ofByteArray0x03
(
sectionData
)
0
x06
->
Image
.
PacketHelper
.
ofByteArray0x06
(
sectionData
)
0
x19
->
{
//长文本
val
value
=
readLVByteArray
()
//todo 未知压缩算法
PlainText
(
String
(
value
))
// PlainText(String(GZip.uncompress( value)))
}
0
x14
->
{
//长文本
val
value
=
readLVByteArray
()
println
(
value
.
size
)
println
(
value
.
toUHexString
())
//todo 未知压缩算法
this
.
skip
(
7
)
//几个TLV
return
PlainText
(
String
(
value
))
}
0
x0E
->
{
//null
null
}
else
->
{
println
(
"未知的messageType=0x${messageType.toByte().toUHexString()}"
)
println
(
"后文=${this.readAllBytes().toUHexString()}"
)
null
}
}
}
fun
DataInputStream
.
readMessageChain
():
MessageChain
{
val
chain
=
MessageChain
()
var
got
:
Message
?
=
null
do
{
if
(
got
!=
null
)
{
chain
.
concat
(
got
)
}
if
(
this
.
available
()
==
0
)
{
return
chain
}
got
=
this
.
readMessage
()
}
while
(
got
!=
null
)
return
chain
}
\ No newline at end of file
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/defaults/PlainText.kt
View file @
db831568
...
@@ -38,7 +38,7 @@ class PlainText(private val text: String) : Message() {
...
@@ -38,7 +38,7 @@ class PlainText(private val text: String) : Message() {
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
this
.
toString
().
contains
(
sub
)
override
operator
fun
contains
(
sub
:
String
):
Boolean
=
this
.
toString
().
contains
(
sub
)
internal
object
PacketHelper
{
object
PacketHelper
{
@JvmStatic
@JvmStatic
fun
ofByteArray
(
data
:
ByteArray
):
PlainText
=
dataDecode
(
data
)
{
fun
ofByteArray
(
data
:
ByteArray
):
PlainText
=
dataDecode
(
data
)
{
it
.
skip
(
1
)
it
.
skip
(
1
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/TIMProtocol.kt
View file @
db831568
...
@@ -39,6 +39,7 @@ object TIMProtocol {
...
@@ -39,6 +39,7 @@ object TIMProtocol {
*/
*/
const
val
fixVer2
=
"02 00 00 00 01 01 01 00 00 68 20"
const
val
fixVer2
=
"02 00 00 00 01 01 01 00 00 68 20"
// 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00
// 02 38 03 00 CD 48 68 3E 03 3F A2 02 00 00 00
// 02 00 00 00 01 2E 01 00 00 69 35
/**
/**
* 0825data1
* 0825data1
*/
*/
...
@@ -105,6 +106,7 @@ object TIMProtocol {
...
@@ -105,6 +106,7 @@ object TIMProtocol {
* length=15
* length=15
*/
*/
const
val
messageConst1
=
"00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
const
val
messageConst1
=
"00 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91"
// TIM最新 22 00 0C E5 BE AE E8 BD AF E9 9B 85 E9 BB 91
private
val
hexToByteArrayCacheMap
:
MutableMap
<
Int
,
ByteArray
>
=
mutableMapOf
()
private
val
hexToByteArrayCacheMap
:
MutableMap
<
Int
,
ByteArray
>
=
mutableMapOf
()
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/ServerEvent.kt
View file @
db831568
...
@@ -2,11 +2,8 @@
...
@@ -2,11 +2,8 @@
package
net.mamoe.mirai.network.protocol.tim.packet
package
net.mamoe.mirai.network.protocol.tim.packet
import
net.mamoe.mirai.message.Message
import
net.mamoe.mirai.message.defaults.Face
import
net.mamoe.mirai.message.defaults.Image
import
net.mamoe.mirai.message.defaults.MessageChain
import
net.mamoe.mirai.message.defaults.MessageChain
import
net.mamoe.mirai.message.defaults.
PlainText
import
net.mamoe.mirai.message.defaults.
readMessageChain
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.utils.dataDecode
import
net.mamoe.mirai.utils.dataDecode
import
net.mamoe.mirai.utils.hexToBytes
import
net.mamoe.mirai.utils.hexToBytes
...
@@ -49,7 +46,7 @@ abstract class ServerEventPacket(input: DataInputStream, val packetId: ByteArray
...
@@ -49,7 +46,7 @@ abstract class ServerEventPacket(input: DataInputStream, val packetId: ByteArray
@PacketId
(
"00 17"
)
@PacketId
(
"00 17"
)
class
Encrypted
(
input
:
DataInputStream
,
private
val
packetId
:
ByteArray
)
:
ServerPacket
(
input
)
{
class
Encrypted
(
input
:
DataInputStream
,
private
val
packetId
:
ByteArray
)
:
ServerPacket
(
input
)
{
fun
decrypt
(
sessionKey
:
ByteArray
):
Raw
=
Raw
(
decryptBy
(
sessionKey
),
packetId
).
setId
(
this
.
idHex
)
fun
decrypt
(
sessionKey
:
ByteArray
):
Raw
=
Raw
(
this
.
decryptBy
(
sessionKey
),
packetId
).
setId
(
this
.
idHex
)
}
}
}
}
...
@@ -135,7 +132,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
...
@@ -135,7 +132,7 @@ class ServerGroupMessageEventPacket(input: DataInputStream, packetId: ByteArray,
this
.
input
.
goto
(
108
)
this
.
input
.
goto
(
108
)
this
.
input
.
readLVByteArray
()
this
.
input
.
readLVByteArray
()
input
.
skip
(
2
)
//2个0x00
input
.
skip
(
2
)
//2个0x00
message
=
input
.
read
Sections
()
message
=
input
.
read
MessageChain
()
val
map
=
input
.
readTLVMap
(
true
)
val
map
=
input
.
readTLVMap
(
true
)
if
(
map
.
containsKey
(
18
))
{
if
(
map
.
containsKey
(
18
))
{
...
@@ -262,7 +259,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
...
@@ -262,7 +259,7 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
input
.
goto
(
93
+
l1
)
input
.
goto
(
93
+
l1
)
input
.
readLVByteArray
()
//font
input
.
readLVByteArray
()
//font
input
.
skip
(
2
)
//2个0x00
input
.
skip
(
2
)
//2个0x00
message
=
input
.
read
Sections
()
message
=
input
.
read
MessageChain
()
val
map
:
Map
<
Int
,
ByteArray
>
=
input
.
readTLVMap
(
true
).
withDefault
{
byteArrayOf
()
}
val
map
:
Map
<
Int
,
ByteArray
>
=
input
.
readTLVMap
(
true
).
withDefault
{
byteArrayOf
()
}
println
(
map
.
getValue
(
18
))
println
(
map
.
getValue
(
18
))
...
@@ -278,64 +275,6 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
...
@@ -278,64 +275,6 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
}
}
}
}
private
fun
DataInputStream
.
readSection
():
Message
?
{
val
messageType
=
this
.
readByte
().
toInt
()
val
sectionLength
=
this
.
readShort
().
toLong
()
//sectionLength: short
val
sectionData
=
this
.
readNBytes
(
sectionLength
)
return
when
(
messageType
)
{
0
x01
->
PlainText
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x02
->
Face
.
PacketHelper
.
ofByteArray
(
sectionData
)
0
x03
->
Image
.
PacketHelper
.
ofByteArray0x03
(
sectionData
)
0
x06
->
Image
.
PacketHelper
.
ofByteArray0x06
(
sectionData
)
0
x19
->
{
//长文本
val
value
=
readLVByteArray
()
//todo 未知压缩算法
PlainText
(
String
(
value
))
// PlainText(String(GZip.uncompress( value)))
}
0
x14
->
{
//长文本
val
value
=
readLVByteArray
()
println
(
value
.
size
)
println
(
value
.
toUHexString
())
//todo 未知压缩算法
this
.
skip
(
7
)
//几个TLV
return
PlainText
(
String
(
value
))
}
0
x0E
->
{
//null
null
}
else
->
{
println
(
"未知的messageType=0x${messageType.toByte().toUHexString()}"
)
println
(
"后文=${this.readAllBytes().toUHexString()}"
)
null
}
}
}
private
fun
DataInputStream
.
readSections
():
MessageChain
{
val
chain
=
MessageChain
()
var
got
:
Message
?
=
null
do
{
if
(
got
!=
null
)
{
chain
.
concat
(
got
)
}
if
(
this
.
available
()
==
0
)
{
return
chain
}
got
=
this
.
readSection
()
}
while
(
got
!=
null
)
return
chain
}
/*
/*
牛逼 (10404
牛逼 (10404
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/action/ClientSendFriendMessagePacket.kt
View file @
db831568
...
@@ -34,11 +34,22 @@ class ClientSendFriendMessagePacket(
...
@@ -34,11 +34,22 @@ class ClientSendFriendMessagePacket(
writeRandom
(
2
)
writeRandom
(
2
)
writeTime
()
writeTime
()
writeHex
(
"00 00"
+
writeHex
(
"00 00"
+
"00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00"
)
"00 00 00 00"
)
//01 1D 00 00 00 00 01 00 00 00 01 4D 53 47 00 00 00 00 00
//消息过多要分包发送
//如果只有一个
writeByte
(
0
x01
)
writeByte
(
0
)
//第几个包
writeByte
(
0
)
//如果大于一个,
//writeByte(0x02)//数量
//writeByte(0)//第几个包
//writeByte(0x91)//why?
writeHex
(
"00 01 4D 53 47 00 00 00 00 00"
)
writeTime
()
writeTime
()
writeRandom
(
4
)
writeRandom
(
4
)
writeHex
(
"00 00 00 00 09 00 86"
)
writeHex
(
"00 00 00 00 09 00 86"
)
//TIM最新 0C 00 86
writeHex
(
TIMProtocol
.
messageConst1
)
//... 85 E9 BB 91
writeHex
(
TIMProtocol
.
messageConst1
)
//... 85 E9 BB 91
writeZero
(
2
)
writeZero
(
2
)
...
@@ -56,9 +67,5 @@ class ClientSendFriendMessagePacket(
...
@@ -56,9 +67,5 @@ class ClientSendFriendMessagePacket(
}
}
}
}
fun
main
()
{
}
@PacketId
(
"00 CD"
)
@PacketId
(
"00 CD"
)
class
ServerSendFriendMessageResponsePacket
(
input
:
DataInputStream
)
:
ServerPacket
(
input
)
class
ServerSendFriendMessageResponsePacket
(
input
:
DataInputStream
)
:
ServerPacket
(
input
)
\ No newline at end of file
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/network/protocol/tim/packet/image/UploadGroupImage.kt
View file @
db831568
...
@@ -37,18 +37,19 @@ class ClientTryGetImageIDPacket(
...
@@ -37,18 +37,19 @@ class ClientTryGetImageIDPacket(
writeZero
(
2
)
writeZero
(
2
)
writeHex
(
"5
E"
)
writeHex
(
"5
B"
)
//原5E
writeHex
(
"08"
)
writeHex
(
"08"
)
writeHex
(
"01 12 03 98 01 01 10 01"
)
writeHex
(
"01 12 03 98 01 01 10 01"
)
writeHex
(
"1A"
)
writeHex
(
"1A"
)
writeHex
(
"5
A"
)
writeHex
(
"5
7"
)
//原5A
writeHex
(
"08"
)
writeHex
(
"08"
)
writeUVarInt
(
groupNumberOrQQNumber
)
writeUVarInt
(
groupNumberOrQQNumber
)
//FB D2 D8 94
writeByte
(
0
x02
)
writeHex
(
"10"
)
writeHex
(
"10"
)
writeUVarInt
(
botNumber
)
writeUVarInt
(
botNumber
)
//A2 FF 8C F0
writeHex
(
"18 00"
)
writeHex
(
"18 00"
)
...
@@ -57,10 +58,13 @@ class ClientTryGetImageIDPacket(
...
@@ -57,10 +58,13 @@ class ClientTryGetImageIDPacket(
write
(
md5
(
byteArray
))
write
(
md5
(
byteArray
))
writeHex
(
"28"
)
writeHex
(
"28"
)
writeUVarInt
(
byteArray
.
size
.
toUInt
())
writeUVarInt
(
byteArray
.
size
.
toUInt
())
//E2 0D
writeHex
(
"32"
)
writeHex
(
"32"
)
writeHex
(
"1A"
)
writeHex
(
"1A"
)
//28 00 5A 00 53 00 41 00 58 00 40 00 57 00 4B 00 52 00 4A 00 5A 00 31 00 7E 00 38 01 48 01 50 38 58 34 60 04 6A 05 32 36 39 33 33 70 00 78 03 80 01 00
writeHex
(
"37 00 4D 00 32 00 25 00 4C 00 31 00 56 00 32 00 7B 00 39 00 30 00 29 00 52 00"
)
writeHex
(
"37 00 4D 00 32 00 25 00 4C 00 31 00 56 00 32 00 7B 00 39 00 30 00 29 00 52 00"
)
writeHex
(
"38 01"
)
writeHex
(
"38 01"
)
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Utils.kt
View file @
db831568
...
@@ -84,6 +84,11 @@ fun <R> dataDecode(byteArray: ByteArray, t: (DataInputStream) -> R): R = byteArr
...
@@ -84,6 +84,11 @@ fun <R> dataDecode(byteArray: ByteArray, t: (DataInputStream) -> R): R = byteArr
fun
<
R
>
ByteArray
.
decode
(
t
:
(
DataInputStream
)
->
R
):
R
=
this
.
dataInputStream
().
let
(
t
)
fun
<
R
>
ByteArray
.
decode
(
t
:
(
DataInputStream
)
->
R
):
R
=
this
.
dataInputStream
().
let
(
t
)
fun
ByteArray
.
decryptBy
(
key
:
ByteArray
):
ByteArray
=
TEA
.
decrypt
(
this
,
key
)
fun
ByteArray
.
decryptBy
(
key
:
String
):
ByteArray
=
TEA
.
decrypt
(
this
,
key
)
fun
DataInputStream
.
skip
(
n
:
Number
)
{
fun
DataInputStream
.
skip
(
n
:
Number
)
{
this
.
skip
(
n
.
toLong
())
this
.
skip
(
n
.
toLong
())
}
}
...
...
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils/Varint.kt
View file @
db831568
...
@@ -69,7 +69,6 @@ fun DataOutputStream.writeVarInt(signedInt: Int) {
...
@@ -69,7 +69,6 @@ fun DataOutputStream.writeVarInt(signedInt: Int) {
this
.
writeUVarInt
(
encodeZigZag32
(
signedInt
))
this
.
writeUVarInt
(
encodeZigZag32
(
signedInt
))
}
}
@Throws
(
IOException
::
class
)
@Throws
(
IOException
::
class
)
fun
DataOutputStream
.
writeUVarInt
(
uint
:
UInt
)
{
fun
DataOutputStream
.
writeUVarInt
(
uint
:
UInt
)
{
return
writeUVarInt
(
uint
.
toLong
())
return
writeUVarInt
(
uint
.
toLong
())
...
...
mirai-debug/build.gradle
View file @
db831568
...
@@ -3,11 +3,12 @@ apply plugin: "java"
...
@@ -3,11 +3,12 @@ apply plugin: "java"
dependencies
{
dependencies
{
implementation
project
(
':mirai-core'
)
implementation
project
(
':mirai-core'
)
compile
'com.google.protobuf:protobuf-java:3.5.0'
compile
files
(
'./lib/jpcap.jar'
)
compile
files
(
'./lib/jpcap.jar'
)
compile
'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M2'
compile
rootProject
.
ext
.
coroutineCommon
compile
'org.jetbrains.kotlin:kotlin-stdlib:1.3.50'
compile
rootProject
.
ext
.
kotlinJvm
compile
group:
'com.google.protobuf'
,
name:
'protobuf-java'
,
version:
rootProject
.
ext
.
protobuf_version
}
}
tasks
.
withType
(
JavaCompile
)
{
tasks
.
withType
(
JavaCompile
)
{
...
...
mirai-debug/src/main/java/HexComparator.java
deleted
100644 → 0
View file @
7749c116
import
kotlin.ranges.IntRange
;
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
;
import
net.mamoe.mirai.network.protocol.tim.packet.ClientPacketKt
;
import
net.mamoe.mirai.utils.UtilsKt
;
import
java.awt.*
;
import
java.awt.datatransfer.DataFlavor
;
import
java.awt.datatransfer.Transferable
;
import
java.lang.reflect.Field
;
import
java.util.Arrays
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Scanner
;
import
java.util.concurrent.atomic.AtomicBoolean
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.function.BiConsumer
;
/**
* This could be used to check packet encoding..
* but better to run under UNIX
*
* @author NaturalHG
*/
public
class
HexComparator
{
/**
* a string result
*/
private
static
final
String
RED
=
"\033[31m"
;
private
static
final
String
GREEN
=
"\033[33m"
;
private
static
final
String
UNKNOWN
=
"\033[30m"
;
private
static
final
String
BLUE
=
"\033[34m"
;
public
static
final
List
<
HexReader
>
consts
=
new
LinkedList
<>()
{{
add
(
new
HexReader
(
"90 5E 39 DF 00 02 76 E4 B8 DD 00"
));
}};
private
static
class
ConstMatcher
{
private
static
final
List
<
Field
>
CONST_FIELDS
=
new
LinkedList
<>()
{{
List
.
of
(
TIMProtocol
.
class
).
forEach
(
aClass
->
Arrays
.
stream
(
aClass
.
getDeclaredFields
()).
peek
(
this
::
add
).
forEach
(
Field:
:
trySetAccessible
));
List
.
of
(
TestConsts
.
class
).
forEach
(
aClass
->
Arrays
.
stream
(
aClass
.
getDeclaredFields
()).
peek
(
this
::
add
).
forEach
(
Field:
:
trySetAccessible
));
}};
@SuppressWarnings
({
"unused"
,
"NonAsciiCharacters"
})
private
static
class
TestConsts
{
private
static
final
String
NIU_BI
=
UtilsKt
.
toUHexString
(
"牛逼"
.
getBytes
(),
" "
);
private
static
final
String
_1994701021
=
ClientPacketKt
.
toUHexString
(
1994701021
,
" "
);
private
static
final
String
_1040400290
=
ClientPacketKt
.
toUHexString
(
1040400290
,
" "
);
private
static
final
String
_580266363
=
ClientPacketKt
.
toUHexString
(
580266363
,
" "
);
private
static
final
String
_1040400290_
=
"3E 03 3F A2"
;
private
static
final
String
_1994701021_
=
"76 E4 B8 DD"
;
private
static
final
String
_jiahua_
=
"B1 89 BE 09"
;
private
static
final
String
_Him188moe_
=
UtilsKt
.
toUHexString
(
"Him188moe"
.
getBytes
(),
" "
);
private
static
final
String
发图片
=
UtilsKt
.
toUHexString
(
"发图片"
.
getBytes
(),
" "
);
private
static
final
String
群
=
UtilsKt
.
toUHexString
(
"发图片"
.
getBytes
(),
" "
);
private
static
final
String
SINGLE_PLAIN_MESSAGE_HEAD
=
"00 00 01 00 09 01"
;
private
static
final
String
MESSAGE_TAIL_10404
=
"0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00"
.
replace
(
" "
,
" "
);
//private static final String MESSAGE_TAIL2_10404 ="".replace(" ", " ");
}
private
final
List
<
Match
>
matches
=
new
LinkedList
<>();
private
ConstMatcher
(
String
hex
)
{
CONST_FIELDS
.
forEach
(
field
->
{
for
(
IntRange
match
:
match
(
hex
,
field
))
{
matches
.
add
(
new
Match
(
match
,
field
.
getName
()));
}
});
}
private
String
getMatchedConstName
(
int
hexNumber
)
{
for
(
Match
match
:
this
.
matches
)
{
if
(
match
.
range
.
contains
(
hexNumber
))
{
return
match
.
constName
;
}
}
return
null
;
}
private
static
List
<
IntRange
>
match
(
String
hex
,
Field
field
)
{
final
String
constValue
;
try
{
constValue
=
((
String
)
field
.
get
(
null
)).
trim
();
if
(
constValue
.
length
()
/
3
<=
3
)
{
//Minimum numbers of const hex bytes
return
new
LinkedList
<>();
}
}
catch
(
IllegalAccessException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
ClassCastException
ignored
)
{
return
new
LinkedList
<>();
}
return
new
LinkedList
<>()
{{
int
index
=
-
1
;
while
((
index
=
hex
.
indexOf
(
constValue
,
index
+
1
))
!=
-
1
)
{
add
(
new
IntRange
(
index
/
3
,
(
index
+
constValue
.
length
())
/
3
));
}
}};
}
private
static
class
Match
{
private
IntRange
range
;
private
String
constName
;
Match
(
IntRange
range
,
String
constName
){
this
.
range
=
range
;
this
.
constName
=
constName
;
}
}
}
private
static
void
buildConstNameChain
(
int
length
,
ConstMatcher
constMatcher
,
StringBuilder
constNameBuilder
)
{
//System.out.println(constMatcher.matches);
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
constNameBuilder
.
append
(
" "
);
String
match
=
constMatcher
.
getMatchedConstName
(
i
/
4
);
if
(
match
!=
null
)
{
int
appendedNameLength
=
match
.
length
();
constNameBuilder
.
append
(
match
);
while
(
match
.
equals
(
constMatcher
.
getMatchedConstName
(
i
++
/
4
)))
{
if
(
appendedNameLength
--
<
0
)
{
constNameBuilder
.
append
(
" "
);
}
}
constNameBuilder
.
append
(
" "
.
repeat
(
match
.
length
()
%
4
));
}
}
}
private
static
String
compare
(
String
hex1s
,
String
hex2s
)
{
StringBuilder
builder
=
new
StringBuilder
();
String
[]
hex1
=
hex1s
.
trim
().
replace
(
"\n"
,
""
).
split
(
" "
);
String
[]
hex2
=
hex2s
.
trim
().
replace
(
"\n"
,
""
).
split
(
" "
);
ConstMatcher
constMatcher1
=
new
ConstMatcher
(
hex1s
);
ConstMatcher
constMatcher2
=
new
ConstMatcher
(
hex2s
);
if
(
hex1
.
length
==
hex2
.
length
)
{
builder
.
append
(
GREEN
).
append
(
"长度一致:"
).
append
(
hex1
.
length
);
}
else
{
builder
.
append
(
RED
).
append
(
"长度不一致"
).
append
(
hex1
.
length
).
append
(
"/"
).
append
(
hex2
.
length
);
}
StringBuilder
numberLine
=
new
StringBuilder
();
StringBuilder
hex1ConstName
=
new
StringBuilder
();
StringBuilder
hex1b
=
new
StringBuilder
();
StringBuilder
hex2b
=
new
StringBuilder
();
StringBuilder
hex2ConstName
=
new
StringBuilder
();
int
dif
=
0
;
int
length
=
Math
.
max
(
hex1
.
length
,
hex2
.
length
)
*
4
;
buildConstNameChain
(
length
,
constMatcher1
,
hex1ConstName
);
buildConstNameChain
(
length
,
constMatcher2
,
hex2ConstName
);
for
(
int
i
=
0
;
i
<
Math
.
max
(
hex1
.
length
,
hex2
.
length
);
++
i
)
{
String
h1
=
null
;
String
h2
=
null
;
boolean
isDif
=
false
;
if
(
hex1
.
length
<=
i
)
{
h1
=
RED
+
"__"
;
isDif
=
true
;
}
else
{
String
matchedConstName
=
constMatcher1
.
getMatchedConstName
(
i
);
if
(
matchedConstName
!=
null
)
{
h1
=
BLUE
+
hex1
[
i
];
}
}
if
(
hex2
.
length
<=
i
)
{
h2
=
RED
+
"__"
;
isDif
=
true
;
}
else
{
String
matchedConstName
=
constMatcher2
.
getMatchedConstName
(
i
);
if
(
matchedConstName
!=
null
)
{
h2
=
BLUE
+
hex2
[
i
];
}
}
if
(
h1
==
null
&&
h2
==
null
)
{
h1
=
hex1
[
i
];
h2
=
hex2
[
i
];
if
(
h1
.
equals
(
h2
))
{
h1
=
GREEN
+
h1
;
h2
=
GREEN
+
h2
;
}
else
{
h1
=
RED
+
h1
;
h2
=
RED
+
h2
;
isDif
=
true
;
}
}
else
{
if
(
h1
==
null
)
{
h1
=
RED
+
hex1
[
i
];
}
if
(
h2
==
null
)
{
h2
=
RED
+
hex2
[
i
];
}
}
numberLine
.
append
(
UNKNOWN
).
append
(
getFixedNumber
(
i
)).
append
(
" "
);
hex1b
.
append
(
" "
).
append
(
h1
).
append
(
" "
);
hex2b
.
append
(
" "
).
append
(
h2
).
append
(
" "
);
if
(
isDif
)
{
++
dif
;
}
//doConstReplacement(hex1b);
//doConstReplacement(hex2b);
}
return
(
builder
.
append
(
" "
).
append
(
dif
).
append
(
" 个不同"
).
append
(
"\n"
)
.
append
(
numberLine
).
append
(
"\n"
)
.
append
(
hex1ConstName
).
append
(
"\n"
)
.
append
(
hex1b
).
append
(
"\n"
)
.
append
(
hex2b
).
append
(
"\n"
)
.
append
(
hex2ConstName
).
append
(
"\n"
)
)
.
toString
();
}
private
static
void
doConstReplacement
(
StringBuilder
builder
)
{
String
mirror
=
builder
.
toString
();
HexReader
hexs
=
new
HexReader
(
mirror
);
for
(
AtomicInteger
i
=
new
AtomicInteger
(
0
);
i
.
get
()
<
builder
.
length
();
i
.
addAndGet
(
1
))
{
hexs
.
setTo
(
i
.
get
());
consts
.
forEach
(
a
->
{
hexs
.
setTo
(
i
.
get
());
List
<
Integer
>
posToPlaceColor
=
new
LinkedList
<>();
AtomicBoolean
is
=
new
AtomicBoolean
(
false
);
a
.
readFully
((
c
,
d
)
->
{
if
(
c
.
equals
(
hexs
.
readHex
()))
{
posToPlaceColor
.
add
(
d
);
}
else
{
is
.
set
(
false
);
}
});
if
(
is
.
get
())
{
AtomicInteger
adder
=
new
AtomicInteger
();
posToPlaceColor
.
forEach
(
e
->
{
builder
.
insert
(
e
+
adder
.
getAndAdd
(
BLUE
.
length
()),
BLUE
);
});
}
});
}
}
private
static
String
getFixedNumber
(
int
number
)
{
if
(
number
<
10
)
{
return
"00"
+
number
;
}
if
(
number
<
100
)
{
return
"0"
+
number
;
}
return
String
.
valueOf
(
number
);
}
private
static
String
getClipboardString
()
{
Transferable
trans
=
Toolkit
.
getDefaultToolkit
().
getSystemClipboard
().
getContents
(
null
);
if
(
trans
.
isDataFlavorSupported
(
DataFlavor
.
stringFlavor
))
{
try
{
return
(
String
)
trans
.
getTransferData
(
DataFlavor
.
stringFlavor
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
return
null
;
}
public
static
void
main
(
String
[]
args
)
{
Scanner
scanner
=
new
Scanner
(
System
.
in
);
while
(
true
)
{
System
.
out
.
println
(
"Hex1: "
);
var
hex1
=
scanner
.
nextLine
();
System
.
out
.
println
(
"Hex2: "
);
var
hex2
=
scanner
.
nextLine
();
System
.
out
.
println
(
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
);
System
.
out
.
println
(
HexComparator
.
compare
(
hex1
,
hex2
));
System
.
out
.
println
();
}
/*
System.out.println(HexComparator.compare(
//mirai
"2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC Protocol.messageConst1 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
,
//e
"2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC Protocol.messageConst1 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
));
/*
System.out.println(HexComparator.compare(
//e
"90 5E 39 DF 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 7B 7B 7B 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC",
//mirai
"6F 0B DF 92 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E9 E9 E9 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC\n\n\n"
));*/
}
}
class
HexReader
{
private
String
s
;
private
int
pos
=
0
;
private
int
lastHaxPos
=
0
;
public
HexReader
(
String
s
)
{
this
.
s
=
s
;
}
public
String
readHex
()
{
boolean
isStr
=
false
;
String
next
=
""
;
for
(;
pos
<
s
.
length
()
-
2
;
++
pos
)
{
char
s1
=
' '
;
if
(
pos
!=
0
)
{
s1
=
this
.
s
.
charAt
(
0
);
}
char
s2
=
this
.
s
.
charAt
(
pos
+
1
);
char
s3
=
this
.
s
.
charAt
(
pos
+
2
);
char
s4
=
' '
;
if
(
this
.
s
.
length
()
!=
(
this
.
pos
+
3
))
{
s4
=
this
.
s
.
charAt
(
pos
+
3
);
}
if
(
Character
.
isSpaceChar
(
s1
)
&&
Character
.
isSpaceChar
(
s4
)
&&
(
Character
.
isDigit
(
s2
)
||
Character
.
isAlphabetic
(
s2
))
&&
(
Character
.
isDigit
(
s3
)
||
Character
.
isAlphabetic
(
s3
))
)
{
this
.
pos
+=
2
;
this
.
lastHaxPos
=
this
.
pos
+
1
;
return
String
.
valueOf
(
s2
)
+
s3
;
}
}
return
""
;
}
public
void
readFully
(
BiConsumer
<
String
,
Integer
>
processor
)
{
this
.
reset
();
String
nextHax
=
this
.
readHex
();
while
(!
nextHax
.
equals
(
" "
))
{
processor
.
accept
(
nextHax
,
this
.
lastHaxPos
);
nextHax
=
this
.
readHex
();
}
}
public
void
setTo
(
int
pos
)
{
this
.
pos
=
pos
;
}
public
void
reset
()
{
this
.
pos
=
0
;
}
}
mirai-debug/src/main/java/HexComparator.kt
0 → 100644
View file @
db831568
@
file
:
Suppress
(
"ObjectPropertyName"
,
"unused"
,
"NonAsciiCharacters"
,
"MayBeConstant"
)
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.packet.toUHexString
import
net.mamoe.mirai.utils.toUHexString
import
java.awt.Toolkit
import
java.awt.datatransfer.DataFlavor
import
java.lang.reflect.Field
import
java.util.*
import
kotlin.math.max
/**
* Hex 比较器, 并着色已知常量
*
* This could be used to check packet encoding..
* but better to run under UNIX
*
* @author NaturalHG
* @author Him188moe
*/
object
HexComparator
{
private
val
RED
=
"\u001b[31m"
private
val
GREEN
=
"\u001b[33m"
private
val
UNKNOWN
=
"\u001b[30m"
private
val
BLUE
=
"\u001b[34m"
private
val
clipboardString
:
String
?
get
()
{
val
trans
=
Toolkit
.
getDefaultToolkit
().
systemClipboard
.
getContents
(
null
)
if
(
trans
.
isDataFlavorSupported
(
DataFlavor
.
stringFlavor
))
{
try
{
return
trans
.
getTransferData
(
DataFlavor
.
stringFlavor
)
as
String
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
}
}
return
null
}
class
ConstMatcher
constructor
(
hex
:
String
)
{
private
val
matches
=
LinkedList
<
Match
>()
object
TestConsts
{
val
NIU_BI
=
"牛逼"
.
toByteArray
().
toUHexString
()
val
_1994701021
=
1994701021
.
toUHexString
(
" "
)
val
_1040400290
=
1040400290
.
toUHexString
(
" "
)
val
_580266363
=
580266363
.
toUHexString
(
" "
)
val
_1040400290_
=
"3E 03 3F A2"
val
_1994701021_
=
"76 E4 B8 DD"
val
_jiahua_
=
"B1 89 BE 09"
val
_Him188moe_
=
"Him188moe"
.
toByteArray
().
toUHexString
()
val
发图片 = "发图片".
toByteArray
().
toUHexString
()
val
群 = "群".
toByteArray
().
toUHexString
()
val
SINGLE_PLAIN_MESSAGE_HEAD
=
"00 00 01 00 09 01"
val
MESSAGE_TAIL_10404
=
"0E 00 07 01 00 04 00 00 00 09 19 00 18 01 00 15 AA 02 12 9A 01 0F 80 01 01 C8 01 00 F0 01 00 F8 01 00 90 02 00"
.
replace
(
" "
,
" "
)
}
@Suppress
(
"SpellCheckingInspection"
)
object
PacketIds
{
val
heartbeat
=
"00 58"
val
friendmsg
=
"00 CD"
}
init
{
CONST_FIELDS
.
forEach
{
field
->
for
(
match
in
match
(
hex
,
field
))
{
matches
.
add
(
Match
(
match
,
field
.
name
))
}
}
}
fun
getMatchedConstName
(
hexNumber
:
Int
):
String
?
{
for
(
match
in
this
.
matches
)
{
if
(
match
.
range
.
contains
(
hexNumber
))
{
return
match
.
constName
}
}
return
null
}
private
class
Match
internal
constructor
(
val
range
:
IntRange
,
val
constName
:
String
)
companion
object
{
private
val
CONST_FIELDS
:
List
<
Field
>
=
listOf
(
TestConsts
::
class
.
java
,
TIMProtocol
::
class
.
java
,
PacketIds
::
class
.
java
).
map
{
it
.
declaredFields
}.
flatMap
{
fields
->
fields
.
map
{
field
->
field
.
trySetAccessible
()
field
}
}
}
private
fun
match
(
hex
:
String
,
field
:
Field
):
List
<
IntRange
>
{
val
constValue
:
String
try
{
constValue
=
(
field
.
get
(
null
)
as
String
).
trim
{
it
<=
' '
}
if
(
constValue
.
length
/
3
<=
3
)
{
//Minimum numbers of const hex bytes
return
LinkedList
()
}
}
catch
(
e
:
IllegalAccessException
)
{
throw
RuntimeException
(
e
)
}
catch
(
ignored
:
ClassCastException
)
{
return
LinkedList
()
}
return
object
:
LinkedList
<
IntRange
>()
{
init
{
var
index
=
-
1
index
=
hex
.
indexOf
(
constValue
,
index
+
1
)
while
(
index
!=
-
1
)
{
add
(
IntRange
(
index
/
3
,
(
index
+
constValue
.
length
)
/
3
))
index
=
hex
.
indexOf
(
constValue
,
index
+
1
)
}
}
}
}
}
private
fun
buildConstNameChain
(
length
:
Int
,
constMatcher
:
ConstMatcher
,
constNameBuilder
:
StringBuilder
)
{
//System.out.println(constMatcher.matches);
var
i
=
0
while
(
i
<
length
)
{
constNameBuilder
.
append
(
" "
)
val
match
=
constMatcher
.
getMatchedConstName
(
i
/
4
)
if
(
match
!=
null
)
{
var
appendedNameLength
=
match
.
length
constNameBuilder
.
append
(
match
)
while
(
match
==
constMatcher
.
getMatchedConstName
(
i
++
/
4
))
{
if
(
appendedNameLength--
<
0
)
{
constNameBuilder
.
append
(
" "
)
}
}
constNameBuilder
.
append
(
" "
.
repeat
(
match
.
length
%
4
))
}
i
++
}
}
fun
compare
(
hex1s
:
String
,
hex2s
:
String
):
String
{
val
builder
=
StringBuilder
()
val
hex1
=
hex1s
.
trim
{
it
<=
' '
}.
replace
(
"\n"
,
""
).
split
(
" "
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
val
hex2
=
hex2s
.
trim
{
it
<=
' '
}.
replace
(
"\n"
,
""
).
split
(
" "
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
val
constMatcher1
=
ConstMatcher
(
hex1s
)
val
constMatcher2
=
ConstMatcher
(
hex2s
)
if
(
hex1
.
size
==
hex2
.
size
)
{
builder
.
append
(
GREEN
).
append
(
"长度一致:"
).
append
(
hex1
.
size
)
}
else
{
builder
.
append
(
RED
).
append
(
"长度不一致"
).
append
(
hex1
.
size
).
append
(
"/"
).
append
(
hex2
.
size
)
}
val
numberLine
=
StringBuilder
()
val
hex1ConstName
=
StringBuilder
()
val
hex1b
=
StringBuilder
()
val
hex2b
=
StringBuilder
()
val
hex2ConstName
=
StringBuilder
()
var
dif
=
0
val
length
=
max
(
hex1
.
size
,
hex2
.
size
)
*
4
buildConstNameChain
(
length
,
constMatcher1
,
hex1ConstName
)
buildConstNameChain
(
length
,
constMatcher2
,
hex2ConstName
)
for
(
i
in
0
until
max
(
hex1
.
size
,
hex2
.
size
))
{
var
h1
:
String
?
=
null
var
h2
:
String
?
=
null
var
isDif
=
false
if
(
hex1
.
size
<=
i
)
{
h1
=
RED
+
"__"
isDif
=
true
}
else
{
val
matchedConstName
=
constMatcher1
.
getMatchedConstName
(
i
)
if
(
matchedConstName
!=
null
)
{
h1
=
BLUE
+
hex1
[
i
]
}
}
if
(
hex2
.
size
<=
i
)
{
h2
=
RED
+
"__"
isDif
=
true
}
else
{
val
matchedConstName
=
constMatcher2
.
getMatchedConstName
(
i
)
if
(
matchedConstName
!=
null
)
{
h2
=
BLUE
+
hex2
[
i
]
}
}
if
(
h1
==
null
&&
h2
==
null
)
{
h1
=
hex1
[
i
]
h2
=
hex2
[
i
]
if
(
h1
==
h2
)
{
h1
=
GREEN
+
h1
h2
=
GREEN
+
h2
}
else
{
h1
=
RED
+
h1
h2
=
RED
+
h2
isDif
=
true
}
}
else
{
if
(
h1
==
null
)
{
h1
=
RED
+
hex1
[
i
]
}
if
(
h2
==
null
)
{
h2
=
RED
+
hex2
[
i
]
}
}
numberLine
.
append
(
UNKNOWN
).
append
(
getFixedNumber
(
i
)).
append
(
" "
)
hex1b
.
append
(
" "
).
append
(
h1
).
append
(
" "
)
hex2b
.
append
(
" "
).
append
(
h2
).
append
(
" "
)
if
(
isDif
)
{
++
dif
}
//doConstReplacement(hex1b);
//doConstReplacement(hex2b);
}
return
builder
.
append
(
" "
).
append
(
dif
).
append
(
" 个不同"
).
append
(
"\n"
)
.
append
(
numberLine
).
append
(
"\n"
)
.
append
(
hex1ConstName
).
append
(
"\n"
)
.
append
(
hex1b
).
append
(
"\n"
)
.
append
(
hex2b
).
append
(
"\n"
)
.
append
(
hex2ConstName
).
append
(
"\n"
)
.
toString
()
}
private
fun
getFixedNumber
(
number
:
Int
):
String
{
if
(
number
<
10
)
{
return
"00$number"
}
return
if
(
number
<
100
)
{
"0$number"
}
else
number
.
toString
()
}
}
fun
main
()
{
val
scanner
=
Scanner
(
System
.
`in`
)
while
(
true
)
{
println
(
"Hex1: "
)
val
hex1
=
scanner
.
nextLine
()
println
(
"Hex2: "
)
val
hex2
=
scanner
.
nextLine
()
println
(
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
)
println
(
HexComparator
.
compare
(
hex1
,
hex2
))
println
()
}
/*
System.out.println(HexComparator.compare(
//mirai
"2A 22 96 29 7B 00 40 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 EC 21 40 06 18 89 54 BC Protocol.messageConst1 00 00 01 00 0A 01 00 07 E7 89 9B E9 80 BC 21\n"
,
//e
"2A 22 96 29 7B 00 3F 00 01 01 00 00 00 00 00 00 00 4D 53 47 00 00 00 00 00 5D 6B 8E 1A FE 39 0B FC Protocol.messageConst1 00 00 01 00 0A 01 00 07 6D 65 73 73 61 67 65"
));
*/
/*
System.out.println(HexComparator.compare(
//e
"90 5E 39 DF 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 7B 7B 7B 7B 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC",
//mirai
"6F 0B DF 92 00 02 76 E4 B8 DD 00 00 04 53 00 00 00 01 00 00 15 85 00 00 01 55 35 05 8E C9 BA 16 D0 01 63 5B 59 4B 59 52 31 01 B9 00 00 00 00 00 00 00 00 00 00 00 00 00 E9 E9 E9 E9 00 00 00 00 00 00 00 00 00 10 15 74 C4 89 85 7A 19 F5 5E A9 C9 A3 5E 8A 5A 9B AA BB CC DD EE FF AA BB CC\n\n\n"
));*/
}
\ No newline at end of file
mirai-debug/src/main/java/PacketDebuger.kt
View file @
db831568
...
@@ -3,14 +3,16 @@
...
@@ -3,14 +3,16 @@
import
jpcap.JpcapCaptor
import
jpcap.JpcapCaptor
import
jpcap.packet.IPPacket
import
jpcap.packet.IPPacket
import
jpcap.packet.UDPPacket
import
jpcap.packet.UDPPacket
import
net.mamoe.mirai.message.defaults.readMessageChain
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.packet.ServerEventPacket
import
net.mamoe.mirai.network.protocol.tim.packet.ServerEventPacket
import
net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import
net.mamoe.mirai.network.protocol.tim.packet.ServerPacket
import
net.mamoe.mirai.network.protocol.tim.packet.UnknownServerEventPacket
import
net.mamoe.mirai.network.protocol.tim.packet.UnknownServerPacket
import
net.mamoe.mirai.utils.*
import
net.mamoe.mirai.utils.*
import
java.io.DataInputStream
/**
/**
*
模拟登录并抓取到 session key
*
抓包分析器
*
*
* @author Him188moe
* @author Him188moe
*/
*/
...
@@ -59,8 +61,8 @@ object Main {
...
@@ -59,8 +61,8 @@ object Main {
dataReceived
(
pk
.
data
)
dataReceived
(
pk
.
data
)
}
else
{
}
else
{
try
{
try
{
println
(
"size = "
+
pk
.
data
.
size
)
dataSent
(
pk
.
data
)
dataSent
(
pk
.
data
)
println
()
}
catch
(
e
:
Exception
)
{
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
e
.
printStackTrace
()
}
}
...
@@ -74,24 +76,47 @@ object Main {
...
@@ -74,24 +76,47 @@ object Main {
/**
/**
*
从 TIM 内存中读取.
*
可从 TIM 内存中读取
*
*
* 方法:
* 方法:
* 在 Common.dll 中搜索
* 1. x32dbg 附加 TIM
* 2. `符号` 中找到 common.dll
* 3. 搜索函数 `oi_symmetry_encrypt2` (TEA 加密函数)
* 4. 双击跳转
* 5. 断点并在TIM发送消息以触发
* 6. 运行到 `mov eax,dword ptr ss:[ebp+10]`
* 7. 从 eax 开始的 16个 bytes 便是 `sessionKey`
*/
*/
const
val
sessionKey
:
String
=
"70 BD 1E 12 20 C1 25 12 A0 F8 4F 0D C0 A0 97 0E"
val
sessionKey
:
ByteArray
=
"48 C0 11 42 2D FD 8F 36 6E BA BF FD D3 AA B7 AE"
.
hexToBytes
()
fun
dataReceived
(
data
:
ByteArray
)
{
fun
dataReceived
(
data
:
ByteArray
)
{
//println("--------------")
//println("接收数据包")
//println("raw packet = " + data.toUHexString())
packetReceived
(
ServerPacket
.
ofByteArray
(
data
))
packetReceived
(
ServerPacket
.
ofByteArray
(
data
))
}
}
fun
packetReceived
(
packet
:
ServerPacket
)
{
fun
packetReceived
(
packet
:
ServerPacket
)
{
when
(
packet
)
{
when
(
packet
)
{
is
ServerEventPacket
.
Raw
.
Encrypted
->
{
is
ServerEventPacket
.
Raw
.
Encrypted
->
{
val
sessionKey
=
"8B 45 10 0F 10 00 66 0F 38 00 05 20 39 18 64 0F"
.
hexToBytes
()
println
(
"! ServerEventPacket.Raw.Encrypted"
)
packetReceived
(
packet
.
decrypt
(
sessionKey
))
packetReceived
(
packet
.
decrypt
(
sessionKey
))
println
(
"! decrypt succeed"
)
}
is
ServerEventPacket
.
Raw
->
packetReceived
(
packet
.
distribute
())
is
UnknownServerEventPacket
->
{
println
(
"--------------"
)
println
(
"未知事件ID="
+
packet
.
packetId
.
toUHexString
())
println
(
"未知事件: "
+
packet
.
input
.
readAllBytes
().
toUHexString
())
}
is
ServerEventPacket
->
{
println
(
"事件"
)
println
(
packet
)
}
is
UnknownServerPacket
->
{
//ignore
}
}
else
->
{
else
->
{
...
@@ -99,47 +124,45 @@ object Main {
...
@@ -99,47 +124,45 @@ object Main {
}
}
}
}
fun
dataSent
(
rawPacket
:
ByteArray
)
=
rawPacket
.
cutTail
(
1
).
decode
{
packet
->
println
(
"---------------------------"
)
packet
.
skip
(
3
)
//head
val
idHex
=
packet
.
readNBytes
(
4
).
toUHexString
()
println
(
"发出包ID = $idHex"
)
packet
.
skip
(
TIMProtocol
.
fixVer2
.
hexToBytes
().
size
+
1
+
5
-
3
+
1
)
val
encryptedBody
=
packet
.
readAllBytes
()
println
(
"body = ${encryptedBody.toUHexString()}"
)
encryptedBody
.
decode
{
data
->
fun
dataSent
(
data
:
ByteArray
)
{
data
.
cutTail
(
1
).
decode
{
base
->
base
.
skip
(
3
)
val
idHex
=
base
.
readNBytes
(
4
).
toUHexString
()
println
(
"发出包$idHex"
)
when
(
idHex
.
substring
(
0
,
5
))
{
when
(
idHex
.
substring
(
0
,
5
))
{
"00 CD"
->
{
"00 CD"
->
{
println
(
"好友消息发出: "
)
println
(
"好友消息"
)
dataDecode
(
data
)
{
//it.readShort()
val
raw
=
data
.
readAllBytes
()
//println(it.readUInt())
println
(
"解密前数据: "
+
raw
.
toUHexString
())
println
(
it
.
readNBytes
(
TIMProtocol
.
fixVer2
.
hexToBytes
().
size
+
1
+
5
-
3
+
1
).
toUHexString
())
val
messageData
=
raw
.
decryptBy
(
sessionKey
)
it
.
readAllBytes
().
let
{
println
(
"解密结果: "
+
messageData
.
toUHexString
())
println
(
"解密"
)
println
(
"尝试解消息"
)
println
(
it
.
size
)
messageData
.
decode
{
println
(
it
.
toUHexString
())
it
.
skip
(
println
(
it
.
decryptBy
(
sessionKey
).
toUHexString
())
4
+
4
+
12
+
2
+
4
+
4
+
16
+
2
+
2
+
4
+
2
+
16
+
4
+
4
+
7
+
15
+
2
}
+
1
)
val
chain
=
it
.
readMessageChain
()
println
(
chain
.
toObjectString
())
}
}
}
}
"03 88"
->
{
println
(
"上传图片-获取图片ID"
)
data
.
skip
(
8
)
val
body
=
data
.
readAllBytes
().
decryptBy
(
sessionKey
)
println
(
body
.
toUHexString
())
}
}
}
}
}
}
private
fun
ByteArray
.
decryptBy
(
key
:
ByteArray
):
ByteArray
=
TEA
.
decrypt
(
this
,
key
)
private
fun
ByteArray
.
decryptBy
(
key
:
String
):
ByteArray
=
TEA
.
decrypt
(
this
,
key
)
private
fun
DataInputStream
.
skipHex
(
uHex
:
String
)
{
this
.
skip
(
uHex
.
hexToBytes
().
size
.
toLong
())
}
}
}
}
\ No newline at end of file
/*
00 19
tim的 publicKey = 02 F4 07 37 2D F1 82 1D 45 E8 30 14 41 74 AF E3 03 AB 29 D7 82 D9 E2 E5 89
00 00
tim的 key0836=70 BE 41 20 3A FA 05 B2 2D 66 2E 29 33 55 99 7E
552
76 AF AE 95 EB 89 BE B5 1C 83 D2 87 23 3B 5A 3B 6B 4C 78 AD F9 93 86 CA 13 D7 86 B5 0C D1 84 FB 2B ED 59 26 42 3B E0 6F 1A 91 A5 98 91 20 25 3F 6D C0 F6 FC 27 3D F8 34 EA 50 95 8C 2A BB 22 73 BD 76 60 2A 6B 68 51 07 4A 2F 37 6D 97 42 51 C5 14 47 96 3A A9 6B 8F 66 F8 D4 F4 52 22 13 D5 CC 9F B1 B4 06 BC 4B 35 B6 CF D8 CB 70 0F 0C E6 AA D9 12 E9 A2 C7 7F D8 24 7E 1B 2D 97 67 DA 34 0A FD 8E 44 D3 58 50 0D F0 0A 20 08 0A 46 28 68 0A 06 17 36 84 94 2C 97 2A 22 32 7B 01 67 3F E4 90 71 88 B2 F9 7B 7B AC 1A 00 CD 54 4A D7 AE 71 68 B3 FB E5 F3 94 9A C2 A1 C3 CA A5 4E AB 2C B0 78 AD EE 63 3F E6 24 6E AC 31 A5 00 F4 DB C7 4B 65 44 7B 92 87 30 7D 73 B3 21 81 C8 99 33 06 65 28 0C 98 56 EF 41 DC 64 79 55 69 AD B7 F4 A4 CF 4A 28 4B 3B E3 5A 2B C1 72 20 95 D9 8E 9F 1E A5 DE 9A DD 39 0B BE 76 A8 BE 95 9D 7C C2 C5 A8 3A D3 76 B6 D4 ED 15 34 5D 3C 8E 96 C6 93 64 78 A1 89 78 DA F8 17 E5 96 75 5F B6 97 FC 41 18 A4 54 67 BA 3B ED 97 27 B7 E3 90 81 1E DC 8D 17 25 46 2D 08 0D BB 95 D0 CB C8 9B 78 36 2D 70 E3 C6 4C 21 E9 C0 02 69 3B C5 F7 91 6B 62 D8 E4 10 F0 01 5B 7F 1A 3E 9F 1A D4 D3 A9 2B 4A C2 BD 6D 8B B0 0A AE A4 E9 72 71 F4 39 28 CE 18 42 ED FD BB 61 08 B1 95 93 8E F6 29 D7 B6 CB 15 2A AA AF A7 81 AD DF 3B D5 3F 47 29 AB 61 0C 86 48 82 93 AE 8C 2C 32 CC 83 83 68 08 C6 9D 10 81 82 BA 92 24 0E ED 71 B1 83 E1 08 D0 01 BB DF E2 26 D0 20 DF 8C 95 E1 A6 42 C2 A2 E7 85 00 E6 AA 54 A8 0C 5D BB 8D 46 37 AD 47 88 38 B9 D7 3B 48 13 13 81 3B A5 05 4D 32 24 A4 CE 08 73 6D 89 FD 6D CC F5 AB 8B 6A 39 4B 9D 30 33 73 F1 01 7F E4 43 03 72 44 67 3A 24 28 40 51 2B EB 48 EB F9 05 A9 3C 20 EB 4D B7 45 56 D3 4E BD A0 B5 40 65 D1 16 57 73 A4 81 B1 A6 8C 3F 68 28 AA EB 83
*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment