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
f2aa4cd1
Commit
f2aa4cd1
authored
Jun 05, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: make better variables naming
parent
b940b99e
Hide whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
474 additions
and
305 deletions
+474
-305
build.gradle
build.gradle
+6
-8
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+2
-0
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+2
-2
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+17
-91
NameGen.java
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+134
-0
RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+1
-1
InsnArg.java
...rc/main/java/jadx/core/dex/instructions/args/InsnArg.java
+2
-2
MthParameterArg.java
...java/jadx/core/dex/instructions/args/MthParameterArg.java
+27
-0
RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+30
-25
SSAVar.java
...src/main/java/jadx/core/dex/instructions/args/SSAVar.java
+16
-25
Typed.java
.../src/main/java/jadx/core/dex/instructions/args/Typed.java
+0
-8
VarName.java
...rc/main/java/jadx/core/dex/instructions/args/VarName.java
+18
-0
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+29
-38
DebugInfoParser.java
...main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
+6
-7
LocalVar.java
...re/src/main/java/jadx/core/dex/nodes/parser/LocalVar.java
+21
-7
BlockMakerVisitor.java
...c/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
+12
-1
DebugInfoVisitor.java
...rc/main/java/jadx/core/dex/visitors/DebugInfoVisitor.java
+43
-0
DotGraphVisitor.java
...src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
+3
-1
FallbackModeVisitor.java
...main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
+3
-0
ProcessVariables.java
...java/jadx/core/dex/visitors/regions/ProcessVariables.java
+28
-0
EliminatePhiNodes.java
...in/java/jadx/core/dex/visitors/ssa/EliminatePhiNodes.java
+0
-48
SSATransform.java
...rc/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
+1
-1
TypeInference.java
...a/jadx/core/dex/visitors/typeinference/TypeInference.java
+1
-1
TestInline2.java
...src/test/java/jadx/tests/internal/inline/TestInline2.java
+3
-3
AbstractTest.java
jadx-samples/src/main/java/jadx/samples/AbstractTest.java
+2
-1
TestAnnotations.java
jadx-samples/src/main/java/jadx/samples/TestAnnotations.java
+1
-1
TestCF.java
jadx-samples/src/main/java/jadx/samples/TestCF.java
+9
-7
TestCF2.java
jadx-samples/src/main/java/jadx/samples/TestCF2.java
+5
-3
TestDeadCode.java
jadx-samples/src/main/java/jadx/samples/TestDeadCode.java
+2
-1
TestGenerics.java
jadx-samples/src/main/java/jadx/samples/TestGenerics.java
+7
-4
TestInner.java
jadx-samples/src/main/java/jadx/samples/TestInner.java
+2
-0
TestInner2.java
jadx-samples/src/main/java/jadx/samples/TestInner2.java
+1
-1
TestInvoke.java
jadx-samples/src/main/java/jadx/samples/TestInvoke.java
+13
-4
TestSwitch.java
jadx-samples/src/main/java/jadx/samples/TestSwitch.java
+5
-3
TestTryCatch.java
jadx-samples/src/main/java/jadx/samples/TestTryCatch.java
+19
-10
TestTypeResolver2.java
...samples/src/main/java/jadx/samples/TestTypeResolver2.java
+1
-1
settings.gradle
settings.gradle
+2
-0
No files found.
build.gradle
View file @
f2aa4cd1
...
...
@@ -9,16 +9,14 @@ subprojects {
apply
plugin:
'jacoco'
apply
plugin:
'coveralls'
sourceCompatibility
=
1.6
targetCompatibility
=
1.6
version
=
jadxVersion
gradle
.
projectsEvaluated
{
tasks
.
withType
(
Compile
)
{
if
(!
"$it"
.
contains
(
':jadx-samples:'
))
{
options
.
compilerArgs
<<
'-Xlint'
<<
'-Xlint:unchecked'
<<
'-Xlint:deprecation'
}
tasks
.
withType
(
JavaCompile
)
{
sourceCompatibility
=
JavaVersion
.
VERSION_1_6
targetCompatibility
=
JavaVersion
.
VERSION_1_6
if
(!
"$it"
.
contains
(
':jadx-samples:'
))
{
options
.
compilerArgs
<<
'-Xlint'
<<
'-Xlint:unchecked'
<<
'-Xlint:deprecation'
}
}
...
...
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
f2aa4cd1
...
...
@@ -6,6 +6,7 @@ import jadx.core.dex.visitors.BlockMakerVisitor;
import
jadx.core.dex.visitors.ClassModifier
;
import
jadx.core.dex.visitors.CodeShrinker
;
import
jadx.core.dex.visitors.ConstInlinerVisitor
;
import
jadx.core.dex.visitors.DebugInfoVisitor
;
import
jadx.core.dex.visitors.DotGraphVisitor
;
import
jadx.core.dex.visitors.EnumVisitor
;
import
jadx.core.dex.visitors.FallbackModeVisitor
;
...
...
@@ -54,6 +55,7 @@ public class Jadx {
}
else
{
passes
.
add
(
new
BlockMakerVisitor
());
passes
.
add
(
new
SSATransform
());
passes
.
add
(
new
DebugInfoVisitor
());
passes
.
add
(
new
TypeInference
());
passes
.
add
(
new
ConstInlinerVisitor
());
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
f2aa4cd1
...
...
@@ -88,7 +88,7 @@ public class InsnGen {
public
void
addArg
(
CodeWriter
code
,
InsnArg
arg
,
boolean
wrap
)
throws
CodegenException
{
if
(
arg
.
isRegister
())
{
code
.
add
(
mgen
.
makeArgName
((
RegisterArg
)
arg
));
code
.
add
(
mgen
.
getNameGen
().
useArg
((
RegisterArg
)
arg
));
}
else
if
(
arg
.
isLiteral
())
{
code
.
add
(
lit
((
LiteralArg
)
arg
));
}
else
if
(
arg
.
isInsnWrap
())
{
...
...
@@ -120,7 +120,7 @@ public class InsnGen {
public
void
declareVar
(
CodeWriter
code
,
RegisterArg
arg
)
{
useType
(
code
,
arg
.
getType
());
code
.
add
(
' '
);
code
.
add
(
mgen
.
assignArg
(
arg
));
code
.
add
(
mgen
.
getNameGen
().
assignArg
(
arg
));
}
private
static
String
lit
(
LiteralArg
arg
)
{
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
f2aa4cd1
package
jadx
.
core
.
codegen
;
import
jadx.core.Consts
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.annotations.MethodParameters
;
import
jadx.core.dex.attributes.nodes.JadxErrorAttr
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.NamedArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -21,10 +19,8 @@ import jadx.core.utils.Utils;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.DecodeException
;
import
java.util.HashSet
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -36,27 +32,24 @@ public class MethodGen {
private
final
MethodNode
mth
;
private
final
ClassGen
classGen
;
private
final
boolean
fallback
;
private
final
AnnotationGen
annotationGen
;
private
final
Set
<
String
>
varNames
=
new
HashSet
<
String
>();
private
final
NameGen
nameGen
;
public
MethodGen
(
ClassGen
classGen
,
MethodNode
mth
)
{
this
.
mth
=
mth
;
this
.
classGen
=
classGen
;
this
.
fallback
=
classGen
.
isFallbackMode
();
this
.
annotationGen
=
classGen
.
getAnnotationGen
();
List
<
RegisterArg
>
args
=
mth
.
getArguments
(
true
);
for
(
RegisterArg
arg
:
args
)
{
varNames
.
add
(
makeArgName
(
arg
));
}
this
.
nameGen
=
new
NameGen
(
classGen
.
isFallbackMode
());
}
public
ClassGen
getClassGen
()
{
return
classGen
;
}
public
NameGen
getNameGen
()
{
return
nameGen
;
}
public
MethodNode
getMethodNode
()
{
return
mth
;
}
...
...
@@ -124,9 +117,7 @@ public class MethodGen {
}
private
void
addMethodArguments
(
CodeWriter
argsCode
,
List
<
RegisterArg
>
args
)
{
MethodParameters
paramsAnnotation
=
mth
.
get
(
AType
.
ANNOTATION_MTH_PARAMETERS
);
MethodParameters
paramsAnnotation
=
mth
.
get
(
AType
.
ANNOTATION_MTH_PARAMETERS
);
int
i
=
0
;
for
(
Iterator
<
RegisterArg
>
it
=
args
.
iterator
();
it
.
hasNext
();
)
{
RegisterArg
arg
=
it
.
next
();
...
...
@@ -150,7 +141,7 @@ public class MethodGen {
classGen
.
useType
(
argsCode
,
arg
.
getType
());
}
argsCode
.
add
(
' '
);
argsCode
.
add
(
makeArgName
(
arg
));
argsCode
.
add
(
nameGen
.
assignArg
(
arg
));
i
++;
if
(
it
.
hasNext
())
{
...
...
@@ -159,74 +150,6 @@ public class MethodGen {
}
}
/**
* Make variable name for register,
* Name contains register number and
* variable type or name (if debug info available)
*/
public
String
makeArgName
(
RegisterArg
arg
)
{
String
name
=
arg
.
getName
();
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
fallback
)
{
if
(
name
!=
null
)
{
return
base
+
"_"
+
name
;
}
return
base
;
}
else
{
if
(
name
!=
null
)
{
if
(
Consts
.
DEBUG
)
{
return
base
+
"_"
+
name
;
}
return
name
;
}
else
{
ArgType
type
=
arg
.
getType
();
if
(
type
.
isPrimitive
())
{
return
base
+
type
.
getPrimitiveType
().
getShortName
().
toLowerCase
();
}
else
{
// TODO: prettify variable name
return
base
+
"_"
+
Utils
.
escape
(
type
.
toString
());
}
}
}
}
/**
* Put variable declaration and return variable name (used for assignments)
*
* @param arg register variable
* @return variable name
*/
public
String
assignArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
getSVar
().
setVariableName
(
name
);
return
name
;
}
public
String
assignNamedArg
(
NamedArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
setName
(
name
);
return
name
;
}
private
String
getUniqVarName
(
String
name
)
{
String
r
;
int
i
=
2
;
do
{
r
=
name
+
"_"
+
i
;
i
++;
}
while
(
varNames
.
contains
(
r
));
varNames
.
add
(
r
);
return
r
;
}
public
void
addInstructions
(
CodeWriter
code
)
throws
CodegenException
{
if
(
mth
.
contains
(
AType
.
JADX_ERROR
))
{
code
.
startLine
(
"throw new UnsupportedOperationException(\"Method not decompiled: "
);
...
...
@@ -283,20 +206,23 @@ public class MethodGen {
return
;
}
}
List
<
InsnNode
>
insns
=
mth
.
getInstructions
();
if
(
insn
s
==
null
)
{
InsnNode
[]
insnArr
=
mth
.
getInstructions
();
if
(
insn
Arr
==
null
)
{
code
.
startLine
(
"// Can't load method instructions."
);
return
;
}
if
(
mth
.
getThisArg
()
!=
null
)
{
code
.
startLine
(
getFallbackMethodGen
(
mth
).
makeArgName
(
mth
.
getThisArg
())).
add
(
" = this;"
);
code
.
startLine
(
getFallbackMethodGen
(
mth
).
nameGen
.
useArg
(
mth
.
getThisArg
())).
add
(
" = this;"
);
}
addFallbackInsns
(
code
,
mth
,
insn
s
,
true
);
addFallbackInsns
(
code
,
mth
,
insn
Arr
,
true
);
}
public
static
void
addFallbackInsns
(
CodeWriter
code
,
MethodNode
mth
,
List
<
InsnNode
>
insns
,
boolean
addLabels
)
{
public
static
void
addFallbackInsns
(
CodeWriter
code
,
MethodNode
mth
,
InsnNode
[]
insnArr
,
boolean
addLabels
)
{
InsnGen
insnGen
=
new
InsnGen
(
getFallbackMethodGen
(
mth
),
true
);
for
(
InsnNode
insn
:
insns
)
{
for
(
InsnNode
insn
:
insnArr
)
{
if
(
insn
==
null
)
{
continue
;
}
if
(
addLabels
)
{
if
(
insn
.
contains
(
AType
.
JUMP
)
||
insn
.
contains
(
AType
.
EXC_HANDLER
))
{
...
...
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
0 → 100644
View file @
f2aa4cd1
package
jadx
.
core
.
codegen
;
import
jadx.core.Consts
;
import
jadx.core.deobf.NameMapper
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.NamedArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.utils.Utils
;
import
java.util.HashSet
;
import
java.util.Set
;
public
class
NameGen
{
private
final
Set
<
String
>
varNames
=
new
HashSet
<
String
>();
private
final
boolean
fallback
;
public
NameGen
(
boolean
fallback
)
{
this
.
fallback
=
fallback
;
}
public
String
assignArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
if
(
fallback
)
{
return
name
;
}
name
=
getUniqueVarName
(
name
);
SSAVar
sVar
=
arg
.
getSVar
();
if
(
sVar
!=
null
)
{
sVar
.
setName
(
name
);
}
return
name
;
}
public
String
assignNamedArg
(
NamedArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
fallback
)
{
return
name
;
}
name
=
getUniqueVarName
(
name
);
arg
.
setName
(
name
);
return
name
;
}
public
String
useArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
varNames
.
add
(
name
);
return
name
;
}
private
String
getUniqueVarName
(
String
name
)
{
String
r
=
name
;
int
i
=
2
;
while
(
varNames
.
contains
(
r
))
{
r
=
name
+
i
;
i
++;
}
varNames
.
add
(
r
);
return
r
;
}
private
String
makeArgName
(
RegisterArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
fallback
)
{
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
name
!=
null
)
{
return
base
+
"_"
+
name
;
}
return
base
;
}
String
varName
;
if
(
name
!=
null
)
{
if
(
name
.
equals
(
"this"
))
{
return
name
;
}
varName
=
name
;
}
else
{
varName
=
makeNameForType
(
arg
.
getType
());
}
if
(
NameMapper
.
isReserved
(
varName
))
{
return
varName
+
"R"
;
}
return
varName
;
}
private
static
String
makeNameForType
(
ArgType
type
)
{
if
(
type
.
isPrimitive
())
{
return
makeNameForPrimitive
(
type
);
}
else
if
(
type
.
isArray
())
{
return
makeNameForType
(
type
.
getArrayRootElement
())
+
"Arr"
;
}
else
{
return
makeNameForObject
(
type
);
}
}
private
static
String
makeNameForPrimitive
(
ArgType
type
)
{
return
type
.
getPrimitiveType
().
getShortName
().
toLowerCase
();
}
private
static
String
makeNameForObject
(
ArgType
type
)
{
if
(
type
.
isObject
())
{
String
obj
=
type
.
getObject
();
if
(
obj
.
startsWith
(
"java.lang."
))
{
if
(
obj
.
equals
(
Consts
.
CLASS_STRING
))
{
return
"str"
;
}
if
(
obj
.
equals
(
Consts
.
CLASS_OBJECT
))
{
return
"obj"
;
}
if
(
obj
.
equals
(
Consts
.
CLASS_CLASS
))
{
return
"cls"
;
}
if
(
obj
.
equals
(
Consts
.
CLASS_THROWABLE
))
{
return
"th"
;
}
}
ClassInfo
clsInfo
=
ClassInfo
.
fromType
(
type
);
String
shortName
=
clsInfo
.
getShortName
();
if
(
shortName
.
toUpperCase
().
equals
(
shortName
))
{
// all characters are upper case
return
shortName
.
toLowerCase
();
}
if
(!
shortName
.
isEmpty
())
{
String
v1
=
Character
.
toLowerCase
(
shortName
.
charAt
(
0
))
+
shortName
.
substring
(
1
);
if
(!
v1
.
equals
(
shortName
))
{
return
v1
;
}
}
}
return
Utils
.
escape
(
type
.
toString
());
}
}
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
View file @
f2aa4cd1
...
...
@@ -277,7 +277,7 @@ public class RegionGen extends InsnGen {
useClass
(
code
,
handler
.
getCatchType
());
}
code
.
add
(
' '
);
code
.
add
(
mgen
.
assignNamedArg
(
handler
.
getArg
()));
code
.
add
(
mgen
.
getNameGen
().
assignNamedArg
(
handler
.
getArg
()));
code
.
add
(
") {"
);
makeRegionIndent
(
code
,
region
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java
View file @
f2aa4cd1
...
...
@@ -26,7 +26,7 @@ public abstract class InsnArg extends Typed {
return
reg
(
InsnUtils
.
getArg
(
insn
,
argNum
),
type
);
}
public
static
Regis
terArg
parameterReg
(
int
regNum
,
ArgType
type
)
{
public
static
MthParame
terArg
parameterReg
(
int
regNum
,
ArgType
type
)
{
return
new
MthParameterArg
(
regNum
,
type
);
}
...
...
@@ -113,7 +113,7 @@ public abstract class InsnArg extends Typed {
}
public
boolean
isThis
()
{
// must be implemented in RegisterArg
// must be implemented in RegisterArg
and MthParameterArg
return
false
;
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/MthParameterArg.java
View file @
f2aa4cd1
...
...
@@ -2,6 +2,8 @@ package jadx.core.dex.instructions.args;
public
class
MthParameterArg
extends
RegisterArg
{
private
boolean
isThis
=
false
;
public
MthParameterArg
(
int
rn
,
ArgType
type
)
{
super
(
rn
,
type
);
}
...
...
@@ -14,4 +16,29 @@ public class MthParameterArg extends RegisterArg {
@Override
public
void
setType
(
ArgType
type
)
{
}
public
void
markAsThis
()
{
this
.
isThis
=
true
;
}
@Override
public
boolean
isThis
()
{
return
isThis
;
}
@Override
public
String
getName
()
{
if
(
isThis
)
{
return
"this"
;
}
return
super
.
getName
();
}
@Override
void
setSVar
(
SSAVar
sVar
)
{
if
(
isThis
)
{
sVar
.
setName
(
"this"
);
}
super
.
setSVar
(
sVar
);
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
View file @
f2aa4cd1
...
...
@@ -11,7 +11,6 @@ import jadx.core.dex.nodes.DexNode;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.parser.FieldValueAttr
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -21,7 +20,6 @@ public class RegisterArg extends InsnArg implements Named {
protected
final
int
regNum
;
protected
SSAVar
sVar
;
protected
String
name
;
public
RegisterArg
(
int
rn
)
{
this
.
regNum
=
rn
;
...
...
@@ -49,32 +47,41 @@ public class RegisterArg extends InsnArg implements Named {
this
.
sVar
=
sVar
;
}
@Override
public
void
setType
(
ArgType
type
)
{
if
(
sVar
!=
null
)
{
sVar
.
setType
(
type
);
}
else
{
throw
new
JadxRuntimeException
(
"SSA variable equals null"
);
public
String
getName
()
{
if
(
sVar
==
null
)
{
return
null
;
}
return
sVar
.
getName
();
}
public
void
forceType
(
ArgType
type
)
{
this
.
type
=
type
;
}
public
String
getName
()
{
return
name
;
public
void
setName
(
String
name
)
{
if
(
sVar
!=
null
)
{
sVar
.
setName
(
name
);
}
}
public
boolean
isNameEquals
(
InsnArg
arg
)
{
if
(
name
==
null
||
!(
arg
instanceof
Named
))
{
String
n
=
getName
();
if
(
n
==
null
||
!(
arg
instanceof
Named
))
{
return
false
;
}
return
name
.
equals
(((
Named
)
arg
).
getName
());
return
n
.
equals
(((
Named
)
arg
).
getName
());
}
@Override
public
void
setType
(
ArgType
type
)
{
if
(
sVar
!=
null
)
{
sVar
.
setType
(
type
);
}
}
public
void
mergeDebugInfo
(
ArgType
type
,
String
name
)
{
setType
(
type
);
setName
(
name
);
}
public
void
setName
(
String
newNam
e
)
{
this
.
name
=
newNam
e
;
public
void
forceType
(
ArgType
typ
e
)
{
this
.
type
=
typ
e
;
}
/**
...
...
@@ -113,17 +120,15 @@ public class RegisterArg extends InsnArg implements Named {
@Override
public
boolean
isThis
()
{
if
(
"this"
.
equals
(
name
))
{
if
(
"this"
.
equals
(
getName
()
))
{
return
true
;
}
// maybe it was moved from 'this' register
InsnNode
ai
=
getAssignInsn
();
if
(
ai
!=
null
&&
ai
.
getType
()
==
InsnType
.
MOVE
)
{
InsnArg
arg
=
ai
.
getArg
(
0
);
if
(
arg
!=
this
&&
arg
.
isRegister
()
&&
"this"
.
equals
(((
RegisterArg
)
arg
).
getName
()))
{
return
true
;
if
(
arg
!=
this
)
{
return
arg
.
isThis
();
}
}
return
false
;
...
...
@@ -196,8 +201,8 @@ public class RegisterArg extends InsnArg implements Named {
if
(
sVar
!=
null
)
{
sb
.
append
(
"_"
).
append
(
sVar
.
getVersion
());
}
if
(
name
!=
null
)
{
sb
.
append
(
" '"
).
append
(
name
).
append
(
"'"
);
if
(
getName
()
!=
null
)
{
sb
.
append
(
" '"
).
append
(
getName
()
).
append
(
"'"
);
}
sb
.
append
(
" "
);
sb
.
append
(
type
);
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/SSAVar.java
View file @
f2aa4cd1
...
...
@@ -9,6 +9,7 @@ public class SSAVar {
private
final
int
regNum
;
private
final
int
version
;
private
VarName
varName
;
private
RegisterArg
assign
;
private
final
List
<
RegisterArg
>
useList
=
new
ArrayList
<
RegisterArg
>(
2
);
...
...
@@ -22,7 +23,6 @@ public class SSAVar {
this
.
assign
=
assign
;
if
(
assign
!=
null
)
{
mergeName
(
assign
);
assign
.
setSVar
(
this
);
}
}
...
...
@@ -52,7 +52,6 @@ public class SSAVar {
}
public
void
use
(
RegisterArg
arg
)
{
mergeName
(
arg
);
if
(
arg
.
getSVar
()
!=
null
)
{
arg
.
getSVar
().
removeUse
(
arg
);
}
...
...
@@ -103,35 +102,27 @@ public class SSAVar {
}
public
void
setName
(
String
name
)
{
if
(
assign
!=
null
)
{
assign
.
setName
(
name
);
}
for
(
int
i
=
0
,
useListSize
=
useList
.
size
();
i
<
useListSize
;
i
++)
{
useList
.
get
(
i
)
.
setName
(
name
);
if
(
name
!=
null
)
{
if
(
varName
==
null
)
{
varName
=
new
VarName
();
}
varName
.
setName
(
name
);
}
}
public
void
setVariableName
(
String
name
)
{
setName
(
name
);
if
(
isUsedInPhi
())
{
PhiInsn
phi
=
getUsedInPhi
();
phi
.
getResult
().
getSVar
().
setVariableName
(
name
);
for
(
InsnArg
arg
:
phi
.
getArguments
())
{
if
(
arg
.
isRegister
())
{
RegisterArg
reg
=
(
RegisterArg
)
arg
;
SSAVar
sVar
=
reg
.
getSVar
();
if
(
sVar
!=
this
&&
!
name
.
equals
(
reg
.
getName
()))
{
sVar
.
setVariableName
(
name
);
}
}
}
public
String
getName
()
{
if
(
varName
==
null
)
{
return
null
;
}
return
varName
.
getName
();
}
public
void
mergeName
(
RegisterArg
arg
)
{
if
(
arg
.
getName
()
!=
null
)
{
setName
(
arg
.
getName
());
}
public
VarName
getVarName
()
{
return
varName
;
}
public
void
setVarName
(
VarName
varName
)
{
this
.
varName
=
varName
;
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java
View file @
f2aa4cd1
...
...
@@ -28,12 +28,4 @@ public abstract class Typed {
public
boolean
merge
(
InsnArg
arg
)
{
return
merge
(
arg
.
getType
());
}
public
void
mergeDebugInfo
(
RegisterArg
arg
)
{
this
.
type
=
arg
.
getType
();
if
(
this
instanceof
Named
)
{
Named
n
=
(
Named
)
this
;
n
.
setName
(
arg
.
getName
());
}
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/VarName.java
0 → 100644
View file @
f2aa4cd1
package
jadx
.
core
.
dex
.
instructions
.
args
;
public
class
VarName
{
private
String
name
;
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
@Override
public
String
toString
()
{
return
name
;
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
f2aa4cd1
...
...
@@ -15,9 +15,9 @@ import jadx.core.dex.instructions.InsnDecoder;
import
jadx.core.dex.instructions.SwitchNode
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.MthParameterArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.dex.nodes.parser.DebugInfoParser
;
import
jadx.core.dex.nodes.parser.SignatureParser
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.trycatch.ExcHandlerAttr
;
...
...
@@ -51,7 +51,8 @@ public class MethodNode extends LineAttrNode implements ILoadable {
private
final
Method
methodData
;
private
int
regsCount
;
private
List
<
InsnNode
>
instructions
;
private
InsnNode
[]
instructions
;
private
int
debugInfoOffset
;
private
boolean
noCode
;
private
ArgType
retType
;
...
...
@@ -92,30 +93,12 @@ public class MethodNode extends LineAttrNode implements ILoadable {
InsnDecoder
decoder
=
new
InsnDecoder
(
this
);
decoder
.
decodeInsns
(
mthCode
);
InsnNode
[]
insnByOffset
=
decoder
.
process
();
instructions
=
new
ArrayList
<
InsnNode
>();
for
(
InsnNode
insn
:
insnByOffset
)
{
if
(
insn
!=
null
)
{
instructions
.
add
(
insn
);
}
}
((
ArrayList
<
InsnNode
>)
instructions
).
trimToSize
();
instructions
=
decoder
.
process
();
initTryCatches
(
mthCode
,
insnByOffset
);
initJumps
(
insnByOffset
);
initTryCatches
(
mthCode
);
initJumps
();
int
debugInfoOffset
=
mthCode
.
getDebugInfoOffset
();
if
(
debugInfoOffset
>
0
)
{
DebugInfoParser
debugInfoParser
=
new
DebugInfoParser
(
this
,
debugInfoOffset
,
insnByOffset
);
debugInfoParser
.
process
();
if
(
instructions
.
size
()
!=
0
)
{
int
line
=
instructions
.
get
(
0
).
getSourceLine
();
if
(
line
!=
0
)
{
this
.
setSourceLine
(
line
-
1
);
}
}
}
this
.
debugInfoOffset
=
mthCode
.
getDebugInfoOffset
();
}
catch
(
Exception
e
)
{
if
(!
noCode
)
{
noCode
=
true
;
...
...
@@ -139,9 +122,7 @@ public class MethodNode extends LineAttrNode implements ILoadable {
if
(
noCode
)
{
return
;
}
if
(
instructions
!=
null
)
{
instructions
.
clear
();
}
instructions
=
null
;
blocks
=
null
;
exitBlocks
=
null
;
exceptionHandlers
.
clear
();
...
...
@@ -199,8 +180,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
if
(
accFlags
.
isStatic
())
{
thisArg
=
null
;
}
else
{
thisArg
=
InsnArg
.
parameterReg
(
pos
-
1
,
parentClass
.
getClassInfo
().
getType
());
thisArg
.
setName
(
"this"
);
MthParameterArg
arg
=
InsnArg
.
parameterReg
(
pos
-
1
,
parentClass
.
getClassInfo
().
getType
());
arg
.
markAsThis
();
thisArg
=
arg
;
}
if
(
args
.
isEmpty
())
{
argsList
=
Collections
.
emptyList
();
...
...
@@ -241,7 +223,8 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
genericMap
;
}
private
void
initTryCatches
(
Code
mthCode
,
InsnNode
[]
insnByOffset
)
{
private
void
initTryCatches
(
Code
mthCode
)
{
InsnNode
[]
insnByOffset
=
instructions
;
CatchHandler
[]
catchBlocks
=
mthCode
.
getCatchHandlers
();
Try
[]
tries
=
mthCode
.
getTries
();
...
...
@@ -311,9 +294,13 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
}
private
void
initJumps
(
InsnNode
[]
insnByOffset
)
{
for
(
InsnNode
insn
:
getInstructions
())
{
int
offset
=
insn
.
getOffset
();
private
void
initJumps
()
{
InsnNode
[]
insnByOffset
=
instructions
;
for
(
int
offset
=
0
;
offset
<
insnByOffset
.
length
;
offset
++)
{
InsnNode
insn
=
insnByOffset
[
offset
];
if
(
insn
==
null
)
{
continue
;
}
switch
(
insn
.
getType
())
{
case
SWITCH:
{
SwitchNode
sw
=
(
SwitchNode
)
insn
;
...
...
@@ -367,20 +354,20 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
noCode
;
}
public
List
<
InsnNode
>
getInstructions
()
{
public
InsnNode
[]
getInstructions
()
{
return
instructions
;
}
public
void
unloadInsnArr
()
{
this
.
instructions
=
null
;
}
public
void
initBasicBlocks
()
{
blocks
=
new
ArrayList
<
BlockNode
>();
exitBlocks
=
new
ArrayList
<
BlockNode
>(
1
);
}
public
void
finishBasicBlocks
()
{
// after filling basic blocks we don't need instructions list anymore
instructions
.
clear
();
instructions
=
null
;
((
ArrayList
<
BlockNode
>)
blocks
).
trimToSize
();
((
ArrayList
<
BlockNode
>)
exitBlocks
).
trimToSize
();
...
...
@@ -479,6 +466,10 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
regsCount
;
}
public
int
getDebugInfoOffset
()
{
return
debugInfoOffset
;
}
public
SSAVar
makeNewSVar
(
int
regNum
,
int
[]
versions
,
RegisterArg
arg
)
{
SSAVar
var
=
new
SSAVar
(
regNum
,
versions
[
regNum
],
arg
);
versions
[
regNum
]++;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
View file @
f2aa4cd1
...
...
@@ -226,19 +226,18 @@ public class DebugInfoParser {
}
private
static
void
fillLocals
(
InsnNode
insn
,
LocalVar
var
)
{
if
(
insn
.
getResult
()
!=
null
)
{
merge
(
insn
.
getResult
(),
var
);
}
merge
(
insn
.
getResult
(),
var
);
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
merge
(
arg
,
var
);
}
}
private
static
void
merge
(
InsnArg
arg
,
LocalVar
var
)
{
if
(
arg
!=
null
&&
arg
.
isRegister
()
&&
var
.
getRegNum
()
==
((
RegisterArg
)
arg
).
getRegNum
())
{
arg
.
mergeDebugInfo
(
var
);
if
(
arg
!=
null
&&
arg
.
isRegister
())
{
RegisterArg
reg
=
(
RegisterArg
)
arg
;
if
(
var
.
getRegNum
()
==
reg
.
getRegNum
())
{
reg
.
mergeDebugInfo
(
var
.
getType
(),
var
.
getName
());
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/parser/LocalVar.java
View file @
f2aa4cd1
...
...
@@ -8,17 +8,19 @@ import jadx.core.utils.InsnUtils;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
final
class
LocalVar
extends
RegisterArg
{
final
class
LocalVar
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
LocalVar
.
class
);
private
boolean
isEnd
;
private
int
regNum
;
private
String
name
;
private
ArgType
type
;
private
boolean
isEnd
;
private
int
startAddr
;
private
int
endAddr
;
public
LocalVar
(
DexNode
dex
,
int
rn
,
int
nameId
,
int
typeId
,
int
signId
)
{
super
(
rn
,
ArgType
.
UNKNOWN
)
;
this
.
regNum
=
rn
;
String
name
=
(
nameId
==
DexNode
.
NO_INDEX
?
null
:
dex
.
getString
(
nameId
));
ArgType
type
=
(
typeId
==
DexNode
.
NO_INDEX
?
null
:
dex
.
getType
(
typeId
));
String
sign
=
(
signId
==
DexNode
.
NO_INDEX
?
null
:
dex
.
getString
(
signId
));
...
...
@@ -27,7 +29,7 @@ final class LocalVar extends RegisterArg {
}
public
LocalVar
(
RegisterArg
arg
)
{
super
(
arg
.
getRegNum
(),
arg
.
getType
()
);
this
.
regNum
=
arg
.
getRegNum
(
);
init
(
arg
.
getName
(),
arg
.
getType
(),
null
);
}
...
...
@@ -42,8 +44,8 @@ final class LocalVar extends RegisterArg {
LOG
.
error
(
"Can't parse signature for local variable: "
+
sign
,
e
);
}
}
setName
(
name
)
;
forceType
(
type
)
;
this
.
name
=
name
;
this
.
type
=
type
;
}
private
boolean
checkSignature
(
ArgType
type
,
String
sign
,
ArgType
gType
)
{
...
...
@@ -72,6 +74,18 @@ final class LocalVar extends RegisterArg {
this
.
endAddr
=
addr
;
}
public
int
getRegNum
()
{
return
regNum
;
}
public
String
getName
()
{
return
name
;
}
public
ArgType
getType
()
{
return
type
;
}
public
boolean
isEnd
()
{
return
isEnd
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
View file @
f2aa4cd1
...
...
@@ -60,6 +60,9 @@ public class BlockMakerVisitor extends AbstractVisitor {
// split into blocks
for
(
InsnNode
insn
:
mth
.
getInstructions
())
{
if
(
insn
==
null
)
{
continue
;
}
boolean
startNew
=
false
;
if
(
prevInsn
!=
null
)
{
InsnType
type
=
prevInsn
.
getType
();
...
...
@@ -443,10 +446,18 @@ public class BlockMakerVisitor extends AbstractVisitor {
if
(
returnInsn
.
getArgsCount
()
!=
0
&&
!
isReturnArgAssignInPred
(
preds
,
returnInsn
))
{
return
false
;
}
boolean
first
=
true
;
for
(
BlockNode
pred
:
preds
)
{
BlockNode
newRetBlock
=
startNewBlock
(
mth
,
exitBlock
.
getStartOffset
());
newRetBlock
.
add
(
AFlag
.
SYNTHETIC
);
newRetBlock
.
getInstructions
().
add
(
duplicateReturnInsn
(
returnInsn
));
InsnNode
newRetInsn
;
if
(
first
)
{
newRetInsn
=
returnInsn
;
first
=
false
;
}
else
{
newRetInsn
=
duplicateReturnInsn
(
returnInsn
);
}
newRetBlock
.
getInstructions
().
add
(
newRetInsn
);
removeConnection
(
pred
,
exitBlock
);
connect
(
pred
,
newRetBlock
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DebugInfoVisitor.java
0 → 100644
View file @
f2aa4cd1
package
jadx
.
core
.
dex
.
visitors
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.parser.DebugInfoParser
;
import
jadx.core.utils.exceptions.JadxException
;
public
class
DebugInfoVisitor
extends
AbstractVisitor
{
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
int
debugOffset
=
mth
.
getDebugInfoOffset
();
if
(
debugOffset
>
0
)
{
InsnNode
[]
insnArr
=
mth
.
getInstructions
();
DebugInfoParser
debugInfoParser
=
new
DebugInfoParser
(
mth
,
debugOffset
,
insnArr
);
debugInfoParser
.
process
();
if
(
insnArr
.
length
!=
0
)
{
int
line
=
insnArr
[
0
].
getSourceLine
();
if
(
line
!=
0
)
{
mth
.
setSourceLine
(
line
-
1
);
}
}
if
(!
mth
.
getReturnType
().
equals
(
ArgType
.
VOID
)
&&
mth
.
getExitBlocks
().
size
()
>
1
)
{
// fix debug for splitter 'return' instructions
for
(
BlockNode
exit
:
mth
.
getExitBlocks
())
{
InsnNode
ret
=
exit
.
getInstructions
().
get
(
0
);
InsnNode
oldRet
=
insnArr
[
ret
.
getOffset
()];
if
(
oldRet
!=
ret
)
{
RegisterArg
oldArg
=
(
RegisterArg
)
oldRet
.
getArg
(
0
);
RegisterArg
newArg
=
(
RegisterArg
)
ret
.
getArg
(
0
);
newArg
.
mergeDebugInfo
(
oldArg
.
getType
(),
oldArg
.
getName
());
ret
.
setSourceLine
(
oldRet
.
getSourceLine
());
}
}
}
}
mth
.
unloadInsnArr
();
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
View file @
f2aa4cd1
...
...
@@ -211,7 +211,9 @@ public class DotGraphVisitor extends AbstractVisitor {
return
str
.
toString
();
}
else
{
CodeWriter
code
=
new
CodeWriter
();
MethodGen
.
addFallbackInsns
(
code
,
mth
,
block
.
getInstructions
(),
false
);
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
MethodGen
.
addFallbackInsns
(
code
,
mth
,
instructions
.
toArray
(
new
InsnNode
[
instructions
.
size
()]),
false
);
String
str
=
escape
(
code
.
newLine
().
toString
());
if
(
str
.
startsWith
(
NL
))
{
str
=
str
.
substring
(
NL
.
length
());
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
View file @
f2aa4cd1
...
...
@@ -14,6 +14,9 @@ public class FallbackModeVisitor extends AbstractVisitor {
return
;
}
for
(
InsnNode
insn
:
mth
.
getInstructions
())
{
if
(
insn
==
null
)
{
continue
;
}
// remove 'exception catch' for instruction which don't throw any exceptions
CatchAttr
catchAttr
=
insn
.
get
(
AType
.
CATCH_BLOCK
);
if
(
catchAttr
!=
null
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
View file @
f2aa4cd1
...
...
@@ -5,6 +5,7 @@ import jadx.core.dex.attributes.AType;
import
jadx.core.dex.attributes.nodes.DeclareVariablesAttr
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.VarName
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
...
...
@@ -66,6 +67,7 @@ public class ProcessVariables extends AbstractVisitor {
private
static
class
Usage
{
private
RegisterArg
arg
;
private
VarName
varName
;
private
IRegion
argRegion
;
private
final
Set
<
IRegion
>
usage
=
new
HashSet
<
IRegion
>(
2
);
private
final
Set
<
IRegion
>
assigns
=
new
HashSet
<
IRegion
>(
2
);
...
...
@@ -78,6 +80,14 @@ public class ProcessVariables extends AbstractVisitor {
return
arg
;
}
public
VarName
getVarName
()
{
return
varName
;
}
public
void
setVarName
(
VarName
varName
)
{
this
.
varName
=
varName
;
}
public
void
setArgRegion
(
IRegion
argRegion
)
{
this
.
argRegion
=
argRegion
;
}
...
...
@@ -102,7 +112,14 @@ public class ProcessVariables extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
{
return
;
}
final
Map
<
Variable
,
Usage
>
usageMap
=
new
LinkedHashMap
<
Variable
,
Usage
>();
for
(
RegisterArg
arg
:
mth
.
getArguments
(
true
))
{
addToUsageMap
(
arg
,
usageMap
);
}
// collect all variables usage
IRegionVisitor
collect
=
new
TracedRegionVisitor
()
{
...
...
@@ -210,6 +227,17 @@ public class ProcessVariables extends AbstractVisitor {
usage
=
new
Usage
();
usageMap
.
put
(
varId
,
usage
);
}
// merge variables names
if
(
usage
.
getVarName
()
==
null
)
{
VarName
argVN
=
arg
.
getSVar
().
getVarName
();
if
(
argVN
==
null
)
{
argVN
=
new
VarName
();
arg
.
getSVar
().
setVarName
(
argVN
);
}
usage
.
setVarName
(
argVN
);
}
else
{
arg
.
getSVar
().
setVarName
(
usage
.
getVarName
());
}
return
usage
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/EliminatePhiNodes.java
View file @
f2aa4cd1
...
...
@@ -3,7 +3,6 @@ package jadx.core.dex.visitors.ssa;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.PhiListAttr
;
import
jadx.core.dex.instructions.PhiInsn
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -19,56 +18,9 @@ public class EliminatePhiNodes extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
enumerateSVars
(
mth
);
removePhiInstructions
(
mth
);
}
public
static
void
enumerateSVars
(
MethodNode
mth
)
{
for
(
SSAVar
sVar
:
mth
.
getSVars
())
{
if
(
sVar
.
isUsedInPhi
())
{
sVar
.
mergeName
(
sVar
.
getUsedInPhi
().
getResult
());
}
}
}
// public static void enumerateSVars(MethodNode mth) {
// List<SSAVar> vars = mth.getSVars();
// int varsSize = vars.size();
// Deque<SSAVar> workList = new LinkedList<SSAVar>();
// for (int i = 0; i < varsSize; i++) {
// SSAVar ssaVar = vars.get(i);
// ssaVar.setVarId(i);
// if (ssaVar.isUsedInPhi()) {
// workList.add(ssaVar);
// }
// }
//
// int k = 0;
// while (!workList.isEmpty()) {
// SSAVar var = workList.pop();
// RegisterArg assignVar = var.getUsedInPhi().getResult();
// // set same name and variable ID
// var.mergeName(assignVar);
// SSAVar assignSVar = assignVar.getSVar();
// int varId = assignSVar.getVarId();
// var.setVarId(varId);
//
// if (assignSVar.isUsedInPhi()) {
// PhiInsn assignPhi = assignSVar.getUsedInPhi();
// SSAVar asVar = assignPhi.getResult().getSVar();
// if (asVar.getVarId() != varId) {
// asVar.setVarId(varId);
// for (int i = 0; i < assignPhi.getArgsCount(); i++) {
// workList.push(assignPhi.getArg(i).getSVar());
// }
// }
// }
// if (k++ > 1000) {
// throw new JadxRuntimeException("Can't calculate variable id");
// }
// }
// }
private
static
void
removePhiInstructions
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
PhiListAttr
phiList
=
block
.
get
(
AType
.
PHI_LIST
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
View file @
f2aa4cd1
...
...
@@ -32,7 +32,7 @@ public class SSATransform extends AbstractVisitor {
process
(
mth
);
}
p
ublic
void
process
(
MethodNode
mth
)
{
p
rivate
void
process
(
MethodNode
mth
)
{
LiveVarAnalysis
la
=
new
LiveVarAnalysis
(
mth
);
la
.
runAnalysis
();
for
(
int
i
=
0
;
i
<
mth
.
getRegsCount
();
i
++)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java
View file @
f2aa4cd1
...
...
@@ -82,7 +82,7 @@ public class TypeInference extends AbstractVisitor {
for
(
int
i
=
0
;
i
<
phi
.
getArgsCount
();
i
++)
{
RegisterArg
arg
=
phi
.
getArg
(
i
);
arg
.
setType
(
type
);
arg
.
getSVar
().
mergeName
(
phi
.
getResult
());
arg
.
getSVar
().
setName
(
phi
.
getResult
().
getName
());
}
}
...
...
jadx-core/src/test/java/jadx/tests/internal/inline/TestInline2.java
View file @
f2aa4cd1
...
...
@@ -31,8 +31,8 @@ public class TestInline2 extends InternalJadxTest {
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsString
(
"i < a.length"
));
assertThat
(
code
,
containsString
(
"long i
_
2 ="
));
assertThat
(
code
,
containsString
(
"+ i
_
2"
));
assertThat
(
code
,
containsString
(
"i
_
2--;"
));
assertThat
(
code
,
containsString
(
"long i2 ="
));
assertThat
(
code
,
containsString
(
"+ i2"
));
assertThat
(
code
,
containsString
(
"i2--;"
));
}
}
jadx-samples/src/main/java/jadx/samples/AbstractTest.java
View file @
f2aa4cd1
...
...
@@ -36,8 +36,9 @@ public abstract class AbstractTest {
public
static
void
assertEquals
(
Object
a1
,
Object
a2
)
{
if
(
a1
==
null
)
{
if
(
a2
!=
null
)
if
(
a2
!=
null
)
{
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
}
}
else
if
(!
a1
.
equals
(
a2
))
{
throw
new
AssertionError
(
a1
+
" != "
+
a2
);
}
...
...
jadx-samples/src/main/java/jadx/samples/TestAnnotations.java
View file @
f2aa4cd1
...
...
@@ -50,7 +50,7 @@ public class TestAnnotations extends AbstractTest {
@MyAnnotation
(
name
=
"b"
,
num
=
7
,
cls
=
Exception
.
class
,
doubles
=
{
0.0
,
1.1
},
doubles
=
{
0.0
,
1.1
},
value
=
9.87f
,
simple
=
@SimpleAnnotation
(
false
))
public
static
Object
test
(
String
[]
a
)
{
...
...
jadx-samples/src/main/java/jadx/samples/TestCF.java
View file @
f2aa4cd1
...
...
@@ -22,10 +22,11 @@ public class TestCF extends AbstractTest {
public
int
test1b
(
int
a
)
{
if
(
a
>
0
)
{
if
(
a
<
5
)
if
(
a
<
5
)
{
a
++;
else
}
else
{
a
-=
2
;
}
}
a
*=
2
;
return
a
+
3
;
...
...
@@ -134,16 +135,17 @@ public class TestCF extends AbstractTest {
public
int
testIfElse
(
String
str
)
{
int
r
;
if
(
str
.
equals
(
"a"
))
if
(
str
.
equals
(
"a"
))
{
r
=
1
;
else
if
(
str
.
equals
(
"b"
))
}
else
if
(
str
.
equals
(
"b"
))
{
r
=
2
;
else
if
(
str
.
equals
(
"3"
))
}
else
if
(
str
.
equals
(
"3"
))
{
r
=
3
;
else
if
(
str
.
equals
(
"$"
))
}
else
if
(
str
.
equals
(
"$"
))
{
r
=
4
;
else
}
else
{
r
=
-
1
;
}
r
=
r
*
10
;
return
Math
.
abs
(
r
);
...
...
jadx-samples/src/main/java/jadx/samples/TestCF2.java
View file @
f2aa4cd1
...
...
@@ -5,7 +5,7 @@ public class TestCF2 extends AbstractTest {
private
boolean
ready
=
false
;
public
int
simple_loops
()
throws
InterruptedException
{
int
[]
a
=
new
int
[]
{
1
,
2
,
4
,
6
,
8
};
int
[]
a
=
new
int
[]
{
1
,
2
,
4
,
6
,
8
};
int
b
=
0
;
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
b
+=
a
[
i
];
...
...
@@ -21,8 +21,9 @@ public class TestCF2 extends AbstractTest {
*/
public
void
run
()
throws
InterruptedException
{
while
(
true
)
{
if
(!
ready
)
if
(!
ready
)
{
ready_mutex
.
wait
();
}
ready
=
false
;
func
();
}
...
...
@@ -88,8 +89,9 @@ public class TestCF2 extends AbstractTest {
public
void
do_while_return2
(
boolean
k
)
throws
InterruptedException
{
int
i
=
3
;
do
{
if
(
k
)
if
(
k
)
{
return
;
}
i
++;
}
while
(
i
<
5
);
}
...
...
jadx-samples/src/main/java/jadx/samples/TestDeadCode.java
View file @
f2aa4cd1
...
...
@@ -3,8 +3,9 @@ package jadx.samples;
public
class
TestDeadCode
extends
AbstractTest
{
private
void
test1
(
int
i
)
{
if
(
i
==
0
)
if
(
i
==
0
)
{
return
;
}
return
;
}
...
...
jadx-samples/src/main/java/jadx/samples/TestGenerics.java
View file @
f2aa4cd1
...
...
@@ -77,7 +77,7 @@ public class TestGenerics extends AbstractTest {
public
static
boolean
use
()
{
Pair
<
Integer
,
String
>
p1
=
new
OrderedPair
<
Integer
,
String
>(
1
,
"str1"
);
Pair
<
Integer
,
String
>
p2
=
new
OrderedPair
<
Integer
,
String
>(
2
,
"str2"
);
boolean
same
=
Util
.<
Integer
,
String
>
compare
(
p1
,
p2
);
boolean
same
=
Util
.<
Integer
,
String
>
compare
(
p1
,
p2
);
return
same
;
}
...
...
@@ -107,9 +107,11 @@ public class TestGenerics extends AbstractTest {
public
static
<
T
extends
Comparable
<
T
>>
int
countGreaterThan
(
T
[]
anArray
,
T
elem
)
{
int
count
=
0
;
for
(
T
e
:
anArray
)
if
(
e
.
compareTo
(
elem
)
>
0
)
for
(
T
e
:
anArray
)
{
if
(
e
.
compareTo
(
elem
)
>
0
)
{
++
count
;
}
}
return
count
;
}
...
...
@@ -117,8 +119,9 @@ public class TestGenerics extends AbstractTest {
}
public
static
void
printList
(
List
<?>
list
)
{
for
(
Object
elem
:
list
)
for
(
Object
elem
:
list
)
{
System
.
out
.
print
(
elem
+
" "
);
}
System
.
out
.
println
();
}
...
...
jadx-samples/src/main/java/jadx/samples/TestInner.java
View file @
f2aa4cd1
...
...
@@ -56,6 +56,7 @@ public class TestInner extends AbstractTest {
{
count
+=
5
;
}
@Override
public
void
run
()
{
count
+=
6
;
...
...
@@ -68,6 +69,7 @@ public class TestInner extends AbstractTest {
{
count
+=
7
;
}
@Override
public
String
toString
()
{
count
+=
8
;
...
...
jadx-samples/src/main/java/jadx/samples/TestInner2.java
View file @
f2aa4cd1
...
...
@@ -73,7 +73,7 @@ public class TestInner2 extends AbstractTest {
Method
[]
mths
=
TestInner2
.
class
.
getDeclaredMethods
();
for
(
Method
mth
:
mths
)
{
if
(
mth
.
getName
().
startsWith
(
"access$"
))
{
if
(
mth
.
getName
().
startsWith
(
"access$"
))
{
int
modifiers
=
mth
.
getModifiers
();
assertTrue
((
modifiers
&
SYNTHETIC
)
!=
0
,
"Synthetic methods must be removed"
);
}
...
...
jadx-samples/src/main/java/jadx/samples/TestInvoke.java
View file @
f2aa4cd1
...
...
@@ -14,10 +14,11 @@ public class TestInvoke extends AbstractTest {
}
private
void
parse
(
String
[]
args
)
{
if
(
args
.
length
>
0
)
if
(
args
.
length
>
0
)
{
f
=
Integer
.
parseInt
(
args
[
0
]);
else
}
else
{
f
=
20
;
}
}
public
int
getF
()
{
...
...
@@ -37,18 +38,26 @@ public class TestInvoke extends AbstractTest {
return
s
;
}
private
String
testSameArgTypes
(
String
s1
,
String
s2
)
{
if
(
s1
.
equals
(
s2
))
{
return
null
;
}
return
s1
;
}
@Override
public
boolean
testRun
()
throws
Exception
{
TestInvoke
inv
=
new
TestInvoke
();
inv
.
parse
(
new
String
[]
{
"12"
,
"35"
});
inv
.
parse
(
new
String
[]
{
"12"
,
"35"
});
assertTrue
(
inv
.
getF
()
==
12
);
inv
.
parse
(
new
String
[
0
]);
assertTrue
(
inv
.
getF
()
==
20
);
assertTrue
(
inv
.
testVarArgs
(
"a"
,
"2"
,
"III"
));
assertTrue
(
inv
.
testVarArgs2
(
"a"
.
toCharArray
(),
new
char
[]
{
'1'
,
'2'
}).
equals
(
"a12"
));
assertTrue
(
inv
.
testVarArgs2
(
"a"
.
toCharArray
(),
new
char
[]
{
'1'
,
'2'
}).
equals
(
"a12"
));
assertEquals
(
testSameArgTypes
(
"a"
,
"b"
),
"a"
);
return
true
;
}
...
...
jadx-samples/src/main/java/jadx/samples/TestSwitch.java
View file @
f2aa4cd1
...
...
@@ -43,10 +43,11 @@ public class TestSwitch extends AbstractTest {
int
k
=
i
;
switch
(
k
)
{
case
1
:
if
(
j
==
0
)
if
(
j
==
0
)
{
return
0
;
else
}
else
{
return
-
1
;
}
case
2
:
return
1
;
}
...
...
@@ -69,8 +70,9 @@ public class TestSwitch extends AbstractTest {
int
k
=
i
;
switch
(
k
)
{
case
1
:
if
(
b
==
0
)
if
(
b
==
0
)
{
return
3
;
}
case
2
:
b
++;
...
...
jadx-samples/src/main/java/jadx/samples/TestTryCatch.java
View file @
f2aa4cd1
...
...
@@ -5,14 +5,16 @@ import java.io.IOException;
public
class
TestTryCatch
extends
AbstractTest
{
private
static
boolean
exc
(
Object
obj
)
throws
Exception
{
if
(
obj
==
null
)
if
(
obj
==
null
)
{
throw
new
Exception
(
"test"
);
}
return
(
obj
instanceof
Object
);
}
private
static
boolean
exc2
(
Object
obj
)
throws
IOException
{
if
(
obj
==
null
)
if
(
obj
==
null
)
{
throw
new
IOException
();
}
return
true
;
}
...
...
@@ -41,10 +43,11 @@ public class TestTryCatch extends AbstractTest {
try
{
return
exc
(
obj
);
}
catch
(
Exception
e
)
{
if
(
obj
!=
null
)
if
(
obj
!=
null
)
{
return
true
;
else
}
else
{
return
false
;
}
}
}
...
...
@@ -78,8 +81,9 @@ public class TestTryCatch extends AbstractTest {
try
{
res
=
""
+
exc
(
obj
);
boolean
f
=
exc2
(
"a"
);
if
(!
f
)
if
(!
f
)
{
res
=
"f == false"
;
}
}
catch
(
Exception
e
)
{
res
=
"exc"
;
}
...
...
@@ -95,8 +99,9 @@ public class TestTryCatch extends AbstractTest {
}
catch
(
IOException
e
)
{
res
=
true
;
}
catch
(
Throwable
e
)
{
if
(
obj
==
null
)
if
(
obj
==
null
)
{
obj
=
new
Object
();
}
}
}
}
...
...
@@ -112,8 +117,9 @@ public class TestTryCatch extends AbstractTest {
res
=
true
;
obj
=
new
Object
();
}
catch
(
Throwable
e
)
{
if
(
obj
==
null
)
if
(
obj
==
null
)
{
res
=
false
;
}
}
}
}
...
...
@@ -137,16 +143,18 @@ public class TestTryCatch extends AbstractTest {
}
catch
(
Exception
e
)
{
e
.
toString
();
}
finally
{
if
(!
mDiscovering
)
if
(!
mDiscovering
)
{
mDiscovering
=
true
;
}
}
return
mDiscovering
;
}
private
static
boolean
testSynchronize
(
Object
obj
)
throws
InterruptedException
{
synchronized
(
obj
)
{
if
(
obj
instanceof
String
)
if
(
obj
instanceof
String
)
{
return
false
;
}
obj
.
wait
(
5
);
}
return
true
;
...
...
@@ -171,8 +179,9 @@ public class TestTryCatch extends AbstractTest {
public
int
catchInLoop
(
int
i
,
int
j
)
{
while
(
true
)
{
try
{
while
(
i
<
j
)
while
(
i
<
j
)
{
i
=
j
++
/
i
;
}
}
catch
(
RuntimeException
e
)
{
i
=
10
;
continue
;
...
...
jadx-samples/src/main/java/jadx/samples/TestTypeResolver2.java
View file @
f2aa4cd1
...
...
@@ -7,7 +7,7 @@ package jadx.samples;
*/
public
class
TestTypeResolver2
extends
AbstractTest
{
private
static
String
result
=
""
;
private
static
String
result
=
""
;
public
void
testOverloadedMethods
()
{
Object
s1
=
"The"
;
...
...
settings.gradle
View file @
f2aa4cd1
rootProject
.
name
=
'jadx'
include
'jadx-core'
,
'jadx-samples'
,
'jadx-cli'
,
'jadx-gui'
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