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
f283ef43
Commit
f283ef43
authored
Apr 22, 2019
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: improve class renaming and add checks for class alias usage (#532)
parent
41abbb12
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
111 additions
and
65 deletions
+111
-65
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+19
-16
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+1
-4
NameGen.java
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+4
-1
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+1
-1
ClassInfo.java
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
+75
-30
DexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
+4
-0
DependencyCollector.java
...main/java/jadx/core/dex/visitors/DependencyCollector.java
+2
-2
RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+5
-11
No files found.
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
f283ef43
...
...
@@ -36,6 +36,7 @@ import jadx.core.utils.CodegenUtils;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
public
class
ClassGen
{
...
...
@@ -141,7 +142,7 @@ public class ClassGen {
clsCode
.
add
(
"class "
);
}
clsCode
.
attachDefinition
(
cls
);
clsCode
.
add
(
cls
.
getShortName
());
clsCode
.
add
(
cls
.
get
Alias
().
get
ShortName
());
addGenericMap
(
clsCode
,
cls
.
getGenericMap
(),
true
);
clsCode
.
add
(
' '
);
...
...
@@ -199,9 +200,8 @@ public class ClassGen {
code
.
add
(
g
.
getObject
());
}
else
{
useClass
(
code
,
g
);
if
(
classDeclaration
&&
!
cls
.
getAlias
().
isInner
())
{
addImport
(
ClassInfo
.
extCls
(
cls
.
root
(),
g
));
addImport
(
ClassInfo
.
fromType
(
cls
.
root
(),
g
));
}
}
if
(
it
.
hasNext
())
{
...
...
@@ -462,7 +462,7 @@ public class ClassGen {
}
public
void
useClass
(
CodeWriter
code
,
ArgType
type
)
{
useClass
(
code
,
ClassInfo
.
extCls
(
cls
.
root
(),
type
));
useClass
(
code
,
ClassInfo
.
fromType
(
cls
.
root
(),
type
));
ArgType
[]
generics
=
type
.
getGenericTypes
();
if
(
generics
!=
null
)
{
code
.
add
(
'<'
);
...
...
@@ -503,16 +503,16 @@ public class ClassGen {
}
private
void
addClsName
(
CodeWriter
code
,
ClassInfo
classInfo
)
{
String
clsName
=
useClassInternal
(
cls
.
get
Alias
(),
classInfo
.
getAlias
()
);
String
clsName
=
useClassInternal
(
cls
.
get
ClassInfo
(),
classInfo
);
code
.
add
(
clsName
);
}
private
String
useClassInternal
(
ClassInfo
useCls
,
ClassInfo
extClsInfo
)
{
String
fullName
=
extClsInfo
.
getFullName
();
String
fullName
=
extClsInfo
.
get
Alias
().
make
FullName
();
if
(
fallback
||
!
useImports
)
{
return
fullName
;
}
String
shortName
=
extClsInfo
.
getShortName
();
String
shortName
=
extClsInfo
.
get
Alias
().
get
ShortName
();
if
(
extClsInfo
.
getPackage
().
equals
(
"java.lang"
)
&&
extClsInfo
.
getParentClass
()
==
null
)
{
return
shortName
;
}
...
...
@@ -538,14 +538,14 @@ public class ClassGen {
if
(
extClsInfo
.
isDefaultPackage
())
{
return
shortName
;
}
if
(
extClsInfo
.
get
Package
().
equals
(
useCls
.
getPackage
()))
{
fullName
=
extClsInfo
.
getNameWithoutPackage
();
if
(
extClsInfo
.
get
Alias
().
getPackage
().
equals
(
useCls
.
getAlias
()
.
getPackage
()))
{
fullName
=
extClsInfo
.
get
Alias
().
get
NameWithoutPackage
();
}
for
(
ClassInfo
importCls
:
getImports
())
{
if
(!
importCls
.
equals
(
extClsInfo
)
&&
importCls
.
getShortName
().
equals
(
shortName
))
{
&&
importCls
.
get
Alias
().
get
ShortName
().
equals
(
shortName
))
{
if
(
extClsInfo
.
isInner
())
{
String
parent
=
useClassInternal
(
useCls
,
extClsInfo
.
getParentClass
()
.
getAlias
()
);
String
parent
=
useClassInternal
(
useCls
,
extClsInfo
.
getParentClass
());
return
parent
+
'.'
+
shortName
;
}
else
{
return
fullName
;
...
...
@@ -558,8 +558,11 @@ public class ClassGen {
private
void
addImport
(
ClassInfo
classInfo
)
{
if
(
parentGen
!=
null
)
{
parentGen
.
addImport
(
classInfo
.
getAlias
()
);
parentGen
.
addImport
(
classInfo
);
}
else
{
if
(
classInfo
.
isAlias
())
{
throw
new
JadxRuntimeException
(
"Don't add aliases class info to import list: "
+
classInfo
);
}
imports
.
add
(
classInfo
);
}
}
...
...
@@ -594,15 +597,15 @@ public class ClassGen {
if
(
useCls
==
null
)
{
return
false
;
}
String
shortName
=
searchCls
.
getShortName
();
if
(
useCls
.
getShortName
().
equals
(
shortName
))
{
String
shortName
=
searchCls
.
get
Alias
().
get
ShortName
();
if
(
useCls
.
get
Alias
().
get
ShortName
().
equals
(
shortName
))
{
return
true
;
}
ClassNode
classNode
=
dex
.
resolveClass
(
useCls
);
if
(
classNode
!=
null
)
{
for
(
ClassNode
inner
:
classNode
.
getInnerClasses
())
{
if
(
inner
.
getShortName
().
equals
(
shortName
)
&&
!
inner
.
getAlias
().
equals
(
searchCls
))
{
if
(
inner
.
get
Alias
().
get
ShortName
().
equals
(
shortName
)
&&
!
inner
.
getAlias
().
equals
(
searchCls
.
getAlias
()
))
{
return
true
;
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
f283ef43
...
...
@@ -13,7 +13,6 @@ import jadx.core.dex.attributes.AType;
import
jadx.core.dex.attributes.annotations.MethodParameters
;
import
jadx.core.dex.attributes.nodes.JumpInfo
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.ArgType
;
...
...
@@ -180,10 +179,8 @@ public class MethodGen {
addFallbackMethodCode
(
code
);
code
.
startLine
(
"*/"
);
ClassInfo
clsAlias
=
mth
.
getParentClass
().
getAlias
();
code
.
startLine
(
"throw new UnsupportedOperationException(\"Method not decompiled: "
)
.
add
(
clsAlias
.
makeFullClsName
(
clsAlias
.
getShortName
(),
true
))
.
add
(
mth
.
getParentClass
().
getAlias
().
makeFullName
(
))
.
add
(
'.'
)
.
add
(
mth
.
getAlias
())
.
add
(
'('
)
...
...
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
View file @
f283ef43
...
...
@@ -177,12 +177,15 @@ public class NameGen {
}
private
String
makeNameForObject
(
ArgType
type
)
{
if
(
type
.
isGenericType
())
{
return
StringUtils
.
escape
(
type
.
getObject
().
toLowerCase
());
}
if
(
type
.
isObject
())
{
String
alias
=
getAliasForObject
(
type
.
getObject
());
if
(
alias
!=
null
)
{
return
alias
;
}
ClassInfo
extClsInfo
=
ClassInfo
.
extCls
(
mth
.
root
(),
type
);
ClassInfo
extClsInfo
=
ClassInfo
.
fromType
(
mth
.
root
(),
type
);
String
shortName
=
extClsInfo
.
getShortName
();
String
vName
=
fromName
(
shortName
);
if
(
vName
!=
null
)
{
...
...
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
View file @
f283ef43
...
...
@@ -232,7 +232,7 @@ public class Deobfuscator {
ClassInfo
clsInfo
=
cls
.
getClassInfo
();
String
fullName
=
getClassFullName
(
clsInfo
);
if
(!
fullName
.
equals
(
clsInfo
.
getFullName
()))
{
clsInfo
.
rename
(
cls
.
dex
().
root
(),
fullName
);
clsInfo
.
rename
(
cls
.
root
(),
fullName
);
}
for
(
FieldNode
field
:
cls
.
getFields
())
{
if
(
field
.
contains
(
AFlag
.
DONT_RENAME
))
{
...
...
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
View file @
f283ef43
package
jadx
.
core
.
dex
.
info
;
import
java.io.File
;
import
java.util.Objects
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.nodes.DexNode
;
...
...
@@ -20,30 +22,53 @@ public final class ClassInfo implements Comparable<ClassInfo> {
// class info after rename (deobfuscation)
private
ClassInfo
alias
;
private
ClassInfo
(
ArgType
type
)
{
this
.
type
=
checkClassType
(
type
);
this
.
alias
=
this
;
}
private
ClassInfo
(
RootNode
root
,
ArgType
type
)
{
this
(
root
,
type
,
true
);
}
private
ClassInfo
(
RootNode
root
,
ArgType
type
,
boolean
inner
)
{
if
(!
type
.
isObject
()
||
type
.
isGeneric
())
{
throw
new
JadxRuntimeException
(
"Not class type: "
+
type
);
}
this
.
type
=
type
;
this
.
alias
=
this
;
this
(
type
);
splitAndApplyNames
(
root
,
type
,
inner
);
}
splitNames
(
root
,
inner
);
private
ClassInfo
(
ArgType
type
,
String
pkg
,
String
name
,
@Nullable
ClassInfo
parentClass
)
{
this
(
type
);
this
.
pkg
=
pkg
;
this
.
name
=
name
;
this
.
parentClass
=
parentClass
;
this
.
fullName
=
makeFullClsName
(
name
,
false
);
}
public
static
ClassInfo
fromType
(
RootNode
root
,
ArgType
type
)
{
if
(
type
.
isArray
())
{
type
=
ArgType
.
OBJECT
;
}
ClassInfo
cls
=
root
.
getInfoStorage
().
getCls
(
type
);
ArgType
clsType
=
checkClassType
(
type
);
ClassInfo
cls
=
root
.
getInfoStorage
().
getCls
(
clsType
);
if
(
cls
!=
null
)
{
return
cls
;
}
cls
=
new
ClassInfo
(
root
,
type
);
return
root
.
getInfoStorage
().
putCls
(
cls
);
ClassInfo
newClsInfo
=
new
ClassInfo
(
root
,
clsType
);
return
root
.
getInfoStorage
().
putCls
(
newClsInfo
);
}
private
static
ArgType
checkClassType
(
ArgType
type
)
{
if
(
type
==
null
)
{
throw
new
JadxRuntimeException
(
"Null class type"
);
}
if
(
type
.
isArray
())
{
// TODO: check case with method declared in array class like ( clone in int[])
return
ArgType
.
OBJECT
;
}
if
(!
type
.
isObject
()
||
type
.
isGenericType
())
{
throw
new
JadxRuntimeException
(
"Not class type: "
+
type
);
}
if
(
type
.
isGeneric
())
{
return
ArgType
.
object
(
type
.
getObject
());
}
return
type
;
}
public
static
ClassInfo
fromDex
(
DexNode
dex
,
int
clsIndex
)
{
...
...
@@ -57,19 +82,27 @@ public final class ClassInfo implements Comparable<ClassInfo> {
return
fromType
(
root
,
ArgType
.
object
(
clsName
));
}
public
static
ClassInfo
extCls
(
RootNode
root
,
ArgType
type
)
{
ClassInfo
classInfo
=
fromName
(
root
,
type
.
getObject
());
return
classInfo
.
alias
;
public
void
rename
(
RootNode
root
,
String
fullName
)
{
if
(!
alias
.
makeFullName
().
equals
(
fullName
))
{
ClassInfo
newAlias
=
new
ClassInfo
(
type
);
newAlias
.
splitAndApplyNames
(
root
,
fullName
,
isInner
());
newAlias
.
alias
=
null
;
this
.
alias
=
newAlias
;
}
}
public
void
rename
(
RootNode
root
,
String
fullName
)
{
ArgType
clsType
=
ArgType
.
object
(
fullName
);
ClassInfo
newAlias
=
root
.
getInfoStorage
().
getCls
(
clsType
);
if
(
newAlias
==
null
)
{
newAlias
=
new
ClassInfo
(
root
,
clsType
,
isInner
());
root
.
getInfoStorage
().
putCls
(
newAlias
);
public
void
renameShortName
(
String
aliasName
)
{
if
(!
Objects
.
equals
(
name
,
aliasName
))
{
ClassInfo
newAlias
=
new
ClassInfo
(
type
,
alias
.
pkg
,
aliasName
,
parentClass
);
newAlias
.
alias
=
null
;
this
.
alias
=
newAlias
;
}
if
(!
alias
.
getFullName
().
equals
(
newAlias
.
getFullName
()))
{
}
public
void
renamePkg
(
String
aliasPkg
)
{
if
(!
Objects
.
equals
(
pkg
,
aliasPkg
))
{
ClassInfo
newAlias
=
new
ClassInfo
(
type
,
aliasPkg
,
alias
.
name
,
parentClass
);
newAlias
.
alias
=
null
;
this
.
alias
=
newAlias
;
}
}
...
...
@@ -78,11 +111,18 @@ public final class ClassInfo implements Comparable<ClassInfo> {
}
public
ClassInfo
getAlias
()
{
return
alias
;
return
alias
==
null
?
this
:
alias
;
}
public
boolean
isAlias
()
{
return
alias
==
null
;
}
private
void
splitNames
(
RootNode
root
,
boolean
canBeInner
)
{
String
fullObjectName
=
type
.
getObject
();
private
void
splitAndApplyNames
(
RootNode
root
,
ArgType
type
,
boolean
canBeInner
)
{
splitAndApplyNames
(
root
,
type
.
getObject
(),
canBeInner
);
}
private
void
splitAndApplyNames
(
RootNode
root
,
String
fullObjectName
,
boolean
canBeInner
)
{
String
clsName
;
int
dot
=
fullObjectName
.
lastIndexOf
(
'.'
);
if
(
dot
==
-
1
)
{
...
...
@@ -109,7 +149,7 @@ public final class ClassInfo implements Comparable<ClassInfo> {
this
.
fullName
=
makeFullClsName
(
clsName
,
false
);
}
p
ublic
String
makeFullClsName
(
String
shortName
,
boolean
raw
)
{
p
rivate
String
makeFullClsName
(
String
shortName
,
boolean
raw
)
{
if
(
parentClass
!=
null
)
{
String
innerSep
=
raw
?
"$"
:
"."
;
return
parentClass
.
makeFullClsName
(
parentClass
.
getShortName
(),
raw
)
+
innerSep
+
shortName
;
...
...
@@ -117,6 +157,10 @@ public final class ClassInfo implements Comparable<ClassInfo> {
return
pkg
.
isEmpty
()
?
shortName
:
pkg
+
'.'
+
shortName
;
}
public
String
makeFullName
()
{
return
makeFullClsName
(
this
.
name
,
false
);
}
public
String
makeRawFullName
()
{
return
makeFullClsName
(
this
.
name
,
true
);
}
...
...
@@ -129,7 +173,7 @@ public final class ClassInfo implements Comparable<ClassInfo> {
}
public
String
getFullName
()
{
return
fullName
;
return
makeFullName
()
;
}
public
String
getShortName
()
{
...
...
@@ -172,11 +216,12 @@ public final class ClassInfo implements Comparable<ClassInfo> {
}
public
void
notInner
(
RootNode
root
)
{
splitNames
(
root
,
false
);
this
.
parentClass
=
null
;
splitAndApplyNames
(
root
,
type
,
false
);
}
public
void
updateNames
(
RootNode
root
)
{
split
Names
(
root
,
isInner
());
split
AndApplyNames
(
root
,
type
,
isInner
());
}
public
ArgType
getType
()
{
...
...
@@ -185,7 +230,7 @@ public final class ClassInfo implements Comparable<ClassInfo> {
@Override
public
String
toString
()
{
return
fullName
;
return
makeFullName
()
;
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
View file @
f283ef43
...
...
@@ -24,6 +24,7 @@ import jadx.core.dex.info.ClassInfo;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.info.MethodInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.DexFile
;
public
class
DexNode
implements
IDexNode
{
...
...
@@ -93,6 +94,9 @@ public class DexNode implements IDexNode {
@Nullable
ClassNode
resolveClassLocal
(
ClassInfo
clsInfo
)
{
if
(
clsInfo
.
isAlias
())
{
throw
new
JadxRuntimeException
(
"Don't resolve class by alias: "
+
clsInfo
);
}
return
clsMap
.
get
(
clsInfo
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java
View file @
f283ef43
...
...
@@ -114,8 +114,8 @@ public class DependencyCollector extends AbstractVisitor {
private
static
void
addDep
(
DexNode
dex
,
Set
<
ClassNode
>
depList
,
ArgType
type
)
{
if
(
type
!=
null
)
{
if
(
type
.
isObject
())
{
addDep
(
dex
,
depList
,
ClassInfo
.
from
Name
(
dex
.
root
(),
type
.
getObject
()
));
if
(
type
.
isObject
()
&&
!
type
.
isGenericType
()
)
{
addDep
(
dex
,
depList
,
ClassInfo
.
from
Type
(
dex
.
root
(),
type
));
ArgType
[]
genericTypes
=
type
.
getGenericTypes
();
if
(
type
.
isGeneric
()
&&
genericTypes
!=
null
)
{
for
(
ArgType
argType
:
genericTypes
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
View file @
f283ef43
...
...
@@ -60,9 +60,7 @@ public class RenameVisitor extends AbstractVisitor {
ClassInfo
aliasClsInfo
=
clsInfo
.
getAlias
();
if
(!
clsFullPaths
.
add
(
aliasClsInfo
.
getFullPath
().
toLowerCase
()))
{
String
newShortName
=
deobfuscator
.
getClsAlias
(
cls
);
String
newFullName
=
aliasClsInfo
.
makeFullClsName
(
newShortName
,
true
);
clsInfo
.
rename
(
root
,
newFullName
);
clsInfo
.
renameShortName
(
newShortName
);
clsFullPaths
.
add
(
clsInfo
.
getAlias
().
getFullPath
().
toLowerCase
());
}
}
...
...
@@ -71,18 +69,14 @@ public class RenameVisitor extends AbstractVisitor {
private
void
checkClassName
(
ClassNode
cls
,
JadxArgs
args
)
{
ClassInfo
classInfo
=
cls
.
getClassInfo
();
ClassInfo
alias
=
classInfo
.
getAlias
();
String
clsName
=
alias
.
getShortName
();
String
clsName
=
classInfo
.
getAlias
().
getShortName
();
String
newShortName
=
fixClsShortName
(
args
,
clsName
);
if
(!
newShortName
.
equals
(
clsName
))
{
classInfo
.
rename
(
cls
.
root
(),
alias
.
makeFullClsName
(
newShortName
,
true
));
alias
=
classInfo
.
getAlias
();
classInfo
.
renameShortName
(
newShortName
);
}
if
(
alias
.
getPackage
().
isEmpty
())
{
String
fullName
=
alias
.
makeFullClsName
(
alias
.
getShortName
(),
true
);
String
newFullName
=
Consts
.
DEFAULT_PACKAGE_NAME
+
'.'
+
fullName
;
classInfo
.
rename
(
cls
.
root
(),
newFullName
);
if
(
classInfo
.
getAlias
().
getPackage
().
isEmpty
())
{
classInfo
.
renamePkg
(
Consts
.
DEFAULT_PACKAGE_NAME
);
}
}
...
...
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