Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
9856b6d3
Commit
9856b6d3
authored
Feb 21, 2019
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: remove invalid chars from class names (#453)
parent
e1ca2904
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
23 deletions
+104
-23
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+1
-15
NameMapper.java
jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
+51
-0
RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+14
-8
NameMapperTest.java
jadx-core/src/test/java/jadx/core/deobf/NameMapperTest.java
+38
-0
No files found.
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
View file @
9856b6d3
...
...
@@ -483,21 +483,7 @@ public class Deobfuscator {
if
(
name
.
length
()
>
maxLength
)
{
return
"x"
+
Integer
.
toHexString
(
name
.
hashCode
());
}
if
(!
NameMapper
.
isAllCharsPrintable
(
name
))
{
return
removeInvalidChars
(
name
);
}
return
name
;
}
private
String
removeInvalidChars
(
String
name
)
{
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
name
.
length
();
i
++)
{
int
ch
=
name
.
charAt
(
i
);
if
(
NameMapper
.
isPrintableChar
(
ch
))
{
sb
.
append
((
char
)
ch
);
}
}
return
sb
.
toString
();
return
NameMapper
.
removeInvalidCharsMiddle
(
name
);
}
private
void
dumpClassAlias
(
ClassNode
cls
)
{
...
...
jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
View file @
9856b6d3
...
...
@@ -91,6 +91,14 @@ public class NameMapper {
&&
isAllCharsPrintable
(
str
);
}
public
static
boolean
isValidIdentifierStart
(
int
codePoint
)
{
return
Character
.
isJavaIdentifierStart
(
codePoint
);
}
public
static
boolean
isValidIdentifierPart
(
int
codePoint
)
{
return
Character
.
isJavaIdentifierPart
(
codePoint
);
}
public
static
boolean
isPrintableChar
(
int
c
)
{
return
32
<=
c
&&
c
<=
126
;
}
...
...
@@ -105,6 +113,49 @@ public class NameMapper {
return
true
;
}
/**
* Return modified string with removed:
* <p><ul>
* <li> not printable chars (including unicode)
* <li> chars not valid for java identifier part
* </ul><p>
* Note: this 'middle' method must be used with prefixed string:
* <p><ul>
* <li> can leave invalid chars for java identifier start (i.e numbers)
* <li> result not checked for reserved words
* </ul><p>
*/
public
static
String
removeInvalidCharsMiddle
(
String
name
)
{
if
(
isValidIdentifier
(
name
)
&&
isAllCharsPrintable
(
name
))
{
return
name
;
}
int
len
=
name
.
length
();
StringBuilder
sb
=
new
StringBuilder
(
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
int
codePoint
=
name
.
codePointAt
(
i
);
if
(
isPrintableChar
(
codePoint
)
&&
isValidIdentifierPart
(
codePoint
))
{
sb
.
append
((
char
)
codePoint
);
}
}
return
sb
.
toString
();
}
/**
* Return string with removed invalid chars, see {@link #removeInvalidCharsMiddle}
* <p>
* Prepend prefix if first char is not valid as java identifier start char.
*/
public
static
String
removeInvalidChars
(
String
name
,
String
prefix
)
{
String
result
=
removeInvalidCharsMiddle
(
name
);
if
(!
result
.
isEmpty
())
{
int
codePoint
=
result
.
codePointAt
(
0
);
if
(!
isValidIdentifierStart
(
codePoint
))
{
return
prefix
+
result
;
}
}
return
result
;
}
private
NameMapper
()
{
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
View file @
9856b6d3
...
...
@@ -72,14 +72,9 @@ public class RenameVisitor extends AbstractVisitor {
ClassInfo
classInfo
=
cls
.
getClassInfo
();
ClassInfo
alias
=
classInfo
.
getAlias
();
String
clsName
=
alias
.
getShortName
();
String
newShortName
=
null
;
char
firstChar
=
clsName
.
charAt
(
0
);
if
(
Character
.
isDigit
(
firstChar
))
{
newShortName
=
Consts
.
ANONYMOUS_CLASS_PREFIX
+
clsName
;
}
else
if
(
firstChar
==
'$'
)
{
newShortName
=
"C"
+
clsName
;
}
if
(
newShortName
!=
null
)
{
String
newShortName
=
fixClsShortName
(
clsName
);
if
(!
newShortName
.
equals
(
clsName
))
{
classInfo
.
rename
(
cls
.
root
(),
alias
.
makeFullClsName
(
newShortName
,
true
));
}
if
(
alias
.
getPackage
().
isEmpty
())
{
...
...
@@ -89,6 +84,17 @@ public class RenameVisitor extends AbstractVisitor {
}
}
private
String
fixClsShortName
(
String
clsName
)
{
char
firstChar
=
clsName
.
charAt
(
0
);
if
(
Character
.
isDigit
(
firstChar
))
{
return
Consts
.
ANONYMOUS_CLASS_PREFIX
+
NameMapper
.
removeInvalidCharsMiddle
(
clsName
);
}
if
(
firstChar
==
'$'
)
{
return
'C'
+
NameMapper
.
removeInvalidCharsMiddle
(
clsName
);
}
return
NameMapper
.
removeInvalidChars
(
clsName
,
"C"
);
}
private
void
checkFields
(
ClassNode
cls
)
{
Set
<
String
>
names
=
new
HashSet
<>();
for
(
FieldNode
field
:
cls
.
getFields
())
{
...
...
jadx-core/src/test/java/jadx/core/deobf/NameMapperTest.java
0 → 100644
View file @
9856b6d3
package
jadx
.
core
.
deobf
;
import
org.junit.Test
;
import
static
jadx
.
core
.
deobf
.
NameMapper
.
isValidIdentifier
;
import
static
jadx
.
core
.
deobf
.
NameMapper
.
removeInvalidChars
;
import
static
jadx
.
core
.
deobf
.
NameMapper
.
removeInvalidCharsMiddle
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
NameMapperTest
{
@Test
public
void
validIdentifiers
()
{
assertThat
(
isValidIdentifier
(
"ACls"
),
is
(
true
));
}
@Test
public
void
notValidIdentifiers
()
{
assertThat
(
isValidIdentifier
(
"1cls"
),
is
(
false
));
assertThat
(
isValidIdentifier
(
"-cls"
),
is
(
false
));
assertThat
(
isValidIdentifier
(
"A-cls"
),
is
(
false
));
}
@Test
public
void
testRemoveInvalidCharsMiddle
()
{
assertThat
(
removeInvalidCharsMiddle
(
"1cls"
),
is
(
"1cls"
));
assertThat
(
removeInvalidCharsMiddle
(
"-cls"
),
is
(
"cls"
));
assertThat
(
removeInvalidCharsMiddle
(
"A-cls"
),
is
(
"Acls"
));
}
@Test
public
void
testRemoveInvalidChars
()
{
assertThat
(
removeInvalidChars
(
"1cls"
,
"C"
),
is
(
"C1cls"
));
assertThat
(
removeInvalidChars
(
"-cls"
,
"C"
),
is
(
"cls"
));
assertThat
(
removeInvalidChars
(
"A-cls"
,
"C"
),
is
(
"Acls"
));
}
}
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