Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
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
a3b961e7
Commit
a3b961e7
authored
Apr 22, 2018
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix method deobfuscation (#241)
parent
0e4c8df4
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
209 additions
and
129 deletions
+209
-129
.gitignore
.gitignore
+1
-0
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+1
-1
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+1
-1
NameGen.java
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+1
-1
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+73
-54
ClassInfo.java
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
+25
-24
DexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
+9
-16
RootNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
+20
-3
ClassModifier.java
...e/src/main/java/jadx/core/dex/visitors/ClassModifier.java
+1
-1
DependencyCollector.java
...main/java/jadx/core/dex/visitors/DependencyCollector.java
+1
-1
RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+6
-18
AndroidResourcesUtils.java
...n/java/jadx/core/utils/android/AndroidResourcesUtils.java
+2
-3
FileUtils.java
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
+12
-0
IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+17
-6
TestMthRename.java
...test/java/jadx/tests/integration/deobf/TestMthRename.java
+39
-0
No files found.
.gitignore
View file @
a3b961e7
...
...
@@ -29,3 +29,4 @@ jadx-output/
*.log
*.cfg
jadx-core/src/test/java/jadx/tests/external/
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
a3b961e7
...
...
@@ -435,7 +435,7 @@ public class ClassGen {
}
public
void
useClass
(
CodeWriter
code
,
ArgType
type
)
{
useClass
(
code
,
ClassInfo
.
extCls
(
cls
.
dex
(),
type
));
useClass
(
code
,
ClassInfo
.
extCls
(
cls
.
root
(),
type
));
ArgType
[]
generics
=
type
.
getGenericTypes
();
if
(
generics
!=
null
)
{
code
.
add
(
'<'
);
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
a3b961e7
...
...
@@ -612,7 +612,7 @@ public class InsnGen {
MethodInfo
callMth
=
insn
.
getCallMth
();
// inline method
MethodNode
callMthNode
=
mth
.
dex
().
deepResolveMethod
(
callMth
);
MethodNode
callMthNode
=
mth
.
root
().
deepResolveMethod
(
callMth
);
if
(
callMthNode
!=
null
)
{
if
(
inlineMethod
(
callMthNode
,
insn
,
code
))
{
return
;
...
...
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
View file @
a3b961e7
...
...
@@ -159,7 +159,7 @@ public class NameGen {
if
(
alias
!=
null
)
{
return
alias
;
}
ClassInfo
extClsInfo
=
ClassInfo
.
extCls
(
mth
.
dex
(),
type
);
ClassInfo
extClsInfo
=
ClassInfo
.
extCls
(
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 @
a3b961e7
package
jadx
.
core
.
deobf
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
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.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
...
...
@@ -26,6 +14,18 @@ import org.jetbrains.annotations.Nullable;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
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.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.MethodNode
;
public
class
Deobfuscator
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Deobfuscator
.
class
);
...
...
@@ -89,7 +89,7 @@ public class Deobfuscator {
private
void
preProcess
()
{
for
(
DexNode
dexNode
:
dexNodes
)
{
for
(
ClassNode
cls
:
dexNode
.
getClasses
())
{
do
Class
(
cls
);
preProcess
Class
(
cls
);
}
}
}
...
...
@@ -101,7 +101,7 @@ public class Deobfuscator {
}
for
(
DexNode
dexNode
:
dexNodes
)
{
for
(
ClassNode
cls
:
dexNode
.
getClasses
())
{
processClass
(
dexNode
,
cls
);
processClass
(
cls
);
}
}
postProcess
();
...
...
@@ -128,7 +128,6 @@ public class Deobfuscator {
mth
.
setAlias
(
aliasToUse
);
mth
.
setAliasFromPreset
(
aliasFromPreset
);
}
id
++;
}
}
...
...
@@ -151,9 +150,7 @@ public class Deobfuscator {
for
(
MethodNode
m
:
cls
.
getMethods
())
{
if
(
m
.
getMethodInfo
().
getShortId
().
startsWith
(
signature
))
{
result
=
cls
;
if
(!
overrideSet
.
contains
(
m
.
getMethodInfo
()))
{
overrideSet
.
add
(
m
.
getMethodInfo
());
}
break
;
}
}
...
...
@@ -196,13 +193,14 @@ public class Deobfuscator {
}
}
}
return
result
;
}
private
void
resolveOverriding
(
DexNode
dex
,
ClassNode
cls
,
MethodNode
mth
)
{
private
void
resolveOverriding
(
MethodNode
mth
)
{
Set
<
MethodInfo
>
overrideSet
=
new
HashSet
<>();
resolveOverridingInternal
(
dex
,
cls
,
mth
.
getMethodInfo
().
makeSignature
(
false
),
overrideSet
,
cls
);
String
mthSignature
=
mth
.
getMethodInfo
().
makeSignature
(
false
);
ClassNode
cls
=
mth
.
getParentClass
();
resolveOverridingInternal
(
mth
.
dex
(),
cls
,
mthSignature
,
overrideSet
,
cls
);
if
(
overrideSet
.
size
()
>
1
)
{
OverridedMethodsNode
overrideNode
=
null
;
for
(
MethodInfo
_mth
:
overrideSet
)
{
...
...
@@ -223,34 +221,42 @@ public class Deobfuscator {
}
}
}
}
else
{
overrideSet
.
clear
();
}
overrideSet
.
clear
();
}
private
void
processClass
(
DexNode
dex
,
ClassNode
cls
)
{
private
void
processClass
(
ClassNode
cls
)
{
ClassInfo
clsInfo
=
cls
.
getClassInfo
();
String
fullName
=
getClassFullName
(
clsInfo
);
if
(!
fullName
.
equals
(
clsInfo
.
getFullName
()))
{
clsInfo
.
rename
(
dex
,
fullName
);
clsInfo
.
rename
(
cls
.
dex
().
root
()
,
fullName
);
}
for
(
FieldNode
field
:
cls
.
getFields
())
{
renameField
(
field
);
}
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
renameMethod
(
mth
);
}
for
(
ClassNode
innerCls
:
cls
.
getInnerClasses
())
{
processClass
(
innerCls
);
}
}
public
void
renameField
(
FieldNode
field
)
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
String
alias
=
getFieldAlias
(
field
);
if
(
alias
!=
null
)
{
fieldInfo
.
setAlias
(
alias
);
}
}
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
public
void
renameMethod
(
MethodNode
mth
)
{
String
alias
=
getMethodAlias
(
mth
);
if
(
alias
!=
null
)
{
methodInfo
.
setAlias
(
alias
);
mth
.
getMethodInfo
()
.
setAlias
(
alias
);
}
if
(
mth
.
isVirtual
())
{
resolveOverriding
(
dex
,
cls
,
mth
);
}
resolveOverriding
(
mth
);
}
}
...
...
@@ -311,7 +317,7 @@ public class Deobfuscator {
return
prefix
+
clsInfo
.
getShortName
();
}
private
void
do
Class
(
ClassNode
cls
)
{
private
void
preProcess
Class
(
ClassNode
cls
)
{
ClassInfo
classInfo
=
cls
.
getClassInfo
();
String
pkgFullName
=
classInfo
.
getPackage
();
PackageNode
pkg
=
getPackageNode
(
pkgFullName
,
true
);
...
...
@@ -320,13 +326,14 @@ public class Deobfuscator {
String
alias
=
deobfPresets
.
getForCls
(
classInfo
);
if
(
alias
!=
null
)
{
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
this
,
cls
,
pkg
,
alias
));
return
;
}
else
{
if
(!
clsMap
.
containsKey
(
classInfo
)
&&
shouldRename
(
classInfo
.
getShortName
()))
{
makeClsAlias
(
cls
);
}
if
(
clsMap
.
containsKey
(
classInfo
))
{
return
;
}
if
(
shouldRename
(
classInfo
.
getShortName
()
))
{
makeClsAlias
(
c
ls
);
for
(
ClassNode
innerCls
:
cls
.
getInnerClasses
(
))
{
preProcessClass
(
innerC
ls
);
}
}
...
...
@@ -361,21 +368,33 @@ public class Deobfuscator {
if
(
sourceFileAttr
==
null
)
{
return
null
;
}
if
(
cls
.
getClassInfo
().
isInner
())
{
return
null
;
}
String
name
=
sourceFileAttr
.
getFileName
();
if
(
name
.
endsWith
(
".java"
))
{
name
=
name
.
substring
(
0
,
name
.
length
()
-
".java"
.
length
());
}
else
if
(
name
.
endsWith
(
".kt"
))
{
name
=
name
.
substring
(
0
,
name
.
length
()
-
".kt"
.
length
());
}
if
(!
NameMapper
.
isValidIdentifier
(
name
)
||
NameMapper
.
isReserved
(
name
))
{
return
null
;
}
for
(
DeobfClsInfo
deobfClsInfo
:
clsMap
.
values
())
{
if
(
deobfClsInfo
.
getAlias
().
equals
(
name
))
{
return
null
;
}
if
(
NameMapper
.
isValidIdentifier
(
name
)
&&
!
NameMapper
.
isReserved
(
name
))
{
// TODO: check if no class with this name exists or already renamed
cls
.
remove
(
AType
.
SOURCE_FILE
);
return
name
;
}
ClassNode
otherCls
=
cls
.
dex
().
root
().
searchClassByName
(
cls
.
getPackage
()
+
"."
+
name
);
if
(
otherCls
!=
null
)
{
return
null
;
}
cls
.
remove
(
AType
.
SOURCE_FILE
);
return
name
;
}
@Nullable
p
ublic
String
getFieldAlias
(
FieldNode
field
)
{
p
rivate
String
getFieldAlias
(
FieldNode
field
)
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
String
alias
=
fldMap
.
get
(
fieldInfo
);
if
(
alias
!=
null
)
{
...
...
@@ -393,7 +412,7 @@ public class Deobfuscator {
}
@Nullable
p
ublic
String
getMethodAlias
(
MethodNode
mth
)
{
p
rivate
String
getMethodAlias
(
MethodNode
mth
)
{
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
String
alias
=
mthMap
.
get
(
methodInfo
);
if
(
alias
!=
null
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
View file @
a3b961e7
package
jadx
.
core
.
dex
.
info
;
import
java.io.File
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
java.io.File
;
public
final
class
ClassInfo
{
private
final
ArgType
type
;
...
...
@@ -17,50 +18,50 @@ public final class ClassInfo {
// class info after rename (deobfuscation)
private
ClassInfo
alias
;
private
ClassInfo
(
DexNode
dex
,
ArgType
type
)
{
this
(
dex
,
type
,
true
);
private
ClassInfo
(
RootNode
root
,
ArgType
type
)
{
this
(
root
,
type
,
true
);
}
private
ClassInfo
(
DexNode
dex
,
ArgType
type
,
boolean
inner
)
{
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
;
splitNames
(
dex
,
inner
);
splitNames
(
root
,
inner
);
}
public
static
ClassInfo
fromType
(
DexNode
dex
,
ArgType
type
)
{
public
static
ClassInfo
fromType
(
RootNode
root
,
ArgType
type
)
{
if
(
type
.
isArray
())
{
type
=
ArgType
.
OBJECT
;
}
ClassInfo
cls
=
dex
.
root
()
.
getInfoStorage
().
getCls
(
type
);
ClassInfo
cls
=
root
.
getInfoStorage
().
getCls
(
type
);
if
(
cls
!=
null
)
{
return
cls
;
}
cls
=
new
ClassInfo
(
dex
,
type
);
return
dex
.
root
()
.
getInfoStorage
().
putCls
(
cls
);
cls
=
new
ClassInfo
(
root
,
type
);
return
root
.
getInfoStorage
().
putCls
(
cls
);
}
public
static
ClassInfo
fromDex
(
DexNode
dex
,
int
clsIndex
)
{
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
{
return
null
;
}
return
fromType
(
dex
,
dex
.
getType
(
clsIndex
));
return
fromType
(
dex
.
root
()
,
dex
.
getType
(
clsIndex
));
}
public
static
ClassInfo
fromName
(
DexNode
dex
,
String
clsName
)
{
return
fromType
(
dex
,
ArgType
.
object
(
clsName
));
public
static
ClassInfo
fromName
(
RootNode
root
,
String
clsName
)
{
return
fromType
(
root
,
ArgType
.
object
(
clsName
));
}
public
static
ClassInfo
extCls
(
DexNode
dex
,
ArgType
type
)
{
ClassInfo
classInfo
=
fromName
(
dex
,
type
.
getObject
());
public
static
ClassInfo
extCls
(
RootNode
root
,
ArgType
type
)
{
ClassInfo
classInfo
=
fromName
(
root
,
type
.
getObject
());
return
classInfo
.
alias
;
}
public
void
rename
(
DexNode
dex
,
String
fullName
)
{
ClassInfo
newAlias
=
new
ClassInfo
(
dex
,
ArgType
.
object
(
fullName
),
isInner
());
public
void
rename
(
RootNode
root
,
String
fullName
)
{
ClassInfo
newAlias
=
new
ClassInfo
(
root
,
ArgType
.
object
(
fullName
),
isInner
());
if
(!
alias
.
getFullName
().
equals
(
newAlias
.
getFullName
()))
{
this
.
alias
=
newAlias
;
}
...
...
@@ -74,7 +75,7 @@ public final class ClassInfo {
return
alias
;
}
private
void
splitNames
(
DexNode
dex
,
boolean
canBeInner
)
{
private
void
splitNames
(
RootNode
root
,
boolean
canBeInner
)
{
String
fullObjectName
=
type
.
getObject
();
String
clsName
;
int
dot
=
fullObjectName
.
lastIndexOf
(
'.'
);
...
...
@@ -93,7 +94,7 @@ public final class ClassInfo {
parClsName
=
clsName
.
substring
(
0
,
sep
);
}
parentClass
=
fromName
(
dex
,
parClsName
);
parentClass
=
fromName
(
root
,
parClsName
);
clsName
=
clsName
.
substring
(
sep
+
1
);
}
else
{
parentClass
=
null
;
...
...
@@ -111,10 +112,10 @@ public final class ClassInfo {
}
public
String
getFullPath
()
{
ClassInfo
a
lias
=
getAlias
();
return
a
lias
.
getPackage
().
replace
(
'.'
,
File
.
separatorChar
)
ClassInfo
usedA
lias
=
getAlias
();
return
usedA
lias
.
getPackage
().
replace
(
'.'
,
File
.
separatorChar
)
+
File
.
separatorChar
+
a
lias
.
getNameWithoutPackage
().
replace
(
'.'
,
'_'
);
+
usedA
lias
.
getNameWithoutPackage
().
replace
(
'.'
,
'_'
);
}
public
String
getFullName
()
{
...
...
@@ -160,8 +161,8 @@ public final class ClassInfo {
return
parentClass
!=
null
;
}
public
void
notInner
(
DexNode
dex
)
{
splitNames
(
dex
,
false
);
public
void
notInner
(
RootNode
root
)
{
splitNames
(
root
,
false
);
}
public
ArgType
getType
()
{
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
View file @
a3b961e7
...
...
@@ -65,7 +65,7 @@ public class DexNode implements IDexNode {
ClassNode
parent
=
resolveClass
(
clsInfo
.
getParentClass
());
if
(
parent
==
null
)
{
clsMap
.
remove
(
clsInfo
);
clsInfo
.
notInner
(
cls
.
dex
()
);
clsInfo
.
notInner
(
root
);
clsMap
.
put
(
clsInfo
,
cls
);
}
else
{
parent
.
addInnerClass
(
cls
);
...
...
@@ -78,16 +78,21 @@ public class DexNode implements IDexNode {
}
@Nullable
public
ClassNode
resolveClass
(
ClassInfo
clsInfo
)
{
ClassNode
resolveClassLocal
(
ClassInfo
clsInfo
)
{
return
clsMap
.
get
(
clsInfo
);
}
@Nullable
public
ClassNode
resolveClass
(
ClassInfo
clsInfo
)
{
return
root
.
resolveClass
(
clsInfo
);
}
@Nullable
public
ClassNode
resolveClass
(
@NotNull
ArgType
type
)
{
if
(
type
.
isGeneric
())
{
type
=
ArgType
.
object
(
type
.
getObject
());
}
return
resolveClass
(
ClassInfo
.
fromType
(
this
,
type
));
return
resolveClass
(
ClassInfo
.
fromType
(
root
,
type
));
}
@Nullable
...
...
@@ -99,20 +104,8 @@ public class DexNode implements IDexNode {
return
null
;
}
/**
* Search method in class hierarchy.
*/
@Nullable
public
MethodNode
deepResolveMethod
(
@NotNull
MethodInfo
mth
)
{
ClassNode
cls
=
resolveClass
(
mth
.
getDeclClass
());
if
(
cls
==
null
)
{
return
null
;
}
return
deepResolveMethod
(
cls
,
mth
.
makeSignature
(
false
));
}
@Nullable
private
MethodNode
deepResolveMethod
(
@NotNull
ClassNode
cls
,
String
signature
)
{
MethodNode
deepResolveMethod
(
@NotNull
ClassNode
cls
,
String
signature
)
{
for
(
MethodNode
m
:
cls
.
getMethods
())
{
if
(
m
.
getMethodInfo
().
getShortId
().
startsWith
(
signature
))
{
return
m
;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
View file @
a3b961e7
...
...
@@ -5,6 +5,7 @@ import java.io.InputStream;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -17,6 +18,7 @@ import jadx.core.clsp.ClspGraph;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.ConstStorage
;
import
jadx.core.dex.info.InfoStorage
;
import
jadx.core.dex.info.MethodInfo
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.StringUtils
;
import
jadx.core.utils.android.AndroidResourcesUtils
;
...
...
@@ -144,10 +146,10 @@ public class RootNode {
return
classes
;
}
public
ClassNode
searchClassByName
(
String
fullName
)
{
@Nullable
public
ClassNode
resolveClass
(
ClassInfo
clsInfo
)
{
for
(
DexNode
dexNode
:
dexNodes
)
{
ClassInfo
clsInfo
=
ClassInfo
.
fromName
(
dexNode
,
fullName
);
ClassNode
cls
=
dexNode
.
resolveClass
(
clsInfo
);
ClassNode
cls
=
dexNode
.
resolveClassLocal
(
clsInfo
);
if
(
cls
!=
null
)
{
return
cls
;
}
...
...
@@ -155,6 +157,12 @@ public class RootNode {
return
null
;
}
@Nullable
public
ClassNode
searchClassByName
(
String
fullName
)
{
ClassInfo
clsInfo
=
ClassInfo
.
fromName
(
this
,
fullName
);
return
resolveClass
(
clsInfo
);
}
public
List
<
ClassNode
>
searchClassByShortName
(
String
shortName
)
{
List
<
ClassNode
>
list
=
new
ArrayList
<>();
for
(
DexNode
dexNode
:
dexNodes
)
{
...
...
@@ -167,6 +175,15 @@ public class RootNode {
return
list
;
}
@Nullable
public
MethodNode
deepResolveMethod
(
@NotNull
MethodInfo
mth
)
{
ClassNode
cls
=
resolveClass
(
mth
.
getDeclClass
());
if
(
cls
==
null
)
{
return
null
;
}
return
cls
.
dex
().
deepResolveMethod
(
cls
,
mth
.
makeSignature
(
false
));
}
public
List
<
DexNode
>
getDexNodes
()
{
return
dexNodes
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java
View file @
a3b961e7
...
...
@@ -63,7 +63,7 @@ public class ClassModifier extends AbstractVisitor {
// remove fields if it is synthetic and type is a outer class
for
(
FieldNode
field
:
cls
.
getFields
())
{
if
(
field
.
getAccessFlags
().
isSynthetic
()
&&
field
.
getType
().
isObject
())
{
ClassInfo
clsInfo
=
ClassInfo
.
fromType
(
cls
.
dex
(),
field
.
getType
());
ClassInfo
clsInfo
=
ClassInfo
.
fromType
(
cls
.
root
(),
field
.
getType
());
ClassNode
fieldsCls
=
cls
.
dex
().
resolveClass
(
clsInfo
);
ClassInfo
parentClass
=
cls
.
getClassInfo
().
getParentClass
();
if
(
fieldsCls
!=
null
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java
View file @
a3b961e7
...
...
@@ -96,7 +96,7 @@ 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
.
fromName
(
dex
,
type
.
getObject
()));
addDep
(
dex
,
depList
,
ClassInfo
.
fromName
(
dex
.
root
()
,
type
.
getObject
()));
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 @
a3b961e7
...
...
@@ -71,7 +71,7 @@ public class RenameVisitor extends AbstractVisitor {
if
(!
clsNames
.
add
(
clsFileName
.
toLowerCase
()))
{
String
newShortName
=
deobfuscator
.
getClsAlias
(
cls
);
String
newFullName
=
classInfo
.
makeFullClsName
(
newShortName
,
true
);
classInfo
.
rename
(
cls
.
dex
(),
newFullName
);
classInfo
.
rename
(
cls
.
root
(),
newFullName
);
clsNames
.
add
(
classInfo
.
getAlias
().
getFullPath
().
toLowerCase
());
}
}
...
...
@@ -89,12 +89,12 @@ public class RenameVisitor extends AbstractVisitor {
newShortName
=
"C"
+
clsName
;
}
if
(
newShortName
!=
null
)
{
classInfo
.
rename
(
cls
.
dex
(),
classInfo
.
makeFullClsName
(
newShortName
,
true
));
classInfo
.
rename
(
cls
.
root
(),
classInfo
.
makeFullClsName
(
newShortName
,
true
));
}
if
(
classInfo
.
getAlias
().
getPackage
().
isEmpty
())
{
String
fullName
=
classInfo
.
makeFullClsName
(
classInfo
.
getAlias
().
getShortName
(),
true
);
String
newFullName
=
Consts
.
DEFAULT_PACKAGE_NAME
+
"."
+
fullName
;
classInfo
.
rename
(
cls
.
dex
(),
newFullName
);
classInfo
.
rename
(
cls
.
root
(),
newFullName
);
}
}
...
...
@@ -103,7 +103,7 @@ public class RenameVisitor extends AbstractVisitor {
for
(
FieldNode
field
:
cls
.
getFields
())
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
if
(!
names
.
add
(
fieldInfo
.
getAlias
()))
{
fieldInfo
.
setAlias
(
deobfuscator
.
makeFieldAlias
(
field
)
);
deobfuscator
.
renameField
(
field
);
}
}
}
...
...
@@ -114,22 +114,10 @@ public class RenameVisitor extends AbstractVisitor {
if
(
mth
.
contains
(
AFlag
.
DONT_GENERATE
))
{
continue
;
}
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
String
signature
=
makeMethodSignature
(
methodInfo
);
String
signature
=
mth
.
getMethodInfo
().
makeSignature
(
false
);
if
(!
names
.
add
(
signature
))
{
methodInfo
.
setAlias
(
deobfuscator
.
makeMethodAlias
(
mth
)
);
deobfuscator
.
renameMethod
(
mth
);
}
}
}
private
static
String
makeMethodSignature
(
MethodInfo
methodInfo
)
{
StringBuilder
signature
=
new
StringBuilder
();
signature
.
append
(
methodInfo
.
getAlias
());
signature
.
append
(
'('
);
for
(
ArgType
arg
:
methodInfo
.
getArgumentsTypes
())
{
signature
.
append
(
TypeGen
.
signature
(
arg
));
}
signature
.
append
(
')'
);
return
signature
.
toString
();
}
}
jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java
View file @
a3b961e7
...
...
@@ -55,8 +55,7 @@ public class AndroidResourcesUtils {
if
(
dexNodes
.
isEmpty
())
{
return
null
;
}
DexNode
firstDex
=
dexNodes
.
get
(
0
);
ClassInfo
r
=
ClassInfo
.
fromName
(
firstDex
,
clsName
);
return
new
ClassNode
(
firstDex
,
r
);
ClassInfo
r
=
ClassInfo
.
fromName
(
root
,
clsName
);
return
new
ClassNode
(
dexNodes
.
get
(
0
),
r
);
}
}
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
View file @
a3b961e7
...
...
@@ -8,6 +8,8 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.attribute.FileAttribute
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.List
;
...
...
@@ -74,6 +76,16 @@ public class FileUtils {
return
temp
;
}
public
static
File
createTempDir
(
String
suffix
)
{
try
{
Path
path
=
Files
.
createTempDirectory
(
"jadx-tmp-"
+
System
.
nanoTime
()
+
"-"
+
suffix
);
path
.
toFile
().
deleteOnExit
();
return
path
.
toFile
();
}
catch
(
IOException
e
)
{
throw
new
JadxRuntimeException
(
"Failed to create temp directory with suffix: "
+
suffix
);
}
}
public
static
void
copyStream
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[
READ_BUFFER_SIZE
];
while
(
true
)
{
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
View file @
a3b961e7
...
...
@@ -48,7 +48,7 @@ public abstract class IntegrationTest extends TestUtils {
private
static
final
String
TEST_DIRECTORY
=
"src/test/java"
;
private
static
final
String
TEST_DIRECTORY2
=
"jadx-core/"
+
TEST_DIRECTORY
;
pr
ivate
JadxArgs
args
;
pr
otected
JadxArgs
args
;
protected
boolean
deleteTmpFiles
=
true
;
protected
boolean
withDebugInfo
=
true
;
...
...
@@ -113,27 +113,31 @@ public abstract class IntegrationTest extends TestUtils {
return
cls
;
}
pr
ivate
void
decompile
(
JadxDecompiler
jadx
,
ClassNode
cls
)
{
pr
otected
void
decompile
(
JadxDecompiler
jadx
,
ClassNode
cls
)
{
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
jadx
.
getArgs
());
ProcessClass
.
process
(
cls
,
passes
,
new
CodeGen
());
}
pr
ivate
void
decompileWithoutUnload
(
JadxDecompiler
d
,
ClassNode
cls
)
{
pr
otected
void
decompileWithoutUnload
(
JadxDecompiler
d
,
ClassNode
cls
)
{
cls
.
load
();
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
d
.
getArgs
());
for
(
IDexTreeVisitor
visitor
:
passes
)
{
DepthTraversal
.
visit
(
visitor
,
cls
);
}
generateClsCode
(
cls
);
// don't unload class
}
protected
void
generateClsCode
(
ClassNode
cls
)
{
try
{
new
CodeGen
().
visit
(
cls
);
}
catch
(
Codegen
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
// don't unload class
}
pr
ivate
static
void
checkCode
(
ClassNode
cls
)
{
pr
otected
static
void
checkCode
(
ClassNode
cls
)
{
assertTrue
(
"Inconsistent cls: "
+
cls
,
!
cls
.
contains
(
AFlag
.
INCONSISTENT_CODE
)
&&
!
cls
.
contains
(
AType
.
JADX_ERROR
));
for
(
MethodNode
mthNode
:
cls
.
getMethods
())
{
...
...
@@ -370,6 +374,13 @@ public abstract class IntegrationTest extends TestUtils {
this
.
unloadCls
=
false
;
}
protected
void
enableDeobfuscation
()
{
args
.
setDeobfuscationOn
(
true
);
args
.
setDeobfuscationForceSave
(
true
);
args
.
setDeobfuscationMinLength
(
2
);
args
.
setDeobfuscationMaxLength
(
64
);
}
// Use only for debug purpose
@Deprecated
protected
void
setOutputCFG
()
{
...
...
jadx-core/src/test/java/jadx/tests/integration/deobf/TestMthRename.java
0 → 100644
View file @
a3b961e7
package
jadx
.
tests
.
integration
.
deobf
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestMthRename
extends
IntegrationTest
{
public
static
class
TestCls
{
public
static
abstract
class
TestAbstractCls
{
public
abstract
void
a
();
}
public
void
test
(
TestAbstractCls
a
)
{
a
.
a
();
}
}
@Test
public
void
test
()
{
noDebugInfo
();
enableDeobfuscation
();
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsString
(
"public abstract void m0a();"
));
assertThat
(
code
,
not
(
containsString
(
"public abstract void a();"
)));
assertThat
(
code
,
containsString
(
".m0a();"
));
assertThat
(
code
,
not
(
containsString
(
".a();"
)));
}
}
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