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
68969669
Commit
68969669
authored
Oct 07, 2019
by
Him188
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Change into Kotlin
parent
888faaa6
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
193 additions
and
286 deletions
+193
-286
mirai-debug/src/main/java/HexComparator.kt
mirai-debug/src/main/java/HexComparator.kt
+182
-271
mirai-debug/src/main/java/PacketDebuger.kt
mirai-debug/src/main/java/PacketDebuger.kt
+11
-15
No files found.
mirai-debug/src/main/java/HexComparator.kt
View file @
68969669
import
kotlin.ranges.IntRange;
@
file
:
Suppress
(
"ObjectPropertyName"
,
"unused"
,
"NonAsciiCharacters"
,
"MayBeConstant"
)
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol;
import
net.mamoe.mirai.network.protocol.tim.TIMProtocol
import
net.mamoe.mirai.network.protocol.tim.packet.ClientPacketKt;
import
net.mamoe.mirai.network.protocol.tim.packet.toUHexString
import
net.mamoe.mirai.utils.UtilsKt;
import
net.mamoe.mirai.utils.toUHexString
import
java.awt.Toolkit
import
java.awt.*;
import
java.awt.datatransfer.DataFlavor
import
java.awt.datatransfer.DataFlavor;
import
java.lang.reflect.Field
import
java.awt.datatransfer.Transferable;
import
java.util.*
import
java.lang.reflect.Field;
import
kotlin.math.max
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;
/**
/**
* Hex 比较器, 并着色已知常量
*
* This could be used to check packet encoding..
* This could be used to check packet encoding..
* but better to run under UNIX
* but better to run under UNIX
*
*
* @author NaturalHG
* @author NaturalHG
* @author Him188moe
*/
*/
public
class
HexComparator
{
object
HexComparator
{
/**
private
val
RED
=
"\u001b[31m"
* a string result
*/
private
static
final
String
RED
=
"\033[31m"
;
private
val
GREEN
=
"\u001b[33m"
private
static
final
String
GREEN
=
"\033[33m"
;
private
val
UNKNOWN
=
"\u001b[30m"
private
static
final
String
UNKNOWN
=
"\033[30m"
;
private
val
BLUE
=
"\u001b[34m"
private
static
final
String
BLUE
=
"\033[34m"
;
public
static
final
List
<
HexReader
>
consts
=
new
LinkedList
<>()
{{
private
val
clipboardString
:
String
?
add
(
new
HexReader
(
"90 5E 39 DF 00 02 76 E4 B8 DD 00"
));
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
()
}
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"
})
return
null
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"
;
class
ConstMatcher
constructor
(
hex
:
String
)
{
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
val
matches
=
LinkedList
<
Match
>()
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
(
" "
,
" "
);
object
TestConsts
{
//private static final String MESSAGE_TAIL2_10404 ="".replace(" ", " ");
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
()
private
final
List
<
Match
>
matches
=
new
LinkedList
<>();
val
SINGLE_PLAIN_MESSAGE_HEAD
=
"00 00 01 00 09 01"
private
ConstMatcher
(
String
hex
)
{
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"
CONST_FIELDS
.
forEach
(
field
->
{
.
replace
(
" "
,
" "
)
for
(
IntRange
match
:
match
(
hex
,
field
))
{
}
matches
.
add
(
new
Match
(
match
,
field
.
getName
()));
init
{
CONST_FIELDS
.
forEach
{
field
->
for
(
match
in
match
(
hex
,
field
))
{
matches
.
add
(
Match
(
match
,
field
.
name
))
}
}
}
);
}
}
}
private
String
getMatchedConstName
(
int
hexNumber
)
{
fun
getMatchedConstName
(
hexNumber
:
Int
):
String
?
{
for
(
Match
match
:
this
.
matches
)
{
for
(
match
in
this
.
matches
)
{
if
(
match
.
range
.
contains
(
hexNumber
))
{
if
(
match
.
range
.
contains
(
hexNumber
))
{
return
match
.
constName
;
return
match
.
constName
}
}
}
}
return
null
;
return
null
}
}
private
static
List
<
IntRange
>
match
(
String
hex
,
Field
field
)
{
private
class
Match
internal
constructor
(
val
range
:
IntRange
,
val
constName
:
String
)
final
String
constValue
;
try
{
companion
object
{
constValue
=
((
String
)
field
.
get
(
null
)).
trim
();
private
val
CONST_FIELDS
:
List
<
Field
>
=
listOf
(
if
(
constValue
.
length
()
/
3
<=
3
)
{
//Minimum numbers of const hex bytes
TestConsts
::
class
.
java
,
return
new
LinkedList
<>();
TIMProtocol
::
class
.
java
).
map
{
it
.
declaredFields
}.
flatMap
{
fields
->
fields
.
map
{
field
->
field
.
trySetAccessible
()
field
}
}
}
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
){
private
fun
match
(
hex
:
String
,
field
:
Field
):
List
<
IntRange
>
{
this
.
range
=
range
;
val
constValue
:
String
this
.
constName
=
constName
;
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
static
void
buildConstNameChain
(
int
length
,
ConstMatcher
constMatcher
,
StringBuilder
constName
Builder
)
{
private
fun
buildConstNameChain
(
length
:
Int
,
constMatcher
:
ConstMatcher
,
constNameBuilder
:
String
Builder
)
{
//System.out.println(constMatcher.matches);
//System.out.println(constMatcher.matches);
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
var
i
=
0
constNameBuilder
.
append
(
" "
);
while
(
i
<
length
)
{
String
match
=
constMatcher
.
getMatchedConstName
(
i
/
4
);
constNameBuilder
.
append
(
" "
)
val
match
=
constMatcher
.
getMatchedConstName
(
i
/
4
)
if
(
match
!=
null
)
{
if
(
match
!=
null
)
{
int
appendedNameLength
=
match
.
length
();
var
appendedNameLength
=
match
.
length
constNameBuilder
.
append
(
match
)
;
constNameBuilder
.
append
(
match
)
while
(
match
.
equals
(
constMatcher
.
getMatchedConstName
(
i
++
/
4
)
))
{
while
(
match
==
constMatcher
.
getMatchedConstName
(
i
++
/
4
))
{
if
(
appendedNameLength--
<
0
)
{
if
(
appendedNameLength--
<
0
)
{
constNameBuilder
.
append
(
" "
)
;
constNameBuilder
.
append
(
" "
)
}
}
}
}
constNameBuilder
.
append
(
" "
.
repeat
(
match
.
length
()
%
4
));
constNameBuilder
.
append
(
" "
.
repeat
(
match
.
length
%
4
))
}
}
i
++
}
}
}
}
private
static
String
compare
(
String
hex1s
,
String
hex2s
)
{
fun
compare
(
hex1s
:
String
,
hex2s
:
String
):
String
{
StringBuilder
builder
=
new
StringBuilder
();
val
builder
=
StringBuilder
()
String
[]
hex1
=
hex1s
.
trim
().
replace
(
"\n"
,
""
).
split
(
" "
);
val
hex1
=
hex1s
.
trim
{
it
<=
' '
}.
replace
(
"\n"
,
""
).
split
(
" "
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
String
[]
hex2
=
hex2s
.
trim
().
replace
(
"\n"
,
""
).
split
(
" "
);
val
hex2
=
hex2s
.
trim
{
it
<=
' '
}.
replace
(
"\n"
,
""
).
split
(
" "
.
toRegex
()).
dropLastWhile
{
it
.
isEmpty
()
}.
toTypedArray
()
ConstMatcher
constMatcher1
=
new
ConstMatcher
(
hex1s
);
val
constMatcher1
=
ConstMatcher
(
hex1s
)
ConstMatcher
constMatcher2
=
new
ConstMatcher
(
hex2s
);
val
constMatcher2
=
ConstMatcher
(
hex2s
)
if
(
hex1
.
length
==
hex2
.
length
)
{
if
(
hex1
.
size
==
hex2
.
size
)
{
builder
.
append
(
GREEN
).
append
(
"长度一致:"
).
append
(
hex1
.
length
);
builder
.
append
(
GREEN
).
append
(
"长度一致:"
).
append
(
hex1
.
size
)
}
else
{
}
else
{
builder
.
append
(
RED
).
append
(
"长度不一致"
).
append
(
hex1
.
length
).
append
(
"/"
).
append
(
hex2
.
length
);
builder
.
append
(
RED
).
append
(
"长度不一致"
).
append
(
hex1
.
size
).
append
(
"/"
).
append
(
hex2
.
size
)
}
}
StringBuilder
numberLine
=
new
StringBuilder
();
val
numberLine
=
StringBuilder
()
StringBuilder
hex1ConstName
=
new
StringBuilder
();
val
hex1ConstName
=
StringBuilder
()
StringBuilder
hex1b
=
new
StringBuilder
();
val
hex1b
=
StringBuilder
()
StringBuilder
hex2b
=
new
StringBuilder
();
val
hex2b
=
StringBuilder
()
StringBuilder
hex2ConstName
=
new
StringBuilder
();
val
hex2ConstName
=
StringBuilder
()
int
dif
=
0
;
var
dif
=
0
int
length
=
Math
.
max
(
hex1
.
length
,
hex2
.
length
)
*
4
;
val
length
=
max
(
hex1
.
size
,
hex2
.
size
)
*
4
buildConstNameChain
(
length
,
constMatcher1
,
hex1ConstName
)
;
buildConstNameChain
(
length
,
constMatcher1
,
hex1ConstName
)
buildConstNameChain
(
length
,
constMatcher2
,
hex2ConstName
)
;
buildConstNameChain
(
length
,
constMatcher2
,
hex2ConstName
)
for
(
i
nt
i
=
0
;
i
<
Math
.
max
(
hex1
.
length
,
hex2
.
length
);
++
i
)
{
for
(
i
in
0
until
max
(
hex1
.
size
,
hex2
.
size
)
)
{
String
h1
=
null
;
var
h1
:
String
?
=
null
String
h2
=
null
;
var
h2
:
String
?
=
null
boolean
isDif
=
false
;
var
isDif
=
false
if
(
hex1
.
length
<=
i
)
{
if
(
hex1
.
size
<=
i
)
{
h1
=
RED
+
"__"
;
h1
=
RED
+
"__"
isDif
=
true
;
isDif
=
true
}
else
{
}
else
{
String
matchedConstName
=
constMatcher1
.
getMatchedConstName
(
i
);
val
matchedConstName
=
constMatcher1
.
getMatchedConstName
(
i
)
if
(
matchedConstName
!=
null
)
{
if
(
matchedConstName
!=
null
)
{
h1
=
BLUE
+
hex1
[
i
]
;
h1
=
BLUE
+
hex1
[
i
]
}
}
}
}
if
(
hex2
.
length
<=
i
)
{
if
(
hex2
.
size
<=
i
)
{
h2
=
RED
+
"__"
;
h2
=
RED
+
"__"
isDif
=
true
;
isDif
=
true
}
else
{
}
else
{
String
matchedConstName
=
constMatcher2
.
getMatchedConstName
(
i
);
val
matchedConstName
=
constMatcher2
.
getMatchedConstName
(
i
)
if
(
matchedConstName
!=
null
)
{
if
(
matchedConstName
!=
null
)
{
h2
=
BLUE
+
hex2
[
i
]
;
h2
=
BLUE
+
hex2
[
i
]
}
}
}
}
if
(
h1
==
null
&&
h2
==
null
)
{
if
(
h1
==
null
&&
h2
==
null
)
{
h1
=
hex1
[
i
]
;
h1
=
hex1
[
i
]
h2
=
hex2
[
i
]
;
h2
=
hex2
[
i
]
if
(
h1
.
equals
(
h2
)
)
{
if
(
h1
==
h2
)
{
h1
=
GREEN
+
h1
;
h1
=
GREEN
+
h1
h2
=
GREEN
+
h2
;
h2
=
GREEN
+
h2
}
else
{
}
else
{
h1
=
RED
+
h1
;
h1
=
RED
+
h1
h2
=
RED
+
h2
;
h2
=
RED
+
h2
isDif
=
true
;
isDif
=
true
}
}
}
else
{
}
else
{
if
(
h1
==
null
)
{
if
(
h1
==
null
)
{
h1
=
RED
+
hex1
[
i
]
;
h1
=
RED
+
hex1
[
i
]
}
}
if
(
h2
==
null
)
{
if
(
h2
==
null
)
{
h2
=
RED
+
hex2
[
i
]
;
h2
=
RED
+
hex2
[
i
]
}
}
}
}
numberLine
.
append
(
UNKNOWN
).
append
(
getFixedNumber
(
i
)).
append
(
" "
)
;
numberLine
.
append
(
UNKNOWN
).
append
(
getFixedNumber
(
i
)).
append
(
" "
)
hex1b
.
append
(
" "
).
append
(
h1
).
append
(
" "
)
;
hex1b
.
append
(
" "
).
append
(
h1
).
append
(
" "
)
hex2b
.
append
(
" "
).
append
(
h2
).
append
(
" "
)
;
hex2b
.
append
(
" "
).
append
(
h2
).
append
(
" "
)
if
(
isDif
)
{
if
(
isDif
)
{
++
dif
;
++
dif
}
}
//doConstReplacement(hex1b);
//doConstReplacement(hex1b);
//doConstReplacement(hex2b);
//doConstReplacement(hex2b);
}
}
return
(
builder
.
append
(
" "
).
append
(
dif
).
append
(
" 个不同"
).
append
(
"\n"
)
return
builder
.
append
(
" "
).
append
(
dif
).
append
(
" 个不同"
).
append
(
"\n"
)
.
append
(
numberLine
).
append
(
"\n"
)
.
append
(
numberLine
).
append
(
"\n"
)
.
append
(
hex1ConstName
).
append
(
"\n"
)
.
append
(
hex1ConstName
).
append
(
"\n"
)
.
append
(
hex1b
).
append
(
"\n"
)
.
append
(
hex1b
).
append
(
"\n"
)
.
append
(
hex2b
).
append
(
"\n"
)
.
append
(
hex2b
).
append
(
"\n"
)
.
append
(
hex2ConstName
).
append
(
"\n"
)
.
append
(
hex2ConstName
).
append
(
"\n"
)
)
.
toString
()
.
toString
();
}
}
private
static
void
doConstReplacement
(
StringBuilder
builder
)
{
private
fun
getFixedNumber
(
number
:
Int
):
String
{
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
)
{
if
(
number
<
10
)
{
return
"00
"
+
number
;
return
"00
$number"
}
}
if
(
number
<
100
)
{
return
if
(
number
<
100
)
{
return
"0"
+
number
;
"0$number"
}
}
else
number
.
toString
()
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 {
fun
main
()
{
private String s;
val
scanner
=
Scanner
(
System
.
`in`
)
private int pos = 0;
while
(
true
)
{
private int lastHaxPos = 0;
println
(
"Hex1: "
)
val
hex1
=
scanner
.
nextLine
()
println
(
"Hex2: "
)
public HexReader(String s) {
val
hex2
=
scanner
.
nextLine
()
this.s = s;
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
()
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;
}
}
/*
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"
));
*/
public void reset() {
this.pos = 0;
}
}
/*
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 @
68969669
...
@@ -10,7 +10,7 @@ import net.mamoe.mirai.utils.*
...
@@ -10,7 +10,7 @@ import net.mamoe.mirai.utils.*
import
java.io.DataInputStream
import
java.io.DataInputStream
/**
/**
*
模拟登录并抓取到 session key
*
抓包分析器
*
*
* @author Him188moe
* @author Him188moe
*/
*/
...
@@ -74,12 +74,18 @@ object Main {
...
@@ -74,12 +74,18 @@ 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
)
{
packetReceived
(
ServerPacket
.
ofByteArray
(
data
))
packetReceived
(
ServerPacket
.
ofByteArray
(
data
))
...
@@ -88,7 +94,6 @@ object Main {
...
@@ -88,7 +94,6 @@ object Main {
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"
)
println
(
"! ServerEventPacket.Raw.Encrypted"
)
packetReceived
(
packet
.
decrypt
(
sessionKey
))
packetReceived
(
packet
.
decrypt
(
sessionKey
))
println
(
"! decrypt succeed"
)
println
(
"! decrypt succeed"
)
...
@@ -112,22 +117,13 @@ object Main {
...
@@ -112,22 +117,13 @@ object Main {
//it.readShort()
//it.readShort()
//println(it.readUInt())
//println(it.readUInt())
println
(
it
.
readNBytes
(
TIMProtocol
.
fixVer2
.
hexToBytes
().
size
+
1
+
5
-
3
+
1
).
toUHexString
())
println
(
it
.
readNBytes
(
TIMProtocol
.
fixVer2
.
hexToBytes
().
size
+
1
+
5
-
3
+
1
).
toUHexString
())
it
.
readAllBytes
().
let
{
val
messageData
=
it
.
readAllBytes
().
decryptBy
(
sessionKey
)
println
(
"解密"
)
println
(
it
.
size
)
println
(
it
.
toUHexString
())
println
(
it
.
decryptBy
(
sessionKey
).
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
)
{
private
fun
DataInputStream
.
skipHex
(
uHex
:
String
)
{
this
.
skip
(
uHex
.
hexToBytes
().
size
.
toLong
())
this
.
skip
(
uHex
.
hexToBytes
().
size
.
toLong
())
...
...
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