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
3314de8d
Commit
3314de8d
authored
Mar 24, 2015
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: rename fields and methods in deobfuscation pass.
parent
8dab9b83
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
500 additions
and
203 deletions
+500
-203
JavaField.java
jadx-core/src/main/java/jadx/api/JavaField.java
+2
-2
JavaMethod.java
jadx-core/src/main/java/jadx/api/JavaMethod.java
+1
-1
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+1
-3
ProcessClass.java
jadx-core/src/main/java/jadx/core/ProcessClass.java
+0
-4
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
+3
-3
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+1
-1
RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+1
-1
DeobfClsInfo.java
jadx-core/src/main/java/jadx/core/deobf/DeobfClsInfo.java
+50
-0
DeobfPresets.java
jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
+167
-0
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+143
-164
NameMapper.java
jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
+5
-4
PackageNode.java
jadx-core/src/main/java/jadx/core/deobf/PackageNode.java
+4
-4
FieldInfo.java
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
+19
-0
MethodInfo.java
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
+14
-0
FieldNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
+4
-0
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+4
-0
DependencyCollector.java
...main/java/jadx/core/dex/visitors/DependencyCollector.java
+21
-4
RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+59
-11
No files found.
jadx-core/src/main/java/jadx/api/JavaField.java
View file @
3314de8d
...
...
@@ -16,12 +16,12 @@ public final class JavaField implements JavaNode {
@Override
public
String
getName
()
{
return
field
.
get
Name
();
return
field
.
get
Alias
();
}
@Override
public
String
getFullName
()
{
return
parent
.
getFullName
()
+
"."
+
field
.
getName
();
return
parent
.
getFullName
()
+
"."
+
getName
();
}
@Override
...
...
jadx-core/src/main/java/jadx/api/JavaMethod.java
View file @
3314de8d
...
...
@@ -17,7 +17,7 @@ public final class JavaMethod implements JavaNode {
@Override
public
String
getName
()
{
return
mth
.
get
Name
();
return
mth
.
get
Alias
();
}
@Override
...
...
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
3314de8d
...
...
@@ -108,9 +108,7 @@ public class Jadx {
passes
.
add
(
new
DependencyCollector
());
if
(
args
.
isDeobfuscationOn
())
{
passes
.
add
(
new
RenameVisitor
());
}
passes
.
add
(
new
RenameVisitor
());
}
return
passes
;
}
...
...
jadx-core/src/main/java/jadx/core/ProcessClass.java
View file @
3314de8d
...
...
@@ -53,10 +53,6 @@ public final class ProcessClass {
static
void
processDependencies
(
ClassNode
cls
,
List
<
IDexTreeVisitor
>
passes
)
{
for
(
ClassNode
depCls
:
cls
.
getDependencies
())
{
if
(
cls
.
getTopParentClass
()
==
cls
)
{
// ignore inner classes of this class
continue
;
}
process
(
depCls
,
passes
,
null
);
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
3314de8d
...
...
@@ -337,7 +337,7 @@ public class ClassGen {
code
.
startLine
(
f
.
getAccessFlags
().
makeString
());
useType
(
code
,
f
.
getType
());
code
.
add
(
' '
);
code
.
add
(
f
.
get
Name
());
code
.
add
(
f
.
get
Alias
());
FieldValueAttr
fv
=
f
.
get
(
AType
.
FIELD_VALUE
);
if
(
fv
!=
null
)
{
code
.
add
(
" = "
);
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
3314de8d
...
...
@@ -157,7 +157,7 @@ public class InsnGen {
if
(
fieldNode
!=
null
)
{
code
.
attachAnnotation
(
fieldNode
);
}
code
.
add
(
field
.
get
Name
());
code
.
add
(
field
.
get
Alias
());
}
public
static
void
makeStaticFieldAccess
(
CodeWriter
code
,
FieldInfo
field
,
ClassGen
clsGen
)
{
...
...
@@ -179,7 +179,7 @@ public class InsnGen {
if
(
fieldNode
!=
null
)
{
code
.
attachAnnotation
(
fieldNode
);
}
code
.
add
(
field
.
get
Name
());
code
.
add
(
field
.
get
Alias
());
}
protected
void
staticField
(
CodeWriter
code
,
FieldInfo
field
)
{
...
...
@@ -612,7 +612,7 @@ public class InsnGen {
if
(
callMthNode
!=
null
)
{
code
.
attachAnnotation
(
callMthNode
);
}
code
.
add
(
callMth
.
get
Name
());
code
.
add
(
callMth
.
get
Alias
());
generateMethodArguments
(
code
,
insn
,
k
,
callMthNode
);
}
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
3314de8d
...
...
@@ -90,7 +90,7 @@ public class MethodGen {
}
else
{
classGen
.
useType
(
code
,
mth
.
getReturnType
());
code
.
add
(
' '
);
code
.
add
(
mth
.
get
Name
());
code
.
add
(
mth
.
get
Alias
());
}
code
.
add
(
'('
);
...
...
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
View file @
3314de8d
...
...
@@ -245,7 +245,7 @@ public class RegionGen extends InsnGen {
if
(
k
instanceof
FieldNode
)
{
FieldNode
fn
=
(
FieldNode
)
k
;
if
(
fn
.
getParentClass
().
isEnum
())
{
code
.
add
(
fn
.
get
Name
());
code
.
add
(
fn
.
get
Alias
());
}
else
{
staticField
(
code
,
fn
.
getFieldInfo
());
// print original value, sometimes replace with incorrect field
...
...
jadx-core/src/main/java/jadx/core/deobf/DeobfClsInfo.java
0 → 100644
View file @
3314de8d
package
jadx
.
core
.
deobf
;
import
jadx.core.dex.nodes.ClassNode
;
class
DeobfClsInfo
{
private
final
Deobfuscator
deobfuscator
;
private
final
ClassNode
cls
;
private
final
PackageNode
pkg
;
private
final
String
alias
;
public
DeobfClsInfo
(
Deobfuscator
deobfuscator
,
ClassNode
cls
,
PackageNode
pkg
,
String
alias
)
{
this
.
deobfuscator
=
deobfuscator
;
this
.
cls
=
cls
;
this
.
pkg
=
pkg
;
this
.
alias
=
alias
;
}
public
String
makeNameWithoutPkg
()
{
String
prefix
;
ClassNode
parentClass
=
cls
.
getParentClass
();
if
(
parentClass
!=
cls
)
{
DeobfClsInfo
parentDeobfClsInfo
=
deobfuscator
.
getClsMap
().
get
(
parentClass
.
getClassInfo
());
if
(
parentDeobfClsInfo
!=
null
)
{
prefix
=
parentDeobfClsInfo
.
makeNameWithoutPkg
();
}
else
{
prefix
=
deobfuscator
.
getNameWithoutPackage
(
parentClass
.
getClassInfo
());
}
prefix
+=
Deobfuscator
.
INNER_CLASS_SEPARATOR
;
}
else
{
prefix
=
""
;
}
return
prefix
+
(
this
.
alias
!=
null
?
this
.
alias
:
this
.
cls
.
getShortName
());
}
public
String
getFullName
()
{
return
pkg
.
getFullAlias
()
+
Deobfuscator
.
CLASS_NAME_SEPARATOR
+
makeNameWithoutPkg
();
}
public
ClassNode
getCls
()
{
return
cls
;
}
public
PackageNode
getPkg
()
{
return
pkg
;
}
public
String
getAlias
()
{
return
alias
;
}
}
jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
0 → 100644
View file @
3314de8d
package
jadx
.
core
.
deobf
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.info.MethodInfo
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.apache.commons.io.FileUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
class
DeobfPresets
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DeobfPresets
.
class
);
private
static
final
String
MAP_FILE_CHARSET
=
"UTF-8"
;
private
final
Deobfuscator
deobfuscator
;
private
final
File
deobfMapFile
;
private
final
Map
<
String
,
String
>
clsPresetMap
=
new
HashMap
<
String
,
String
>();
private
final
Map
<
String
,
String
>
fldPresetMap
=
new
HashMap
<
String
,
String
>();
private
final
Map
<
String
,
String
>
mthPresetMap
=
new
HashMap
<
String
,
String
>();
public
DeobfPresets
(
Deobfuscator
deobfuscator
,
File
deobfMapFile
)
{
this
.
deobfuscator
=
deobfuscator
;
this
.
deobfMapFile
=
deobfMapFile
;
}
/**
* Loads deobfuscator presets
*/
public
void
load
()
{
if
(!
deobfMapFile
.
exists
())
{
return
;
}
LOG
.
info
(
"Loading obfuscation map from: {}"
,
deobfMapFile
.
getAbsoluteFile
());
try
{
List
<
String
>
lines
=
FileUtils
.
readLines
(
deobfMapFile
,
MAP_FILE_CHARSET
);
for
(
String
l
:
lines
)
{
l
=
l
.
trim
();
if
(
l
.
isEmpty
()
||
l
.
startsWith
(
"#"
))
{
continue
;
}
String
[]
va
=
splitAndTrim
(
l
);
if
(
va
.
length
!=
2
)
{
continue
;
}
String
origName
=
va
[
0
];
String
alias
=
va
[
1
];
if
(
l
.
startsWith
(
"p "
))
{
deobfuscator
.
addPackagePreset
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"c "
))
{
clsPresetMap
.
put
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"f "
))
{
fldPresetMap
.
put
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"m "
))
{
mthPresetMap
.
put
(
origName
,
alias
);
}
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
getAbsolutePath
(),
e
);
}
}
private
static
String
[]
splitAndTrim
(
String
str
)
{
String
[]
v
=
str
.
substring
(
2
).
split
(
"="
);
for
(
int
i
=
0
;
i
<
v
.
length
;
i
++)
{
v
[
i
]
=
v
[
i
].
trim
();
}
return
v
;
}
public
void
save
(
boolean
forceSave
)
{
try
{
if
(
deobfMapFile
.
exists
())
{
if
(
forceSave
)
{
dumpMapping
();
}
else
{
LOG
.
warn
(
"Deobfuscation map file '{}' exists. Use command line option '--deobf-rewrite-cfg' to rewrite it"
,
deobfMapFile
.
getAbsolutePath
());
}
}
else
{
dumpMapping
();
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
getAbsolutePath
(),
e
);
}
}
/**
* Saves DefaultDeobfuscator presets
*/
private
void
dumpMapping
()
throws
IOException
{
List
<
String
>
list
=
new
ArrayList
<
String
>();
// packages
for
(
PackageNode
p
:
deobfuscator
.
getRootPackage
().
getInnerPackages
())
{
for
(
PackageNode
pp
:
p
.
getInnerPackages
())
{
dfsPackageName
(
list
,
p
.
getName
(),
pp
);
}
if
(
p
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s = %s"
,
p
.
getName
(),
p
.
getAlias
()));
}
}
// classes
for
(
DeobfClsInfo
deobfClsInfo
:
deobfuscator
.
getClsMap
().
values
())
{
if
(
deobfClsInfo
.
getAlias
()
!=
null
)
{
list
.
add
(
String
.
format
(
"c %s = %s"
,
deobfClsInfo
.
getCls
().
getClassInfo
().
getFullName
(),
deobfClsInfo
.
getAlias
()));
}
}
for
(
FieldInfo
fld
:
deobfuscator
.
getFldMap
().
keySet
())
{
list
.
add
(
String
.
format
(
"f %s = %s"
,
fld
.
getFullId
(),
fld
.
getAlias
()));
}
for
(
MethodInfo
mth
:
deobfuscator
.
getMthMap
().
keySet
())
{
list
.
add
(
String
.
format
(
"m %s = %s"
,
mth
.
getFullId
(),
mth
.
getAlias
()));
}
Collections
.
sort
(
list
);
FileUtils
.
writeLines
(
deobfMapFile
,
MAP_FILE_CHARSET
,
list
);
list
.
clear
();
}
private
static
void
dfsPackageName
(
List
<
String
>
list
,
String
prefix
,
PackageNode
node
)
{
for
(
PackageNode
pp
:
node
.
getInnerPackages
())
{
dfsPackageName
(
list
,
prefix
+
'.'
+
node
.
getName
(),
pp
);
}
if
(
node
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s.%s = %s"
,
prefix
,
node
.
getName
(),
node
.
getAlias
()));
}
}
public
String
getForCls
(
ClassInfo
cls
)
{
return
clsPresetMap
.
get
(
cls
.
getFullName
());
}
public
String
getForFld
(
FieldInfo
fld
)
{
return
fldPresetMap
.
get
(
fld
.
getFullId
());
}
public
String
getForMth
(
MethodInfo
mth
)
{
return
mthPresetMap
.
get
(
mth
.
getFullId
());
}
public
void
clear
()
{
clsPresetMap
.
clear
();
fldPresetMap
.
clear
();
mthPresetMap
.
clear
();
}
public
Map
<
String
,
String
>
getClsPresetMap
()
{
return
clsPresetMap
;
}
public
Map
<
String
,
String
>
getFldPresetMap
()
{
return
fldPresetMap
;
}
public
Map
<
String
,
String
>
getMthPresetMap
()
{
return
mthPresetMap
;
}
}
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
View file @
3314de8d
...
...
@@ -4,21 +4,22 @@ import jadx.api.IJadxArgs;
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.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.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.TreeSet
;
import
org.apache.commons.io.FileUtils
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -27,56 +28,60 @@ public class Deobfuscator {
private
static
final
boolean
DEBUG
=
false
;
private
static
final
String
MAP_FILE_CHARSET
=
"UTF-8"
;
private
static
final
String
CLASS_NAME_SEPARATOR
=
"."
;
private
static
final
String
INNER_CLASS_SEPARATOR
=
"$"
;
public
static
final
String
CLASS_NAME_SEPARATOR
=
"."
;
public
static
final
String
INNER_CLASS_SEPARATOR
=
"$"
;
private
final
Map
<
ClassInfo
,
DeobfClsInfo
>
clsMap
=
new
HashMap
<
ClassInfo
,
DeobfClsInfo
>();
private
final
IJadxArgs
args
;
private
final
File
deobfMapFile
;
@NotNull
private
final
List
<
DexNode
>
dexNodes
;
private
final
DeobfPresets
deobfPresets
;
private
final
Map
<
ClassInfo
,
DeobfClsInfo
>
clsMap
=
new
HashMap
<
ClassInfo
,
DeobfClsInfo
>();
private
final
Map
<
FieldInfo
,
String
>
fldMap
=
new
HashMap
<
FieldInfo
,
String
>();
private
final
Map
<
MethodInfo
,
String
>
mthMap
=
new
HashMap
<
MethodInfo
,
String
>();
private
final
PackageNode
rootPackage
=
new
PackageNode
(
""
);
private
final
Set
<
String
>
pkgSet
=
new
TreeSet
<
String
>();
private
final
int
maxLength
;
private
final
int
minLength
;
private
int
pkgIndex
=
0
;
private
int
clsIndex
=
0
;
private
final
PackageNode
rootPackage
=
new
PackageNode
(
""
);
private
final
Set
<
String
>
pkgSet
=
new
TreeSet
<
String
>();
private
Map
<
String
,
String
>
preLoadClsMap
=
Collections
.
emptyMap
();
private
int
fldIndex
=
0
;
private
int
mthIndex
=
0
;
public
Deobfuscator
(
IJadxArgs
args
,
@NotNull
List
<
DexNode
>
dexNodes
,
File
deobfMapFile
)
{
this
.
args
=
args
;
this
.
dexNodes
=
dexNodes
;
this
.
deobfMapFile
=
deobfMapFile
;
this
.
minLength
=
args
.
getDeobfuscationMinLength
();
this
.
maxLength
=
args
.
getDeobfuscationMaxLength
();
this
.
deobfPresets
=
new
DeobfPresets
(
this
,
deobfMapFile
);
}
public
void
execute
()
{
if
(
deobfMapFile
.
exists
()
&&
!
args
.
isDeobfuscationForceSave
())
{
try
{
load
();
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
getAbsolutePath
(),
e
);
}
if
(!
args
.
isDeobfuscationForceSave
())
{
deobfPresets
.
load
();
initIndexes
();
}
process
();
try
{
if
(
deobfMapFile
.
exists
())
{
if
(
args
.
isDeobfuscationForceSave
())
{
save
();
}
else
{
LOG
.
warn
(
"Deobfuscation map file '{}' exists. Use command line option '--deobf-rewrite-cfg' to rewrite it"
,
deobfMapFile
.
getAbsolutePath
());
}
}
else
{
save
();
deobfPresets
.
save
(
args
.
isDeobfuscationForceSave
());
clear
();
}
private
void
initIndexes
()
{
pkgIndex
=
pkgSet
.
size
();
clsIndex
=
deobfPresets
.
getClsPresetMap
().
size
();
fldIndex
=
deobfPresets
.
getFldPresetMap
().
size
();
mthIndex
=
deobfPresets
.
getMthPresetMap
().
size
();
}
private
void
preProcess
()
{
for
(
DexNode
dexNode
:
dexNodes
)
{
for
(
ClassNode
cls
:
dexNode
.
getClasses
())
{
doClass
(
cls
);
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
getAbsolutePath
(),
e
);
}
}
...
...
@@ -85,20 +90,47 @@ public class Deobfuscator {
if
(
DEBUG
)
{
dumpAlias
();
}
preLoadClsMap
.
clear
();
preLoadClsMap
=
Collections
.
emptyMap
();
for
(
DexNode
dexNode
:
dexNodes
)
{
for
(
ClassNode
classNode
:
dexNode
.
getClasses
())
{
ClassInfo
clsInfo
=
classNode
.
getClassInfo
();
String
fullName
=
getClassFullName
(
clsInfo
);
if
(!
fullName
.
equals
(
clsInfo
.
getFullName
()))
{
clsInfo
.
rename
(
dexNode
,
fullName
);
}
for
(
ClassNode
cls
:
dexNode
.
getClasses
())
{
processClass
(
dexNode
,
cls
);
}
}
}
void
clear
()
{
deobfPresets
.
clear
();
clsMap
.
clear
();
fldMap
.
clear
();
mthMap
.
clear
();
}
private
void
processClass
(
DexNode
dex
,
ClassNode
cls
)
{
ClassInfo
clsInfo
=
cls
.
getClassInfo
();
String
fullName
=
getClassFullName
(
clsInfo
);
if
(!
fullName
.
equals
(
clsInfo
.
getFullName
()))
{
clsInfo
.
rename
(
dex
,
fullName
);
}
for
(
FieldNode
field
:
cls
.
getFields
())
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
String
alias
=
getFieldAlias
(
field
);
if
(
alias
!=
null
)
{
fieldInfo
.
setAlias
(
alias
);
}
}
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
String
alias
=
getMethodAlias
(
mth
);
if
(
alias
!=
null
)
{
methodInfo
.
setAlias
(
alias
);
}
}
}
public
void
addPackagePreset
(
String
origPkgName
,
String
pkgAlias
)
{
PackageNode
pkg
=
getPackageNode
(
origPkgName
,
true
);
pkg
.
setAlias
(
pkgAlias
);
}
/**
* Gets package node for full package name
*
...
...
@@ -134,41 +166,7 @@ public class Deobfuscator {
return
result
;
}
private
final
class
DeobfClsInfo
{
public
final
ClassNode
cls
;
public
final
PackageNode
pkg
;
public
final
String
alias
;
public
DeobfClsInfo
(
ClassNode
cls
,
PackageNode
pkg
,
String
alias
)
{
this
.
cls
=
cls
;
this
.
pkg
=
pkg
;
this
.
alias
=
alias
;
}
public
String
makeNameWithoutPkg
()
{
String
prefix
;
ClassNode
parentClass
=
cls
.
getParentClass
();
if
(
parentClass
!=
cls
)
{
DeobfClsInfo
parentDeobfClsInfo
=
clsMap
.
get
(
parentClass
.
getClassInfo
());
if
(
parentDeobfClsInfo
!=
null
)
{
prefix
=
parentDeobfClsInfo
.
makeNameWithoutPkg
();
}
else
{
prefix
=
getNameWithoutPackage
(
parentClass
.
getClassInfo
());
}
prefix
+=
INNER_CLASS_SEPARATOR
;
}
else
{
prefix
=
""
;
}
return
prefix
+
(
this
.
alias
!=
null
?
this
.
alias
:
this
.
cls
.
getShortName
());
}
public
String
getFullName
()
{
return
pkg
.
getFullAlias
()
+
CLASS_NAME_SEPARATOR
+
makeNameWithoutPkg
();
}
}
private
String
getNameWithoutPackage
(
ClassInfo
clsInfo
)
{
String
getNameWithoutPackage
(
ClassInfo
clsInfo
)
{
String
prefix
;
ClassInfo
parentClsInfo
=
clsInfo
.
getParentClass
();
if
(
parentClsInfo
!=
null
)
{
...
...
@@ -191,18 +189,17 @@ public class Deobfuscator {
PackageNode
pkg
=
getPackageNode
(
pkgFullName
,
true
);
doPkg
(
pkg
,
pkgFullName
);
String
fullName
=
classInfo
.
getFullName
();
if
(
preLoadClsMap
.
containsKey
(
fullName
))
{
String
alias
=
preLoadClsMap
.
get
(
fullName
);
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
cls
,
pkg
,
alias
));
String
alias
=
deobfPresets
.
getForCls
(
classInfo
);
if
(
alias
!=
null
)
{
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
this
,
cls
,
pkg
,
alias
));
return
;
}
if
(
clsMap
.
containsKey
(
classInfo
))
{
return
;
}
if
(
shouldRename
(
classInfo
.
getShortName
()))
{
String
alias
=
makeClsAlias
(
cls
);
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
cls
,
pkg
,
alias
));
alias
=
makeClsAlias
(
cls
);
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
this
,
cls
,
pkg
,
alias
));
}
}
...
...
@@ -224,6 +221,54 @@ public class Deobfuscator {
return
String
.
format
(
"C%04d%s"
,
clsIndex
++,
makeName
(
clsName
));
}
@Nullable
public
String
getFieldAlias
(
FieldNode
field
)
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
String
alias
=
fldMap
.
get
(
fieldInfo
);
if
(
alias
!=
null
)
{
return
alias
;
}
alias
=
deobfPresets
.
getForFld
(
fieldInfo
);
if
(
alias
!=
null
)
{
fldMap
.
put
(
fieldInfo
,
alias
);
return
alias
;
}
if
(
shouldRename
(
field
.
getName
()))
{
return
makeFieldAlias
(
field
);
}
return
null
;
}
@Nullable
public
String
getMethodAlias
(
MethodNode
mth
)
{
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
String
alias
=
mthMap
.
get
(
methodInfo
);
if
(
alias
!=
null
)
{
return
alias
;
}
alias
=
deobfPresets
.
getForMth
(
methodInfo
);
if
(
alias
!=
null
)
{
mthMap
.
put
(
methodInfo
,
alias
);
return
alias
;
}
if
(
shouldRename
(
mth
.
getName
()))
{
return
makeMethodAlias
(
mth
);
}
return
null
;
}
public
String
makeFieldAlias
(
FieldNode
field
)
{
String
alias
=
String
.
format
(
"f%d%s"
,
fldIndex
++,
makeName
(
field
.
getName
()));
fldMap
.
put
(
field
.
getFieldInfo
(),
alias
);
return
alias
;
}
public
String
makeMethodAlias
(
MethodNode
mth
)
{
String
alias
=
String
.
format
(
"m%d%s"
,
mthIndex
++,
makeName
(
mth
.
getName
()));
mthMap
.
put
(
mth
.
getMethodInfo
(),
alias
);
return
alias
;
}
private
void
doPkg
(
PackageNode
pkg
,
String
fullName
)
{
if
(
pkgSet
.
contains
(
fullName
))
{
return
;
...
...
@@ -246,14 +291,6 @@ public class Deobfuscator {
}
}
private
void
preProcess
()
{
for
(
DexNode
dexNode
:
dexNodes
)
{
for
(
ClassNode
cls
:
dexNode
.
getClasses
())
{
doClass
(
cls
);
}
}
}
private
boolean
shouldRename
(
String
s
)
{
return
s
.
length
()
>
maxLength
||
s
.
length
()
<
minLength
...
...
@@ -305,80 +342,6 @@ public class Deobfuscator {
}
}
/**
* Loads deobfuscator presets
*
* @throws IOException
*/
private
void
load
()
throws
IOException
{
if
(!
deobfMapFile
.
exists
())
{
return
;
}
LOG
.
info
(
"Loading obfuscation map from: {}"
,
deobfMapFile
.
getAbsoluteFile
());
List
<
String
>
lines
=
FileUtils
.
readLines
(
deobfMapFile
,
MAP_FILE_CHARSET
);
for
(
String
l
:
lines
)
{
l
=
l
.
trim
();
if
(
l
.
startsWith
(
"p "
))
{
String
[]
va
=
splitAndTrim
(
l
);
if
(
va
.
length
==
2
)
{
PackageNode
pkg
=
getPackageNode
(
va
[
0
],
true
);
pkg
.
setAlias
(
va
[
1
]);
}
}
else
if
(
l
.
startsWith
(
"c "
))
{
String
[]
va
=
splitAndTrim
(
l
);
if
(
va
.
length
==
2
)
{
if
(
preLoadClsMap
.
isEmpty
())
{
preLoadClsMap
=
new
HashMap
<
String
,
String
>();
}
preLoadClsMap
.
put
(
va
[
0
],
va
[
1
]);
}
}
}
}
private
static
String
[]
splitAndTrim
(
String
str
)
{
String
[]
v
=
str
.
substring
(
2
).
split
(
"="
);
for
(
int
i
=
0
;
i
<
v
.
length
;
i
++)
{
v
[
i
]
=
v
[
i
].
trim
();
}
return
v
;
}
private
static
void
dfsPackageName
(
List
<
String
>
list
,
String
prefix
,
PackageNode
node
)
{
for
(
PackageNode
pp
:
node
.
getInnerPackages
())
{
dfsPackageName
(
list
,
prefix
+
'.'
+
node
.
getName
(),
pp
);
}
if
(
node
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s.%s=%s"
,
prefix
,
node
.
getName
(),
node
.
getAlias
()));
}
}
/**
* Saves DefaultDeobfuscator presets
*/
private
void
save
()
throws
IOException
{
List
<
String
>
list
=
new
ArrayList
<
String
>();
// packages
for
(
PackageNode
p
:
rootPackage
.
getInnerPackages
())
{
for
(
PackageNode
pp
:
p
.
getInnerPackages
())
{
dfsPackageName
(
list
,
p
.
getName
(),
pp
);
}
if
(
p
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s=%s"
,
p
.
getName
(),
p
.
getAlias
()));
}
}
// classes
for
(
DeobfClsInfo
deobfClsInfo
:
clsMap
.
values
())
{
if
(
deobfClsInfo
.
alias
!=
null
)
{
list
.
add
(
String
.
format
(
"c %s=%s"
,
deobfClsInfo
.
cls
.
getClassInfo
().
getFullName
(),
deobfClsInfo
.
alias
));
}
}
Collections
.
sort
(
list
);
FileUtils
.
writeLines
(
deobfMapFile
,
MAP_FILE_CHARSET
,
list
);
list
.
clear
();
}
private
String
getPackageName
(
String
packageName
)
{
final
PackageNode
pkg
=
getPackageNode
(
packageName
,
false
);
if
(
pkg
!=
null
)
{
...
...
@@ -406,4 +369,20 @@ public class Deobfuscator {
}
return
getPackageName
(
clsInfo
.
getPackage
())
+
CLASS_NAME_SEPARATOR
+
getClassName
(
clsInfo
);
}
public
Map
<
ClassInfo
,
DeobfClsInfo
>
getClsMap
()
{
return
clsMap
;
}
public
Map
<
FieldInfo
,
String
>
getFldMap
()
{
return
fldMap
;
}
public
Map
<
MethodInfo
,
String
>
getMthMap
()
{
return
mthMap
;
}
public
PackageNode
getRootPackage
()
{
return
rootPackage
;
}
}
jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
View file @
3314de8d
...
...
@@ -88,10 +88,11 @@ public class NameMapper {
}
public
static
boolean
isAllCharsPrintable
(
String
str
)
{
for
(
int
i
=
0
;
i
<
str
.
length
();
i
++)
{
if
(!
isPrintableChar
(
str
.
charAt
(
i
)))
{
return
false
;
}
int
len
=
str
.
length
();
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
if
(!
isPrintableChar
(
str
.
charAt
(
i
)))
{
return
false
;
}
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/deobf/PackageNode.java
View file @
3314de8d
...
...
@@ -7,11 +7,11 @@ import java.util.Stack;
public
class
PackageNode
{
private
static
final
char
SEPARATOR_CHAR
=
'.'
;
private
PackageNode
parentPackage
;
private
List
<
PackageNode
>
innerPackages
=
Collections
.
emptyList
();
private
static
final
char
separatorChar
=
'.'
;
private
final
String
packageName
;
private
String
packageAlias
;
...
...
@@ -34,7 +34,7 @@ public class PackageNode {
StringBuilder
result
=
new
StringBuilder
();
result
.
append
(
pp
.
pop
().
getName
());
while
(
pp
.
size
()
>
0
)
{
result
.
append
(
separatorChar
);
result
.
append
(
SEPARATOR_CHAR
);
result
.
append
(
pp
.
pop
().
getName
());
}
cachedPackageFullName
=
result
.
toString
();
...
...
@@ -63,7 +63,7 @@ public class PackageNode {
StringBuilder
result
=
new
StringBuilder
();
result
.
append
(
pp
.
pop
().
getAlias
());
while
(
pp
.
size
()
>
0
)
{
result
.
append
(
separatorChar
);
result
.
append
(
SEPARATOR_CHAR
);
result
.
append
(
pp
.
pop
().
getAlias
());
}
cachedPackageFullAlias
=
result
.
toString
();
...
...
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
View file @
3314de8d
package
jadx
.
core
.
dex
.
info
;
import
jadx.core.codegen.TypeGen
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.nodes.DexNode
;
...
...
@@ -10,11 +11,13 @@ public final class FieldInfo {
private
final
ClassInfo
declClass
;
private
final
String
name
;
private
final
ArgType
type
;
private
String
alias
;
private
FieldInfo
(
ClassInfo
declClass
,
String
name
,
ArgType
type
)
{
this
.
declClass
=
declClass
;
this
.
name
=
name
;
this
.
type
=
type
;
this
.
alias
=
name
;
}
public
static
FieldInfo
from
(
DexNode
dex
,
ClassInfo
declClass
,
String
name
,
ArgType
type
)
{
...
...
@@ -42,6 +45,22 @@ public final class FieldInfo {
return
declClass
;
}
public
String
getAlias
()
{
return
alias
;
}
public
void
setAlias
(
String
alias
)
{
this
.
alias
=
alias
;
}
public
String
getFullId
()
{
return
declClass
.
getFullName
()
+
"."
+
name
+
":"
+
TypeGen
.
signature
(
type
);
}
public
boolean
isRenamed
()
{
return
!
name
.
equals
(
alias
);
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
View file @
3314de8d
...
...
@@ -17,10 +17,12 @@ public final class MethodInfo {
private
final
List
<
ArgType
>
args
;
private
final
ClassInfo
declClass
;
private
final
String
shortId
;
private
String
alias
;
private
MethodInfo
(
DexNode
dex
,
int
mthIndex
)
{
MethodId
mthId
=
dex
.
getMethodId
(
mthIndex
);
name
=
dex
.
getString
(
mthId
.
getNameIndex
());
alias
=
name
;
declClass
=
ClassInfo
.
fromDex
(
dex
,
mthId
.
getDeclaringClassIndex
());
ProtoId
proto
=
dex
.
getProtoId
(
mthId
.
getProtoIndex
());
...
...
@@ -91,6 +93,18 @@ public final class MethodInfo {
return
name
.
equals
(
"<clinit>"
);
}
public
String
getAlias
()
{
return
alias
;
}
public
void
setAlias
(
String
alias
)
{
this
.
alias
=
alias
;
}
public
boolean
isRenamed
()
{
return
!
name
.
equals
(
alias
);
}
@Override
public
int
hashCode
()
{
int
result
=
declClass
.
hashCode
();
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
View file @
3314de8d
...
...
@@ -42,6 +42,10 @@ public class FieldNode extends LineAttrNode {
return
fieldInfo
.
getName
();
}
public
String
getAlias
()
{
return
fieldInfo
.
getAlias
();
}
public
ArgType
getType
()
{
return
type
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
3314de8d
...
...
@@ -369,6 +369,10 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
mthInfo
.
getName
();
}
public
String
getAlias
()
{
return
mthInfo
.
getAlias
();
}
public
ClassNode
getParentClass
()
{
return
parentClass
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java
View file @
3314de8d
...
...
@@ -2,6 +2,9 @@ package jadx.core.dex.visitors;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.instructions.IndexInsnNode
;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
...
...
@@ -73,6 +76,21 @@ public class DependencyCollector extends AbstractVisitor {
addDep
(
dex
,
depList
,
arg
.
getType
());
}
}
processCustomInsn
(
dex
,
depList
,
insnNode
);
}
private
static
void
processCustomInsn
(
DexNode
dex
,
Set
<
ClassNode
>
depList
,
InsnNode
insn
)
{
if
(
insn
instanceof
IndexInsnNode
)
{
Object
index
=
((
IndexInsnNode
)
insn
).
getIndex
();
if
(
index
instanceof
FieldInfo
)
{
addDep
(
dex
,
depList
,
((
FieldInfo
)
index
).
getDeclClass
());
}
else
if
(
index
instanceof
ArgType
)
{
addDep
(
dex
,
depList
,
(
ArgType
)
index
);
}
}
else
if
(
insn
instanceof
InvokeNode
)
{
ClassInfo
declClass
=
((
InvokeNode
)
insn
).
getCallMth
().
getDeclClass
();
addDep
(
dex
,
depList
,
declClass
);
}
}
private
static
void
addDep
(
DexNode
dex
,
Set
<
ClassNode
>
depList
,
ArgType
type
)
{
...
...
@@ -94,15 +112,14 @@ public class DependencyCollector extends AbstractVisitor {
private
static
void
addDep
(
DexNode
dex
,
Set
<
ClassNode
>
depList
,
ClassInfo
clsInfo
)
{
if
(
clsInfo
!=
null
)
{
ClassNode
node
=
dex
.
resolveClass
(
clsInfo
);
if
(
node
!=
null
)
{
depList
.
add
(
node
);
}
addDep
(
dex
,
depList
,
node
);
}
}
private
static
void
addDep
(
DexNode
dex
,
Set
<
ClassNode
>
depList
,
ClassNode
clsNode
)
{
if
(
clsNode
!=
null
)
{
depList
.
add
(
clsNode
);
// add only top classes
depList
.
add
(
clsNode
.
getTopParentClass
());
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
View file @
3314de8d
package
jadx
.
core
.
dex
.
visitors
;
import
jadx.api.IJadxArgs
;
import
jadx.core.codegen.TypeGen
;
import
jadx.core.deobf.Deobfuscator
;
import
jadx.core.dex.attributes.AFlag
;
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.FieldNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.exceptions.JadxException
;
import
java.io.File
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.
apache.commons.io.FilenameUtils
;
import
org.
jetbrains.annotations.NotNull
;
public
class
RenameVisitor
extends
AbstractVisitor
{
@NotNull
private
Deobfuscator
deobfuscator
;
@Override
public
void
init
(
RootNode
root
)
{
String
firstInputFileName
=
root
.
getDexNodes
().
get
(
0
).
getInputFile
().
getFile
().
getAbsolutePath
();
String
inputPath
=
FilenameUtils
.
getFullPathNoEndSeparator
(
firstInputFileName
);
String
inputName
=
FilenameUtils
.
getBaseName
(
firstInputFileName
);
File
deobfMapFile
=
new
File
(
inputPath
,
inputName
+
".jobf"
);
deobfuscator
=
new
Deobfuscator
(
root
.
getArgs
(),
root
.
getDexNodes
(),
deobfMapFile
);
// TODO: check classes for case sensitive names (issue #24)
// TODO: sometimes can be used source file name from 'SourceFileAttr'
deobfuscator
.
execute
();
IJadxArgs
args
=
root
.
getArgs
();
File
deobfMapFile
=
new
File
(
args
.
getOutDir
(),
"deobf_map.jobf"
);
deobfuscator
=
new
Deobfuscator
(
args
,
root
.
getDexNodes
(),
deobfMapFile
);
if
(
args
.
isDeobfuscationOn
())
{
// TODO: check classes for case sensitive names (issue #24)
deobfuscator
.
execute
();
}
}
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
JadxException
{
// TODO: rename fields and methods
checkFields
(
cls
);
checkMethods
(
cls
);
for
(
ClassNode
inner
:
cls
.
getInnerClasses
())
{
visit
(
inner
);
}
return
false
;
}
private
void
checkFields
(
ClassNode
cls
)
{
Set
<
String
>
names
=
new
HashSet
<
String
>();
for
(
FieldNode
field
:
cls
.
getFields
())
{
FieldInfo
fieldInfo
=
field
.
getFieldInfo
();
if
(!
names
.
add
(
fieldInfo
.
getAlias
()))
{
fieldInfo
.
setAlias
(
deobfuscator
.
makeFieldAlias
(
field
));
}
}
}
private
void
checkMethods
(
ClassNode
cls
)
{
Set
<
String
>
names
=
new
HashSet
<
String
>();
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
if
(
mth
.
contains
(
AFlag
.
DONT_GENERATE
))
{
continue
;
}
MethodInfo
methodInfo
=
mth
.
getMethodInfo
();
String
signature
=
makeMethodSignature
(
methodInfo
);
if
(!
names
.
add
(
signature
))
{
methodInfo
.
setAlias
(
deobfuscator
.
makeMethodAlias
(
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
();
}
}
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