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
e3606d1b
Commit
e3606d1b
authored
Jan 03, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reformat code (force braces)
parent
ab593e3c
Hide whitespace changes
Inline
Side-by-side
Showing
65 changed files
with
687 additions
and
419 deletions
+687
-419
JavaPackage.java
jadx-core/src/main/java/jadx/api/JavaPackage.java
+7
-4
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+13
-6
ClspGraph.java
jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
+2
-1
NClass.java
jadx-core/src/main/java/jadx/core/clsp/NClass.java
+7
-4
AnnotationGen.java
jadx-core/src/main/java/jadx/core/codegen/AnnotationGen.java
+32
-25
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+34
-28
CodeWriter.java
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
+7
-4
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+20
-15
TypeGen.java
jadx-core/src/main/java/jadx/core/codegen/TypeGen.java
+7
-5
AttrNode.java
...core/src/main/java/jadx/core/dex/attributes/AttrNode.java
+2
-1
AttributeType.java
...src/main/java/jadx/core/dex/attributes/AttributeType.java
+2
-1
AttributesList.java
...rc/main/java/jadx/core/dex/attributes/AttributesList.java
+32
-20
BlockRegState.java
...src/main/java/jadx/core/dex/attributes/BlockRegState.java
+2
-1
DeclareVariableAttr.java
...in/java/jadx/core/dex/attributes/DeclareVariableAttr.java
+2
-1
EnumClassAttr.java
...src/main/java/jadx/core/dex/attributes/EnumClassAttr.java
+3
-2
JumpAttribute.java
...src/main/java/jadx/core/dex/attributes/JumpAttribute.java
+9
-3
LoopAttr.java
...core/src/main/java/jadx/core/dex/attributes/LoopAttr.java
+4
-2
AccessInfo.java
jadx-core/src/main/java/jadx/core/dex/info/AccessInfo.java
+36
-33
ClassInfo.java
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
+7
-5
FieldInfo.java
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
+15
-6
MethodInfo.java
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
+18
-6
InsnDecoder.java
...src/main/java/jadx/core/dex/instructions/InsnDecoder.java
+16
-8
InvokeNode.java
.../src/main/java/jadx/core/dex/instructions/InvokeNode.java
+2
-1
SwitchNode.java
.../src/main/java/jadx/core/dex/instructions/SwitchNode.java
+2
-1
PrimitiveType.java
...n/java/jadx/core/dex/instructions/args/PrimitiveType.java
+6
-4
RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+19
-8
TypedVar.java
...c/main/java/jadx/core/dex/instructions/args/TypedVar.java
+17
-6
BlockNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
+22
-8
FieldNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
+6
-2
InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+27
-12
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+45
-21
RootNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
+4
-2
AnnotationsParser.java
...in/java/jadx/core/dex/nodes/parser/AnnotationsParser.java
+0
-2
DebugInfoParser.java
...main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
+12
-9
IfCondition.java
...core/src/main/java/jadx/core/dex/regions/IfCondition.java
+4
-2
IfRegion.java
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
+4
-2
LoopRegion.java
...-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
+14
-10
Region.java
jadx-core/src/main/java/jadx/core/dex/regions/Region.java
+2
-1
SwitchRegion.java
...ore/src/main/java/jadx/core/dex/regions/SwitchRegion.java
+2
-1
ExceptionHandler.java
...rc/main/java/jadx/core/dex/trycatch/ExceptionHandler.java
+15
-5
ConstInlinerVisitor.java
...main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
+13
-10
DepthTraverser.java
.../src/main/java/jadx/core/dex/visitors/DepthTraverser.java
+4
-2
DotGraphVisitor.java
...src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
+20
-13
FallbackModeVisitor.java
...main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
+2
-2
CheckRegions.java
...ain/java/jadx/core/dex/visitors/regions/CheckRegions.java
+8
-5
CleanRegions.java
...ain/java/jadx/core/dex/visitors/regions/CleanRegions.java
+4
-4
DepthRegionTraverser.java
.../jadx/core/dex/visitors/regions/DepthRegionTraverser.java
+2
-1
ProcessVariables.java
...java/jadx/core/dex/visitors/regions/ProcessVariables.java
+8
-5
RegionMakerVisitor.java
...va/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
+2
-2
RegionStack.java
...main/java/jadx/core/dex/visitors/regions/RegionStack.java
+12
-7
FinishTypeResolver.java
...dx/core/dex/visitors/typeresolver/FinishTypeResolver.java
+16
-8
TypeResolver.java
...ava/jadx/core/dex/visitors/typeresolver/TypeResolver.java
+8
-5
PostTypeResolver.java
...re/dex/visitors/typeresolver/finish/PostTypeResolver.java
+12
-6
SelectTypeVisitor.java
...e/dex/visitors/typeresolver/finish/SelectTypeVisitor.java
+2
-1
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+29
-22
ErrorsCounter.java
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
+3
-2
InsnUtils.java
jadx-core/src/main/java/jadx/core/utils/InsnUtils.java
+5
-4
InstructionRemover.java
...ore/src/main/java/jadx/core/utils/InstructionRemover.java
+4
-2
RegionUtils.java
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
+29
-19
StringUtils.java
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
+2
-2
Utils.java
jadx-core/src/main/java/jadx/core/utils/Utils.java
+16
-12
InputFile.java
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
+2
-2
TestStringBuilderElimination.java
...ava/jadx/tests/internal/TestStringBuilderElimination.java
+2
-2
TestSwitchLabels.java
...e/src/test/java/jadx/tests/internal/TestSwitchLabels.java
+1
-2
TestInline3.java
...src/test/java/jadx/tests/internal/inline/TestInline3.java
+1
-1
No files found.
jadx-core/src/main/java/jadx/api/JavaPackage.java
View file @
e3606d1b
...
...
@@ -26,11 +26,14 @@ public final class JavaPackage implements Comparable<JavaPackage> {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
JavaPackage
that
=
(
JavaPackage
)
o
;
if
(!
name
.
equals
(
that
.
name
))
return
false
;
return
true
;
return
name
.
equals
(
that
.
name
);
}
@Override
...
...
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
e3606d1b
...
...
@@ -37,10 +37,12 @@ public class Jadx {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Jadx
.
class
);
static
{
if
(
Consts
.
DEBUG
)
if
(
Consts
.
DEBUG
)
{
LOG
.
info
(
"debug enabled"
);
if
(
Jadx
.
class
.
desiredAssertionStatus
())
}
if
(
Jadx
.
class
.
desiredAssertionStatus
())
{
LOG
.
info
(
"assertions enabled"
);
}
}
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
IJadxArgs
args
,
File
outDir
)
{
...
...
@@ -52,8 +54,9 @@ public class Jadx {
passes
.
add
(
new
TypeResolver
());
if
(
args
.
isRawCFGOutput
())
if
(
args
.
isRawCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
,
true
));
}
passes
.
add
(
new
ConstInlinerVisitor
());
passes
.
add
(
new
FinishTypeResolver
());
...
...
@@ -61,8 +64,9 @@ public class Jadx {
passes
.
add
(
new
ModVisitor
());
passes
.
add
(
new
EnumVisitor
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
));
}
passes
.
add
(
new
RegionMakerVisitor
());
passes
.
add
(
new
PostRegionVisitor
());
...
...
@@ -71,8 +75,10 @@ public class Jadx {
passes
.
add
(
new
SimplifyVisitor
());
passes
.
add
(
new
ProcessVariables
());
passes
.
add
(
new
CheckRegions
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
true
));
}
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
ClassModifier
());
...
...
@@ -88,8 +94,9 @@ public class Jadx {
while
(
resources
.
hasMoreElements
())
{
Manifest
manifest
=
new
Manifest
(
resources
.
nextElement
().
openStream
());
String
ver
=
manifest
.
getMainAttributes
().
getValue
(
"jadx-version"
);
if
(
ver
!=
null
)
if
(
ver
!=
null
)
{
return
ver
;
}
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Can't get manifest file"
,
e
);
...
...
jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
View file @
e3606d1b
...
...
@@ -82,8 +82,9 @@ public class ClspGraph {
return
name
;
}
else
{
String
r
=
searchCommonParent
(
anc
,
p
);
if
(
r
!=
null
)
if
(
r
!=
null
)
{
return
r
;
}
}
}
return
null
;
...
...
jadx-core/src/main/java/jadx/core/clsp/NClass.java
View file @
e3606d1b
...
...
@@ -41,11 +41,14 @@ public class NClass {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
NClass
nClass
=
(
NClass
)
o
;
if
(!
name
.
equals
(
nClass
.
name
))
return
false
;
return
true
;
return
name
.
equals
(
nClass
.
name
);
}
@Override
...
...
jadx-core/src/main/java/jadx/core/codegen/AnnotationGen.java
View file @
e3606d1b
...
...
@@ -43,9 +43,9 @@ public class AnnotationGen {
public
void
addForParameter
(
CodeWriter
code
,
MethodParameters
paramsAnnotations
,
int
n
)
{
AnnotationsList
aList
=
paramsAnnotations
.
getParamList
().
get
(
n
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
;
}
for
(
Annotation
a
:
aList
.
getAll
())
{
code
.
add
(
formatAnnotation
(
a
));
code
.
add
(
' '
);
...
...
@@ -54,9 +54,9 @@ public class AnnotationGen {
private
void
add
(
IAttributeNode
node
,
CodeWriter
code
)
{
AnnotationsList
aList
=
(
AnnotationsList
)
node
.
getAttributes
().
get
(
AttributeType
.
ANNOTATION_LIST
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
;
}
for
(
Annotation
a
:
aList
.
getAll
())
{
String
aCls
=
a
.
getAnnotationClass
();
if
(
aCls
.
startsWith
(
Consts
.
DALVIK_ANNOTATION_PKG
))
{
...
...
@@ -86,8 +86,9 @@ public class AnnotationGen {
code
.
add
(
e
.
getKey
());
code
.
add
(
" = "
);
code
.
add
(
encValueToString
(
e
.
getValue
()));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
", "
);
}
}
}
code
.
add
(
')'
);
...
...
@@ -104,8 +105,9 @@ public class AnnotationGen {
for
(
Iterator
<
ArgType
>
it
=
((
List
<
ArgType
>)
exs
).
iterator
();
it
.
hasNext
();
)
{
ArgType
ex
=
it
.
next
();
code
.
add
(
TypeGen
.
translate
(
classGen
,
ex
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
", "
);
}
}
}
}
...
...
@@ -122,31 +124,39 @@ public class AnnotationGen {
// TODO: refactor this boilerplate code
@SuppressWarnings
(
"unchecked"
)
public
String
encValueToString
(
Object
val
)
{
if
(
val
==
null
)
if
(
val
==
null
)
{
return
"null"
;
if
(
val
instanceof
String
)
}
if
(
val
instanceof
String
)
{
return
StringUtils
.
unescapeString
((
String
)
val
);
if
(
val
instanceof
Integer
)
}
if
(
val
instanceof
Integer
)
{
return
TypeGen
.
formatInteger
((
Integer
)
val
);
if
(
val
instanceof
Character
)
}
if
(
val
instanceof
Character
)
{
return
StringUtils
.
unescapeChar
((
Character
)
val
);
if
(
val
instanceof
Boolean
)
}
if
(
val
instanceof
Boolean
)
{
return
Boolean
.
TRUE
.
equals
(
val
)
?
"true"
:
"false"
;
if
(
val
instanceof
Float
)
}
if
(
val
instanceof
Float
)
{
return
TypeGen
.
formatFloat
((
Float
)
val
);
if
(
val
instanceof
Double
)
}
if
(
val
instanceof
Double
)
{
return
TypeGen
.
formatDouble
((
Double
)
val
);
if
(
val
instanceof
Long
)
}
if
(
val
instanceof
Long
)
{
return
TypeGen
.
formatLong
((
Long
)
val
);
if
(
val
instanceof
Short
)
}
if
(
val
instanceof
Short
)
{
return
TypeGen
.
formatShort
((
Short
)
val
);
if
(
val
instanceof
Byte
)
}
if
(
val
instanceof
Byte
)
{
return
TypeGen
.
formatByte
((
Byte
)
val
);
if
(
val
instanceof
ArgType
)
}
if
(
val
instanceof
ArgType
)
{
return
TypeGen
.
translate
(
classGen
,
(
ArgType
)
val
)
+
".class"
;
}
if
(
val
instanceof
FieldInfo
)
{
// must be a static field
FieldInfo
field
=
(
FieldInfo
)
val
;
...
...
@@ -158,7 +168,6 @@ public class AnnotationGen {
return
classGen
.
useClass
(
field
.
getDeclClass
())
+
'.'
+
field
.
getName
();
}
}
if
(
val
instanceof
List
)
{
StringBuilder
str
=
new
StringBuilder
();
str
.
append
(
'{'
);
...
...
@@ -166,19 +175,17 @@ public class AnnotationGen {
for
(
Iterator
<
Object
>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
Object
obj
=
it
.
next
();
str
.
append
(
encValueToString
(
obj
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
str
.
append
(
", "
);
}
}
str
.
append
(
'}'
);
return
str
.
toString
();
}
if
(
val
instanceof
Annotation
)
{
return
formatAnnotation
((
Annotation
)
val
).
toString
();
}
// TODO: also can be method values
throw
new
JadxRuntimeException
(
"Can't decode value: "
+
val
+
" ("
+
val
.
getClass
()
+
")"
);
}
}
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
e3606d1b
...
...
@@ -90,12 +90,12 @@ public class ClassGen {
}
public
void
addClassCode
(
CodeWriter
code
)
throws
CodegenException
{
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
return
;
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
INCONSISTENT_CODE
))
}
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
INCONSISTENT_CODE
))
{
code
.
startLine
(
"// jadx: inconsistent code"
);
}
makeClassDeclaration
(
code
);
makeClassBody
(
code
);
code
.
newLine
();
...
...
@@ -113,8 +113,9 @@ public class ClassGen {
insertSourceFileInfo
(
clsCode
,
cls
);
clsCode
.
startLine
(
af
.
makeString
());
if
(
af
.
isInterface
())
{
if
(
af
.
isAnnotation
())
if
(
af
.
isAnnotation
())
{
clsCode
.
add
(
'@'
);
}
clsCode
.
add
(
"interface "
);
}
else
if
(
af
.
isEnum
())
{
clsCode
.
add
(
"enum "
);
...
...
@@ -134,28 +135,30 @@ public class ClassGen {
}
if
(
cls
.
getInterfaces
().
size
()
>
0
&&
!
af
.
isAnnotation
())
{
if
(
cls
.
getAccessFlags
().
isInterface
())
if
(
cls
.
getAccessFlags
().
isInterface
())
{
clsCode
.
add
(
"extends "
);
else
}
else
{
clsCode
.
add
(
"implements "
);
}
for
(
Iterator
<
ClassInfo
>
it
=
cls
.
getInterfaces
().
iterator
();
it
.
hasNext
();
)
{
ClassInfo
interf
=
it
.
next
();
clsCode
.
add
(
useClass
(
interf
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
clsCode
.
add
(
", "
);
}
}
if
(!
cls
.
getInterfaces
().
isEmpty
())
if
(!
cls
.
getInterfaces
().
isEmpty
())
{
clsCode
.
add
(
' '
);
}
}
clsCode
.
attachAnnotation
(
cls
);
}
public
boolean
makeGenericMap
(
CodeWriter
code
,
Map
<
ArgType
,
List
<
ArgType
>>
gmap
)
{
if
(
gmap
==
null
||
gmap
.
isEmpty
())
if
(
gmap
==
null
||
gmap
.
isEmpty
())
{
return
false
;
}
code
.
add
(
'<'
);
int
i
=
0
;
for
(
Entry
<
ArgType
,
List
<
ArgType
>>
e
:
gmap
.
entrySet
())
{
...
...
@@ -186,14 +189,15 @@ public class ClassGen {
CodeWriter
mthsCode
=
makeMethods
(
clsCode
,
cls
.
getMethods
());
CodeWriter
fieldsCode
=
makeFields
(
clsCode
,
cls
,
cls
.
getFields
());
clsCode
.
add
(
fieldsCode
);
if
(
fieldsCode
.
notEmpty
()
&&
mthsCode
.
notEmpty
())
if
(
fieldsCode
.
notEmpty
()
&&
mthsCode
.
notEmpty
())
{
clsCode
.
newLine
();
}
// insert inner classes code
if
(
cls
.
getInnerClasses
().
size
()
!=
0
)
{
clsCode
.
add
(
makeInnerClasses
(
cls
,
clsCode
.
getIndent
()));
if
(
mthsCode
.
notEmpty
())
if
(
mthsCode
.
notEmpty
())
{
clsCode
.
newLine
();
}
}
clsCode
.
add
(
mthsCode
);
clsCode
.
startLine
(
'}'
);
...
...
@@ -202,12 +206,11 @@ public class ClassGen {
private
CodeWriter
makeInnerClasses
(
ClassNode
cls
,
int
indent
)
throws
CodegenException
{
CodeWriter
innerClsCode
=
new
CodeWriter
(
indent
+
1
);
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
{
if
(
inCls
.
isAnonymous
())
continue
;
ClassGen
inClGen
=
new
ClassGen
(
inCls
,
parentGen
==
null
?
this
:
parentGen
,
fallback
);
inClGen
.
addClassCode
(
innerClsCode
);
imports
.
addAll
(
inClGen
.
getImports
());
if
(!
inCls
.
isAnonymous
())
{
ClassGen
inClGen
=
new
ClassGen
(
inCls
,
parentGen
==
null
?
this
:
parentGen
,
fallback
);
inClGen
.
addClassCode
(
innerClsCode
);
imports
.
addAll
(
inClGen
.
getImports
());
}
}
return
innerClsCode
;
}
...
...
@@ -276,26 +279,28 @@ public class ClassGen {
igen
=
new
InsnGen
(
mthGen
,
enumFields
.
getStaticMethod
(),
false
);
}
code
.
add
(
igen
.
arg
(
arg
));
if
(
aIt
.
hasNext
())
if
(
aIt
.
hasNext
())
{
code
.
add
(
", "
);
}
}
code
.
add
(
')'
);
}
if
(
f
.
getCls
()
!=
null
)
{
new
ClassGen
(
f
.
getCls
(),
this
,
fallback
).
makeClassBody
(
code
);
}
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
','
);
}
}
if
(
enumFields
.
getFields
().
isEmpty
())
if
(
enumFields
.
getFields
().
isEmpty
())
{
code
.
startLine
();
}
code
.
add
(
';'
);
code
.
newLine
();
}
for
(
FieldNode
f
:
fields
)
{
if
(
f
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
if
(
f
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
continue
;
}
annotationGen
.
addForField
(
code
,
f
);
...
...
@@ -338,10 +343,11 @@ public class ClassGen {
sb
.
append
(
", "
);
}
ArgType
gt
=
generics
[
i
];
if
(
gt
.
isTypeKnown
())
if
(
gt
.
isTypeKnown
())
{
sb
.
append
(
TypeGen
.
translate
(
this
,
gt
));
else
}
else
{
sb
.
append
(
'?'
);
}
}
sb
.
append
(
'>'
);
return
sb
.
toString
();
...
...
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
View file @
e3606d1b
...
...
@@ -59,8 +59,9 @@ public class CodeWriter {
public
CodeWriter
startLine
(
int
ind
,
String
str
)
{
addLine
();
buf
.
append
(
indentStr
);
for
(
int
i
=
0
;
i
<
ind
;
i
++)
for
(
int
i
=
0
;
i
<
ind
;
i
++)
{
buf
.
append
(
INDENT
);
}
buf
.
append
(
str
);
return
this
;
}
...
...
@@ -209,10 +210,11 @@ public class CodeWriter {
if
(
name
.
length
()
>
MAX_FILENAME_LENGTH
)
{
int
dotIndex
=
name
.
indexOf
(
'.'
);
int
cutAt
=
MAX_FILENAME_LENGTH
-
name
.
length
()
+
dotIndex
-
1
;
if
(
cutAt
<=
0
)
if
(
cutAt
<=
0
)
{
name
=
name
.
substring
(
0
,
MAX_FILENAME_LENGTH
-
1
);
else
}
else
{
name
=
name
.
substring
(
0
,
cutAt
)
+
name
.
substring
(
dotIndex
);
}
file
=
new
File
(
file
.
getParentFile
(),
name
);
}
...
...
@@ -226,8 +228,9 @@ public class CodeWriter {
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Save file error"
,
e
);
}
finally
{
if
(
out
!=
null
)
if
(
out
!=
null
)
{
out
.
close
();
}
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
e3606d1b
...
...
@@ -127,9 +127,9 @@ public class MethodGen {
RegisterArg
arg
=
it
.
next
();
// add argument annotation
if
(
paramsAnnotation
!=
null
)
if
(
paramsAnnotation
!=
null
)
{
annotationGen
.
addForParameter
(
argsCode
,
paramsAnnotation
,
i
);
}
if
(!
it
.
hasNext
()
&&
mth
.
getAccessFlags
().
isVarArgs
())
{
// change last array argument to varargs
ArgType
type
=
arg
.
getType
();
...
...
@@ -148,8 +148,9 @@ public class MethodGen {
argsCode
.
add
(
makeArgName
(
arg
));
i
++;
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
argsCode
.
add
(
", "
);
}
}
return
argsCode
;
}
...
...
@@ -163,24 +164,27 @@ public class MethodGen {
String
name
=
arg
.
getTypedVar
().
getName
();
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
fallback
)
{
if
(
name
!=
null
)
if
(
name
!=
null
)
{
return
base
+
"_"
+
name
;
else
}
else
{
return
base
;
}
}
else
{
if
(
name
!=
null
)
{
if
(
name
.
equals
(
"this"
))
if
(
name
.
equals
(
"this"
))
{
return
name
;
else
if
(
Consts
.
DEBUG
)
}
else
if
(
Consts
.
DEBUG
)
{
return
name
+
"_"
+
base
;
else
}
else
{
return
name
;
}
}
else
{
ArgType
type
=
arg
.
getType
();
if
(
type
.
isPrimitive
())
if
(
type
.
isPrimitive
())
{
return
base
+
type
.
getPrimitiveType
().
getShortName
().
toLowerCase
();
else
}
else
{
return
base
+
"_"
+
Utils
.
escape
(
TypeGen
.
translate
(
classGen
,
arg
.
getType
()));
}
}
}
}
...
...
@@ -193,9 +197,9 @@ public class MethodGen {
*/
public
String
assignArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
if
(
varNames
.
add
(
name
)
||
fallback
)
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
getTypedVar
().
setName
(
name
);
return
name
;
...
...
@@ -203,9 +207,9 @@ public class MethodGen {
public
String
assignNamedArg
(
NamedArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
varNames
.
add
(
name
)
||
fallback
)
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
setName
(
name
);
return
name
;
...
...
@@ -298,8 +302,9 @@ public class MethodGen {
try
{
if
(
insnGen
.
makeInsn
(
insn
,
code
))
{
CatchAttr
catchAttr
=
(
CatchAttr
)
attrs
.
get
(
AttributeType
.
CATCH_BLOCK
);
if
(
catchAttr
!=
null
)
if
(
catchAttr
!=
null
)
{
code
.
add
(
"\t //"
+
catchAttr
);
}
}
}
catch
(
CodegenException
e
)
{
code
.
startLine
(
"// error: "
+
insn
);
...
...
jadx-core/src/main/java/jadx/core/codegen/TypeGen.java
View file @
e3606d1b
...
...
@@ -10,9 +10,9 @@ public class TypeGen {
public
static
String
translate
(
ClassGen
clsGen
,
ArgType
type
)
{
final
PrimitiveType
stype
=
type
.
getPrimitiveType
();
if
(
stype
==
null
)
if
(
stype
==
null
)
{
return
type
.
toString
();
}
if
(
stype
==
PrimitiveType
.
OBJECT
)
{
return
clsGen
.
useClass
(
type
);
}
...
...
@@ -69,8 +69,9 @@ public class TypeGen {
case
OBJECT:
case
ARRAY:
if
(
lit
!=
0
)
if
(
lit
!=
0
)
{
throw
new
JadxRuntimeException
(
"Wrong object literal: "
+
type
+
" = "
+
lit
);
}
return
"null"
;
default
:
...
...
@@ -100,8 +101,9 @@ public class TypeGen {
public
static
String
formatLong
(
long
lit
)
{
String
l
=
Long
.
toString
(
lit
);
if
(
lit
==
Long
.
MIN_VALUE
||
Math
.
abs
(
lit
)
>=
Integer
.
MAX_VALUE
)
if
(
lit
==
Long
.
MIN_VALUE
||
Math
.
abs
(
lit
)
>=
Integer
.
MAX_VALUE
)
{
l
+=
"L"
;
}
return
wrapNegNum
(
lit
<
0
,
l
);
}
...
...
@@ -109,6 +111,6 @@ public class TypeGen {
// if (lz)
// return "(" + str + ")";
// else
return
str
;
return
str
;
}
}
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
View file @
e3606d1b
...
...
@@ -6,8 +6,9 @@ public abstract class AttrNode implements IAttributeNode {
@Override
public
AttributesList
getAttributes
()
{
if
(
attributesList
==
null
)
if
(
attributesList
==
null
)
{
attributesList
=
new
AttributesList
();
}
return
attributesList
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeType.java
View file @
e3606d1b
...
...
@@ -38,8 +38,9 @@ public enum AttributeType {
AttributeType
[]
vals
=
AttributeType
.
values
();
for
(
int
i
=
0
;
i
<
vals
.
length
;
i
++)
{
AttributeType
type
=
vals
[
i
];
if
(
type
.
notUniq
())
if
(
type
.
notUniq
())
{
last
=
i
;
}
}
NOT_UNIQ_COUNT
=
last
+
1
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttributesList.java
View file @
e3606d1b
...
...
@@ -52,10 +52,11 @@ public final class AttributesList {
// Attributes
public
void
add
(
IAttribute
attr
)
{
if
(
attr
.
getType
().
isUniq
())
if
(
attr
.
getType
().
isUniq
())
{
uniqAttr
.
put
(
attr
.
getType
(),
attr
);
else
}
else
{
addMultiAttribute
(
attr
);
}
}
private
void
addMultiAttribute
(
IAttribute
attr
)
{
...
...
@@ -70,15 +71,17 @@ public final class AttributesList {
public
void
addAll
(
AttributesList
otherList
)
{
flags
.
addAll
(
otherList
.
flags
);
uniqAttr
.
putAll
(
otherList
.
uniqAttr
);
for
(
IAttribute
attr
:
otherList
.
attributes
)
for
(
IAttribute
attr
:
otherList
.
attributes
)
{
addMultiAttribute
(
attr
);
}
}
public
boolean
contains
(
AttributeType
type
)
{
if
(
type
.
isUniq
())
if
(
type
.
isUniq
())
{
return
uniqAttr
.
containsKey
(
type
);
else
}
else
{
return
getMultiCountInternal
(
type
)
!=
0
;
}
}
public
IAttribute
get
(
AttributeType
type
)
{
...
...
@@ -86,9 +89,11 @@ public final class AttributesList {
return
uniqAttr
.
get
(
type
);
}
else
{
if
(
getMultiCountInternal
(
type
)
!=
0
)
{
for
(
IAttribute
attr
:
attributes
)
if
(
attr
.
getType
()
==
type
)
for
(
IAttribute
attr
:
attributes
)
{
if
(
attr
.
getType
()
==
type
)
{
return
attr
;
}
}
}
return
null
;
}
...
...
@@ -104,9 +109,9 @@ public final class AttributesList {
public
Annotation
getAnnotation
(
String
cls
)
{
AnnotationsList
aList
=
(
AnnotationsList
)
get
(
AttributeType
.
ANNOTATION_LIST
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
null
;
}
return
aList
.
get
(
cls
);
}
...
...
@@ -119,8 +124,9 @@ public final class AttributesList {
}
else
{
List
<
IAttribute
>
attrs
=
new
ArrayList
<
IAttribute
>(
count
);
for
(
IAttribute
attr
:
attributes
)
{
if
(
attr
.
getType
()
==
type
)
if
(
attr
.
getType
()
==
type
)
{
attrs
.
add
(
attr
);
}
}
return
attrs
;
}
...
...
@@ -132,8 +138,9 @@ public final class AttributesList {
}
else
{
for
(
Iterator
<
IAttribute
>
it
=
attributes
.
iterator
();
it
.
hasNext
();
)
{
IAttribute
attr
=
it
.
next
();
if
(
attr
.
getType
()
==
type
)
if
(
attr
.
getType
()
==
type
)
{
it
.
remove
();
}
}
attrCount
[
type
.
ordinal
()]
=
0
;
}
...
...
@@ -143,11 +150,13 @@ public final class AttributesList {
AttributeType
type
=
attr
.
getType
();
if
(
type
.
isUniq
())
{
IAttribute
a
=
uniqAttr
.
get
(
type
);
if
(
a
==
attr
)
if
(
a
==
attr
)
{
uniqAttr
.
remove
(
type
);
}
}
else
{
if
(
getMultiCountInternal
(
type
)
==
0
)
if
(
getMultiCountInternal
(
type
)
==
0
)
{
return
;
}
for
(
Iterator
<
IAttribute
>
it
=
attributes
.
iterator
();
it
.
hasNext
();
)
{
IAttribute
a
=
it
.
next
();
...
...
@@ -168,25 +177,28 @@ public final class AttributesList {
public
List
<
String
>
getAttributeStrings
()
{
int
size
=
flags
.
size
()
+
uniqAttr
.
size
()
+
attributes
.
size
();
if
(
size
==
0
)
if
(
size
==
0
)
{
return
Collections
.
emptyList
();
}
List
<
String
>
list
=
new
ArrayList
<
String
>(
size
);
for
(
AttributeFlag
a
:
flags
)
for
(
AttributeFlag
a
:
flags
)
{
list
.
add
(
a
.
toString
());
for
(
IAttribute
a
:
uniqAttr
.
values
())
}
for
(
IAttribute
a
:
uniqAttr
.
values
())
{
list
.
add
(
a
.
toString
());
for
(
IAttribute
a
:
attributes
)
}
for
(
IAttribute
a
:
attributes
)
{
list
.
add
(
a
.
toString
());
}
return
list
;
}
@Override
public
String
toString
()
{
List
<
String
>
list
=
getAttributeStrings
();
if
(
list
.
isEmpty
())
if
(
list
.
isEmpty
())
{
return
""
;
}
return
"A:{"
+
Utils
.
listToString
(
list
)
+
"}"
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java
View file @
e3606d1b
...
...
@@ -45,8 +45,9 @@ public final class BlockRegState {
StringBuilder
str
=
new
StringBuilder
();
for
(
RegisterArg
reg
:
regs
)
{
if
(
reg
.
getTypedVar
()
!=
null
)
{
if
(
str
.
length
()
!=
0
)
if
(
str
.
length
()
!=
0
)
{
str
.
append
(
", "
);
}
str
.
append
(
reg
.
toString
());
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/DeclareVariableAttr.java
View file @
e3606d1b
...
...
@@ -24,8 +24,9 @@ public class DeclareVariableAttr implements IAttribute {
public
void
addVar
(
RegisterArg
arg
)
{
int
i
;
if
((
i
=
vars
.
indexOf
(
arg
))
!=
-
1
)
{
if
(
vars
.
get
(
i
).
getType
().
equals
(
arg
.
getType
()))
if
(
vars
.
get
(
i
).
getType
().
equals
(
arg
.
getType
()))
{
return
;
}
}
vars
.
add
(
arg
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/EnumClassAttr.java
View file @
e3606d1b
...
...
@@ -18,10 +18,11 @@ public class EnumClassAttr implements IAttribute {
public
EnumField
(
String
name
,
int
argsCount
)
{
this
.
name
=
name
;
if
(
argsCount
!=
0
)
if
(
argsCount
!=
0
)
{
this
.
args
=
new
ArrayList
<
InsnArg
>(
argsCount
);
else
}
else
{
this
.
args
=
Collections
.
emptyList
();
}
}
public
String
getName
()
{
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/JumpAttribute.java
View file @
e3606d1b
...
...
@@ -41,9 +41,15 @@ public class JumpAttribute implements IAttribute {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
JumpAttribute
other
=
(
JumpAttribute
)
obj
;
return
dest
==
other
.
dest
&&
src
==
other
.
src
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/LoopAttr.java
View file @
e3606d1b
...
...
@@ -45,9 +45,11 @@ public class LoopAttr implements IAttribute {
Set
<
BlockNode
>
inloop
=
getLoopBlocks
();
for
(
BlockNode
block
:
inloop
)
{
// exit: successor node not from this loop, (don't change to getCleanSuccessors)
for
(
BlockNode
s
:
block
.
getSuccessors
())
if
(!
inloop
.
contains
(
s
)
&&
!
s
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
for
(
BlockNode
s
:
block
.
getSuccessors
())
{
if
(!
inloop
.
contains
(
s
)
&&
!
s
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
nodes
.
add
(
block
);
}
}
}
return
nodes
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/info/AccessInfo.java
View file @
e3606d1b
...
...
@@ -24,10 +24,11 @@ public class AccessInfo {
}
public
AccessInfo
remove
(
int
flag
)
{
if
(
containsFlag
(
flag
))
if
(
containsFlag
(
flag
))
{
return
new
AccessInfo
(
accFlags
-
flag
,
type
);
else
}
else
{
return
this
;
}
}
public
AccessInfo
getVisibility
()
{
...
...
@@ -111,71 +112,73 @@ public class AccessInfo {
public
String
makeString
()
{
StringBuilder
code
=
new
StringBuilder
();
if
(
isPublic
())
if
(
isPublic
())
{
code
.
append
(
"public "
);
if
(
isPrivate
())
}
if
(
isPrivate
())
{
code
.
append
(
"private "
);
if
(
isProtected
())
}
if
(
isProtected
())
{
code
.
append
(
"protected "
);
if
(
isStatic
())
}
if
(
isStatic
())
{
code
.
append
(
"static "
);
if
(
isFinal
())
}
if
(
isFinal
())
{
code
.
append
(
"final "
);
if
(
isAbstract
())
}
if
(
isAbstract
())
{
code
.
append
(
"abstract "
);
if
(
isNative
())
}
if
(
isNative
())
{
code
.
append
(
"native "
);
}
switch
(
type
)
{
case
METHOD:
if
(
isSynchronized
())
if
(
isSynchronized
())
{
code
.
append
(
"synchronized "
);
if
(
isBridge
())
}
if
(
isBridge
())
{
code
.
append
(
"/* bridge */ "
);
}
if
(
Consts
.
DEBUG
)
{
if
(
isVarArgs
())
if
(
isVarArgs
())
{
code
.
append
(
"/* varargs */ "
);
}
}
break
;
case
FIELD:
if
(
isVolatile
())
if
(
isVolatile
())
{
code
.
append
(
"volatile "
);
if
(
isTransient
())
}
if
(
isTransient
())
{
code
.
append
(
"transient "
);
}
break
;
case
CLASS:
if
((
accFlags
&
AccessFlags
.
ACC_STRICT
)
!=
0
)
if
((
accFlags
&
AccessFlags
.
ACC_STRICT
)
!=
0
)
{
code
.
append
(
"strict "
);
}
if
(
Consts
.
DEBUG
)
{
if
((
accFlags
&
AccessFlags
.
ACC_SUPER
)
!=
0
)
if
((
accFlags
&
AccessFlags
.
ACC_SUPER
)
!=
0
)
{
code
.
append
(
"/* super */ "
);
if
((
accFlags
&
AccessFlags
.
ACC_ENUM
)
!=
0
)
}
if
((
accFlags
&
AccessFlags
.
ACC_ENUM
)
!=
0
)
{
code
.
append
(
"/* enum */ "
);
}
}
break
;
}
if
(
isSynthetic
())
if
(
isSynthetic
())
{
code
.
append
(
"/* synthetic */ "
);
}
return
code
.
toString
();
}
public
String
rawString
()
{
switch
(
type
){
switch
(
type
)
{
case
CLASS:
return
AccessFlags
.
classString
(
accFlags
);
case
FIELD:
...
...
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
View file @
e3606d1b
...
...
@@ -14,13 +14,13 @@ public final class ClassInfo {
private
static
final
Map
<
ArgType
,
ClassInfo
>
CLASSINFO_CACHE
=
new
WeakHashMap
<
ArgType
,
ClassInfo
>();
public
static
ClassInfo
fromDex
(
DexNode
dex
,
int
clsIndex
)
{
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
{
return
null
;
}
ArgType
type
=
dex
.
getType
(
clsIndex
);
if
(
type
.
isArray
())
if
(
type
.
isArray
())
{
type
=
ArgType
.
OBJECT
;
}
return
fromType
(
type
);
}
...
...
@@ -153,7 +153,9 @@ public final class ClassInfo {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
instanceof
ClassInfo
)
{
ClassInfo
other
=
(
ClassInfo
)
obj
;
return
this
.
getFullName
().
equals
(
other
.
getFullName
());
...
...
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
View file @
e3606d1b
...
...
@@ -41,13 +41,22 @@ public class FieldInfo {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
FieldInfo
fieldInfo
=
(
FieldInfo
)
o
;
if
(!
name
.
equals
(
fieldInfo
.
name
))
return
false
;
if
(!
type
.
equals
(
fieldInfo
.
type
))
return
false
;
if
(!
declClass
.
equals
(
fieldInfo
.
declClass
))
return
false
;
if
(!
name
.
equals
(
fieldInfo
.
name
))
{
return
false
;
}
if
(!
type
.
equals
(
fieldInfo
.
type
))
{
return
false
;
}
if
(!
declClass
.
equals
(
fieldInfo
.
declClass
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
View file @
e3606d1b
...
...
@@ -98,13 +98,25 @@ public final class MethodInfo {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
MethodInfo
other
=
(
MethodInfo
)
obj
;
if
(!
shortId
.
equals
(
other
.
shortId
))
return
false
;
if
(!
retType
.
equals
(
other
.
retType
))
return
false
;
if
(!
declClass
.
equals
(
other
.
declClass
))
return
false
;
if
(!
shortId
.
equals
(
other
.
shortId
))
{
return
false
;
}
if
(!
retType
.
equals
(
other
.
retType
))
{
return
false
;
}
if
(!
declClass
.
equals
(
other
.
declClass
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java
View file @
e3606d1b
...
...
@@ -578,14 +578,16 @@ public class InsnDecoder {
targets
=
ps
.
getTargets
();
keys
=
new
Object
[
targets
.
length
];
int
k
=
ps
.
getFirstKey
();
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
keys
[
i
]
=
k
++;
}
}
else
{
SparseSwitchPayloadDecodedInstruction
ss
=
(
SparseSwitchPayloadDecodedInstruction
)
payload
;
targets
=
ss
.
getTargets
();
keys
=
new
Object
[
targets
.
length
];
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
keys
[
i
]
=
ss
.
getKeys
()[
i
];
}
}
// convert from relative to absolute offsets
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
...
...
@@ -612,8 +614,9 @@ public class InsnDecoder {
r
++;
}
}
else
{
for
(
int
i
=
0
;
i
<
insn
.
getRegisterCount
();
i
++)
for
(
int
i
=
0
;
i
<
insn
.
getRegisterCount
();
i
++)
{
regs
[
i
]
=
InsnArg
.
reg
(
insn
,
i
,
elType
);
}
}
return
insn
(
InsnType
.
FILLED_NEW_ARRAY
,
resReg
==
-
1
?
null
:
InsnArg
.
reg
(
resReg
,
arrType
),
...
...
@@ -689,8 +692,9 @@ public class InsnDecoder {
InsnNode
node
=
new
InsnNode
(
type
,
args
==
null
?
0
:
args
.
length
);
node
.
setResult
(
res
);
if
(
args
!=
null
)
{
for
(
InsnArg
arg
:
args
)
for
(
InsnArg
arg
:
args
)
{
node
.
addArg
(
arg
);
}
}
return
node
;
}
...
...
@@ -711,19 +715,23 @@ public class InsnDecoder {
public
static
int
getPrevInsnOffset
(
Object
[]
insnArr
,
int
offset
)
{
int
i
=
offset
-
1
;
while
(
i
>=
0
&&
insnArr
[
i
]
==
null
)
while
(
i
>=
0
&&
insnArr
[
i
]
==
null
)
{
i
--;
if
(
i
<
0
)
}
if
(
i
<
0
)
{
return
-
1
;
}
return
i
;
}
public
static
int
getNextInsnOffset
(
Object
[]
insnArr
,
int
offset
)
{
int
i
=
offset
+
1
;
while
(
i
<
insnArr
.
length
&&
insnArr
[
i
]
==
null
)
while
(
i
<
insnArr
.
length
&&
insnArr
[
i
]
==
null
)
{
i
++;
if
(
i
>=
insnArr
.
length
)
}
if
(
i
>=
insnArr
.
length
)
{
return
-
1
;
}
return
i
;
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java
View file @
e3606d1b
...
...
@@ -19,8 +19,9 @@ public class InvokeNode extends InsnNode {
this
.
mth
=
mth
;
this
.
type
=
type
;
if
(
resReg
>=
0
)
if
(
resReg
>=
0
)
{
setResult
(
InsnArg
.
reg
(
resReg
,
mth
.
getReturnType
()));
}
int
k
=
isRange
?
insn
.
getA
()
:
0
;
if
(
type
!=
InvokeType
.
STATIC
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
View file @
e3606d1b
...
...
@@ -42,8 +42,9 @@ public class SwitchNode extends InsnNode {
targ
.
append
(
'['
);
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
targ
.
append
(
InsnUtils
.
formatOffset
(
targets
[
i
]));
if
(
i
<
targets
.
length
-
1
)
if
(
i
<
targets
.
length
-
1
)
{
targ
.
append
(
", "
);
}
}
targ
.
append
(
']'
);
return
super
.
toString
()
+
" k:"
+
Arrays
.
toString
(
keys
)
+
" t:"
+
targ
;
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/PrimitiveType.java
View file @
e3606d1b
...
...
@@ -30,17 +30,19 @@ public enum PrimitiveType {
}
public
static
PrimitiveType
getWidest
(
PrimitiveType
a
,
PrimitiveType
b
)
{
if
(
a
.
ordinal
()
>
b
.
ordinal
())
if
(
a
.
ordinal
()
>
b
.
ordinal
())
{
return
a
;
else
}
else
{
return
b
;
}
}
public
static
PrimitiveType
getSmaller
(
PrimitiveType
a
,
PrimitiveType
b
)
{
if
(
a
.
ordinal
()
<
b
.
ordinal
())
if
(
a
.
ordinal
()
<
b
.
ordinal
())
{
return
a
;
else
}
else
{
return
b
;
}
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
View file @
e3606d1b
...
...
@@ -40,12 +40,13 @@ public class RegisterArg extends InsnArg {
public
InsnNode
getAssignInsn
()
{
for
(
InsnArg
arg
:
getTypedVar
().
getUseList
())
{
InsnNode
assignInsn
=
arg
.
getParentInsn
();
if
(
assignInsn
==
null
)
if
(
assignInsn
==
null
)
{
// assign as function argument
return
null
;
else
if
(
assignInsn
.
getResult
()
!=
null
&&
assignInsn
.
getResult
().
getRegNum
()
==
regNum
)
}
else
if
(
assignInsn
.
getResult
()
!=
null
&&
assignInsn
.
getResult
().
getRegNum
()
==
regNum
)
{
return
assignInsn
;
}
}
return
null
;
}
...
...
@@ -109,12 +110,22 @@ public class RegisterArg extends InsnArg {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
RegisterArg
other
=
(
RegisterArg
)
obj
;
if
(
regNum
!=
other
.
regNum
)
return
false
;
if
(!
typedVar
.
equals
(
other
.
typedVar
))
return
false
;
if
(
regNum
!=
other
.
regNum
)
{
return
false
;
}
if
(!
typedVar
.
equals
(
other
.
typedVar
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java
View file @
e3606d1b
...
...
@@ -70,13 +70,23 @@ public class TypedVar {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(!(
obj
instanceof
TypedVar
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(!(
obj
instanceof
TypedVar
))
{
return
false
;
}
TypedVar
other
=
(
TypedVar
)
obj
;
if
(!
type
.
equals
(
other
.
type
))
return
false
;
if
(!
type
.
equals
(
other
.
type
))
{
return
false
;
}
if
(
name
==
null
)
{
if
(
other
.
name
!=
null
)
return
false
;
if
(
other
.
name
!=
null
)
{
return
false
;
}
}
else
if
(!
name
.
equals
(
other
.
name
))
{
return
false
;
}
...
...
@@ -86,8 +96,9 @@ public class TypedVar {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
name
!=
null
)
if
(
name
!=
null
)
{
sb
.
append
(
'\''
).
append
(
name
).
append
(
"' "
);
}
sb
.
append
(
type
);
return
sb
.
toString
();
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
View file @
e3606d1b
...
...
@@ -72,15 +72,17 @@ public class BlockNode extends AttrNode implements IBlock {
LoopAttr
loop
=
(
LoopAttr
)
block
.
getAttributes
().
get
(
AttributeType
.
LOOP
);
if
(
loop
==
null
)
{
for
(
BlockNode
b
:
sucList
)
{
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
nodes
.
add
(
b
);
}
}
}
else
{
for
(
BlockNode
b
:
sucList
)
{
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
// don't follow back edge
if
(
loop
.
getStart
()
==
b
&&
loop
.
getEnd
()
==
block
)
if
(
loop
.
getStart
()
==
b
&&
loop
.
getEnd
()
==
block
)
{
continue
;
}
nodes
.
add
(
b
);
}
}
...
...
@@ -153,13 +155,25 @@ public class BlockNode extends AttrNode implements IBlock {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
hashCode
()
!=
obj
.
hashCode
())
return
false
;
if
(!(
obj
instanceof
BlockNode
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
hashCode
()
!=
obj
.
hashCode
())
{
return
false
;
}
if
(!(
obj
instanceof
BlockNode
))
{
return
false
;
}
BlockNode
other
=
(
BlockNode
)
obj
;
if
(
id
!=
other
.
id
)
return
false
;
if
(
startOffset
!=
other
.
startOffset
)
return
false
;
if
(
id
!=
other
.
id
)
{
return
false
;
}
if
(
startOffset
!=
other
.
startOffset
)
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
View file @
e3606d1b
...
...
@@ -48,8 +48,12 @@ public class FieldNode extends LineAttrNode {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
FieldNode
other
=
(
FieldNode
)
obj
;
return
fieldInfo
.
equals
(
other
.
fieldInfo
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
View file @
e3606d1b
...
...
@@ -32,15 +32,17 @@ public class InsnNode extends LineAttrNode {
this
.
insnType
=
type
;
this
.
offset
=
-
1
;
if
(
argsCount
==
0
)
if
(
argsCount
==
0
)
{
this
.
arguments
=
Collections
.
emptyList
();
else
}
else
{
this
.
arguments
=
new
ArrayList
<
InsnArg
>(
argsCount
);
}
}
public
void
setResult
(
RegisterArg
res
)
{
if
(
res
!=
null
)
if
(
res
!=
null
)
{
res
.
setParentInsn
(
this
);
}
this
.
result
=
res
;
}
...
...
@@ -71,8 +73,9 @@ public class InsnNode extends LineAttrNode {
public
boolean
containsArg
(
RegisterArg
arg
)
{
for
(
InsnArg
a
:
arguments
)
{
if
(
a
==
arg
||
(
a
.
isRegister
()
&&
((
RegisterArg
)
a
).
getRegNum
()
==
arg
.
getRegNum
()))
if
(
a
==
arg
||
(
a
.
isRegister
()
&&
((
RegisterArg
)
a
).
getRegNum
()
==
arg
.
getRegNum
()))
{
return
true
;
}
}
return
false
;
}
...
...
@@ -92,8 +95,9 @@ public class InsnNode extends LineAttrNode {
setArg
(
i
,
to
);
return
true
;
}
else
if
(
arg
.
isInsnWrap
())
{
if
(((
InsnWrapArg
)
arg
).
getWrapInsn
().
replaceArg
(
from
,
to
))
if
(((
InsnWrapArg
)
arg
).
getWrapInsn
().
replaceArg
(
from
,
to
))
{
return
true
;
}
}
}
return
false
;
...
...
@@ -176,14 +180,25 @@ public class InsnNode extends LineAttrNode {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
hashCode
()
!=
obj
.
hashCode
())
return
false
;
if
(!(
obj
instanceof
InsnNode
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
hashCode
()
!=
obj
.
hashCode
())
{
return
false
;
}
if
(!(
obj
instanceof
InsnNode
))
{
return
false
;
}
InsnNode
other
=
(
InsnNode
)
obj
;
if
(
insnType
!=
other
.
insnType
)
return
false
;
if
(
arguments
.
size
()
!=
other
.
arguments
.
size
())
return
false
;
if
(
insnType
!=
other
.
insnType
)
{
return
false
;
}
if
(
arguments
.
size
()
!=
other
.
arguments
.
size
())
{
return
false
;
}
// TODO !!! finish equals
return
true
;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
e3606d1b
...
...
@@ -90,8 +90,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
InsnNode
[]
insnByOffset
=
decoder
.
run
();
instructions
=
new
ArrayList
<
InsnNode
>();
for
(
InsnNode
insn
:
insnByOffset
)
{
if
(
insn
!=
null
)
if
(
insn
!=
null
)
{
instructions
.
add
(
insn
);
}
}
((
ArrayList
<
InsnNode
>)
instructions
).
trimToSize
();
...
...
@@ -127,18 +128,23 @@ public class MethodNode extends LineAttrNode implements ILoadable {
if
(
noCode
)
{
return
;
}
if
(
instructions
!=
null
)
instructions
.
clear
();
if
(
instructions
!=
null
)
{
instructions
.
clear
();
}
blocks
=
null
;
exitBlocks
=
null
;
if
(
exceptionHandlers
!=
null
)
exceptionHandlers
.
clear
();
if
(
exceptionHandlers
!=
null
)
{
exceptionHandlers
.
clear
();
}
noCode
=
true
;
}
@SuppressWarnings
(
"unchecked"
)
private
boolean
parseSignature
()
{
Annotation
a
=
getAttributes
().
getAnnotation
(
Consts
.
DALVIK_SIGNATURE
);
if
(
a
==
null
)
if
(
a
==
null
)
{
return
false
;
}
String
sign
=
Utils
.
mergeSignature
((
List
<
String
>)
a
.
getDefaultValue
());
...
...
@@ -162,8 +168,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
List
<
ArgType
>
argsTypes
=
ArgType
.
parseSignatureList
(
argsTypesStr
);
if
(
argsTypes
==
null
)
if
(
argsTypes
==
null
)
{
return
false
;
}
List
<
ArgType
>
mthArgs
=
mthInfo
.
getArgumentsTypes
();
if
(
argsTypes
.
size
()
!=
mthArgs
.
size
())
{
...
...
@@ -197,8 +204,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
pos
=
1
;
}
else
{
pos
=
regsCount
;
for
(
ArgType
arg
:
args
)
for
(
ArgType
arg
:
args
)
{
pos
-=
arg
.
getRegCount
();
}
}
if
(
accFlags
.
isStatic
())
{
thisArg
=
null
;
...
...
@@ -289,11 +297,15 @@ public class MethodNode extends LineAttrNode implements ILoadable {
// resolve nested try blocks:
// inner block contains all handlers from outer block => remove these handlers from inner block
// each handler must be only in one try/catch block
for
(
TryCatchBlock
ct1
:
catches
)
for
(
TryCatchBlock
ct2
:
catches
)
if
(
ct1
!=
ct2
&&
ct2
.
getHandlers
().
containsAll
(
ct1
.
getHandlers
()))
for
(
ExceptionHandler
h
:
ct1
.
getHandlers
())
for
(
TryCatchBlock
ct1
:
catches
)
{
for
(
TryCatchBlock
ct2
:
catches
)
{
if
(
ct1
!=
ct2
&&
ct2
.
getHandlers
().
containsAll
(
ct1
.
getHandlers
()))
{
for
(
ExceptionHandler
h
:
ct1
.
getHandlers
())
{
ct2
.
removeHandler
(
this
,
h
);
}
}
}
}
}
// attach EXC_HANDLER attributes to instructions
...
...
@@ -319,8 +331,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
block
.
addInsn
(
insnByOffset
[
offset
]);
offset
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
}
if
(
insnByOffset
[
end
]
!=
null
)
if
(
insnByOffset
[
end
]
!=
null
)
{
insnByOffset
[
end
].
getAttributes
().
add
(
AttributeFlag
.
TRY_LEAVE
);
}
}
}
...
...
@@ -335,15 +348,17 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
// default case
int
next
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
if
(
next
!=
-
1
)
if
(
next
!=
-
1
)
{
addJump
(
insnByOffset
,
offset
,
next
);
}
break
;
}
case
IF:
int
next
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
if
(
next
!=
-
1
)
if
(
next
!=
-
1
)
{
addJump
(
insnByOffset
,
offset
,
next
);
}
addJump
(
insnByOffset
,
offset
,
((
IfNode
)
insn
).
getTarget
());
break
;
...
...
@@ -363,10 +378,11 @@ public class MethodNode extends LineAttrNode implements ILoadable {
public
String
getName
()
{
String
name
=
mthInfo
.
getName
();
if
(
name
.
equals
(
parentClass
.
getShortName
()))
if
(
name
.
equals
(
parentClass
.
getShortName
()))
{
return
name
+
"_"
;
else
}
else
{
return
name
;
}
}
public
ClassNode
getParentClass
()
{
...
...
@@ -397,8 +413,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
blocks
=
Collections
.
unmodifiableList
(
blocks
);
exitBlocks
=
Collections
.
unmodifiableList
(
exitBlocks
);
for
(
BlockNode
block
:
blocks
)
for
(
BlockNode
block
:
blocks
)
{
block
.
lock
();
}
}
public
List
<
BlockNode
>
getBasicBlocks
()
{
...
...
@@ -430,8 +447,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
public
LoopAttr
getLoopForBlock
(
BlockNode
block
)
{
for
(
LoopAttr
loop
:
loops
)
{
if
(
loop
.
getLoopBlocks
().
contains
(
block
))
if
(
loop
.
getLoopBlocks
().
contains
(
block
))
{
return
loop
;
}
}
return
null
;
}
...
...
@@ -445,8 +463,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
exceptionHandlers
=
new
ArrayList
<
ExceptionHandler
>(
2
);
}
else
{
for
(
ExceptionHandler
h
:
exceptionHandlers
)
{
if
(
h
==
handler
||
h
.
getHandleOffset
()
==
handler
.
getHandleOffset
())
if
(
h
==
handler
||
h
.
getHandleOffset
()
==
handler
.
getHandleOffset
())
{
return
h
;
}
}
}
exceptionHandlers
.
add
(
handler
);
...
...
@@ -471,8 +490,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
for
(
MethodNode
method
:
methods
)
{
if
(
this
!=
method
&&
method
.
getName
().
equals
(
name
)
&&
method
.
mthInfo
.
getArgumentsTypes
().
size
()
==
argsCount
)
&&
method
.
mthInfo
.
getArgumentsTypes
().
size
()
==
argsCount
)
{
return
true
;
}
}
return
false
;
}
...
...
@@ -508,8 +528,12 @@ public class MethodNode extends LineAttrNode implements ILoadable {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
MethodNode
other
=
(
MethodNode
)
obj
;
return
mthInfo
.
equals
(
other
.
mthInfo
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
View file @
e3606d1b
...
...
@@ -59,8 +59,9 @@ public class RootNode {
// move inner classes
List
<
ClassNode
>
inner
=
new
ArrayList
<
ClassNode
>();
for
(
ClassNode
cls
:
classes
)
{
if
(
cls
.
getClassInfo
().
isInner
())
if
(
cls
.
getClassInfo
().
isInner
())
{
inner
.
add
(
cls
);
}
}
for
(
ClassNode
cls
:
inner
)
{
ClassNode
parent
=
resolveClass
(
cls
.
getClassInfo
().
getParentClass
());
...
...
@@ -81,8 +82,9 @@ public class RootNode {
if
(
includeInner
)
{
classes
.
add
(
cls
);
}
else
{
if
(!
cls
.
getClassInfo
().
isInner
())
if
(!
cls
.
getClassInfo
().
isInner
())
{
classes
.
add
(
cls
);
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/AnnotationsParser.java
View file @
e3606d1b
...
...
@@ -61,8 +61,6 @@ public class AnnotationsParser {
private
AnnotationsList
readAnnotationSet
(
int
offset
)
throws
DecodeException
{
Section
section
=
dex
.
openSection
(
offset
);
int
size
=
section
.
readInt
();
if
(
size
>
100
)
section
.
toString
();
List
<
Annotation
>
list
=
new
ArrayList
<
Annotation
>(
size
);
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Section
anSection
=
dex
.
openSection
(
section
.
readInt
());
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
View file @
e3606d1b
...
...
@@ -162,18 +162,19 @@ public class DebugInfoParser {
int
newAddr
=
addr
+
addrInc
;
for
(
int
i
=
addr
+
1
;
i
<=
newAddr
;
i
++)
{
InsnNode
insn
=
insnByOffset
[
i
];
if
(
insn
==
null
)
if
(
insn
==
null
)
{
continue
;
}
insn
.
setSourceLine
(
line
);
for
(
InsnArg
arg
:
insn
.
getArguments
())
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(
arg
.
isRegister
())
{
activeRegisters
[((
RegisterArg
)
arg
).
getRegNum
()]
=
arg
;
}
}
RegisterArg
res
=
insn
.
getResult
();
if
(
res
!=
null
)
if
(
res
!=
null
)
{
activeRegisters
[
res
.
getRegNum
()]
=
res
;
}
}
return
newAddr
;
}
...
...
@@ -195,18 +196,20 @@ public class DebugInfoParser {
for
(
int
i
=
start
;
i
<=
end
;
i
++)
{
InsnNode
insn
=
insnByOffset
[
i
];
if
(
insn
!=
null
)
if
(
insn
!=
null
)
{
fillLocals
(
insn
,
var
);
}
}
merge
(
activeRegisters
[
var
.
getRegNum
()],
var
);
}
private
static
void
fillLocals
(
InsnNode
insn
,
LocalVar
var
)
{
if
(
insn
.
getResult
()
!=
null
)
if
(
insn
.
getResult
()
!=
null
)
{
merge
(
insn
.
getResult
(),
var
);
for
(
InsnArg
arg
:
insn
.
getArguments
())
}
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
merge
(
arg
,
var
);
}
}
private
static
void
merge
(
InsnArg
arg
,
LocalVar
var
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java
View file @
e3606d1b
...
...
@@ -53,11 +53,13 @@ public final class IfCondition {
}
public
InsnArg
getB
()
{
if
(
insn
.
isZeroCmp
())
if
(
insn
.
isZeroCmp
())
{
return
InsnArg
.
lit
(
0
,
getA
().
getType
());
else
}
else
{
return
insn
.
getArg
(
1
);
}
}
public
Compare
invert
()
{
insn
.
invertCondition
();
return
this
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
View file @
e3606d1b
...
...
@@ -51,10 +51,12 @@ public final class IfRegion extends AbstractRegion {
public
List
<
IContainer
>
getSubBlocks
()
{
ArrayList
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
all
.
add
(
header
);
if
(
thenRegion
!=
null
)
if
(
thenRegion
!=
null
)
{
all
.
add
(
thenRegion
);
if
(
elseRegion
!=
null
)
}
if
(
elseRegion
!=
null
)
{
all
.
add
(
elseRegion
);
}
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
View file @
e3606d1b
...
...
@@ -68,9 +68,9 @@ public final class LoopRegion extends AbstractRegion {
*/
public
boolean
checkPreCondition
()
{
List
<
InsnNode
>
insns
=
preCondition
.
getInstructions
();
if
(
insns
.
isEmpty
())
if
(
insns
.
isEmpty
())
{
return
true
;
}
IfNode
ifInsn
=
getIfInsn
();
int
size
=
insns
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
...
...
@@ -79,21 +79,23 @@ public final class LoopRegion extends AbstractRegion {
return
false
;
}
else
{
RegisterArg
res
=
insn
.
getResult
();
if
(
res
.
getTypedVar
().
getUseList
().
size
()
>
2
)
if
(
res
.
getTypedVar
().
getUseList
().
size
()
>
2
)
{
return
false
;
}
boolean
found
=
false
;
// search result arg in other insns
for
(
int
j
=
i
+
1
;
j
<
size
;
j
++)
{
if
(
insns
.
get
(
i
).
containsArg
(
res
))
if
(
insns
.
get
(
i
).
containsArg
(
res
))
{
found
=
true
;
}
}
// or in if insn
if
(!
found
&&
ifInsn
.
containsArg
(
res
))
if
(!
found
&&
ifInsn
.
containsArg
(
res
))
{
found
=
true
;
if
(!
found
)
}
if
(!
found
)
{
return
false
;
}
}
}
return
true
;
...
...
@@ -117,10 +119,12 @@ public final class LoopRegion extends AbstractRegion {
@Override
public
List
<
IContainer
>
getSubBlocks
()
{
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
if
(
preCondition
!=
null
)
if
(
preCondition
!=
null
)
{
all
.
add
(
preCondition
);
if
(
conditionBlock
!=
null
)
}
if
(
conditionBlock
!=
null
)
{
all
.
add
(
conditionBlock
);
}
all
.
add
(
body
);
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/regions/Region.java
View file @
e3606d1b
...
...
@@ -28,8 +28,9 @@ public final class Region extends AbstractRegion {
sb
.
append
(
blocks
.
size
());
if
(
blocks
.
size
()
!=
0
)
{
for
(
IContainer
cont
:
blocks
)
{
if
(
cont
instanceof
BlockNode
)
if
(
cont
instanceof
BlockNode
)
{
sb
.
append
(((
BlockNode
)
cont
).
getId
());
}
}
}
return
sb
.
toString
();
...
...
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
View file @
e3606d1b
...
...
@@ -53,8 +53,9 @@ public final class SwitchRegion extends AbstractRegion {
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
cases
.
size
()
+
2
);
all
.
add
(
header
);
all
.
addAll
(
cases
);
if
(
defCase
!=
null
)
if
(
defCase
!=
null
)
{
all
.
add
(
defCase
);
}
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java
View file @
e3606d1b
...
...
@@ -86,13 +86,23 @@ public class ExceptionHandler {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
ExceptionHandler
other
=
(
ExceptionHandler
)
obj
;
if
(
catchType
==
null
)
{
if
(
other
.
catchType
!=
null
)
return
false
;
}
else
if
(!
catchType
.
equals
(
other
.
catchType
))
return
false
;
if
(
other
.
catchType
!=
null
)
{
return
false
;
}
}
else
if
(!
catchType
.
equals
(
other
.
catchType
))
{
return
false
;
}
return
handleOffset
==
other
.
handleOffset
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
View file @
e3606d1b
...
...
@@ -22,14 +22,15 @@ public class ConstInlinerVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
Iterator
<
InsnNode
>
it
=
block
.
getInstructions
().
iterator
();
it
.
hasNext
();
)
{
InsnNode
insn
=
it
.
next
();
if
(
checkInsn
(
mth
,
block
,
insn
))
if
(
checkInsn
(
mth
,
block
,
insn
))
{
it
.
remove
();
}
}
}
}
...
...
@@ -57,9 +58,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
int
replace
=
0
;
for
(
InsnArg
arg
:
use
)
{
InsnNode
useInsn
=
arg
.
getParentInsn
();
if
(
useInsn
==
null
)
if
(
useInsn
==
null
)
{
continue
;
}
BlockNode
useBlock
=
BlockUtils
.
getBlockByInsn
(
mth
,
useInsn
);
if
(
useBlock
==
block
||
useBlock
.
isDominator
(
block
))
{
if
(
arg
!=
insn
.
getResult
()
&&
!
registerReassignOnPath
(
block
,
useBlock
,
insn
))
{
...
...
@@ -77,9 +78,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
}
private
static
boolean
registerReassignOnPath
(
BlockNode
block
,
BlockNode
useBlock
,
InsnNode
assignInsn
)
{
if
(
block
==
useBlock
)
if
(
block
==
useBlock
)
{
return
false
;
}
Set
<
BlockNode
>
blocks
=
BlockUtils
.
getAllPathsBlocks
(
block
,
useBlock
);
// TODO store list of assign insn for each register
int
regNum
=
assignInsn
.
getResult
().
getRegNum
();
...
...
@@ -87,8 +88,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
for
(
InsnNode
insn
:
b
.
getInstructions
())
{
if
(
insn
.
getResult
()
!=
null
&&
insn
!=
assignInsn
&&
insn
.
getResult
().
getRegNum
()
==
regNum
)
&&
insn
.
getResult
().
getRegNum
()
==
regNum
)
{
return
true
;
}
}
}
return
false
;
...
...
@@ -156,10 +158,11 @@ public class ConstInlinerVisitor extends AbstractVisitor {
InsnArg
arg
=
insn
.
getArg
(
i
);
if
(!
arg
.
getType
().
isTypeKnown
())
{
ArgType
type
;
if
(
k
>=
0
)
if
(
k
>=
0
)
{
type
=
types
.
get
(
k
);
else
}
else
{
type
=
mth
.
getParentClass
().
getClassInfo
().
getType
();
}
arg
.
merge
(
type
);
}
k
++;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraverser.java
View file @
e3606d1b
...
...
@@ -9,10 +9,12 @@ public class DepthTraverser {
public
static
void
visit
(
IDexTreeVisitor
visitor
,
ClassNode
cls
)
{
try
{
if
(
visitor
.
visit
(
cls
))
{
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
{
visit
(
visitor
,
inCls
);
for
(
MethodNode
mth
:
cls
.
getMethods
())
}
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
visit
(
visitor
,
mth
);
}
}
}
catch
(
Throwable
e
)
{
ErrorsCounter
.
classError
(
cls
,
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
View file @
e3606d1b
...
...
@@ -36,9 +36,9 @@ public class DotGraphVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
CodeWriter
dot
=
new
CodeWriter
();
CodeWriter
conn
=
new
CodeWriter
();
...
...
@@ -47,18 +47,22 @@ public class DotGraphVisitor extends AbstractVisitor {
+
"\" {"
);
if
(
useRegions
)
{
if
(
mth
.
getRegion
()
==
null
)
if
(
mth
.
getRegion
()
==
null
)
{
return
;
}
processRegion
(
mth
,
mth
.
getRegion
(),
dot
,
conn
);
if
(
mth
.
getExceptionHandlers
()
!=
null
)
{
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
if
(
h
.
getHandlerRegion
()
!=
null
)
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
if
(
h
.
getHandlerRegion
()
!=
null
)
{
processRegion
(
mth
,
h
.
getHandlerRegion
(),
dot
,
conn
);
}
}
}
}
else
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
processBlock
(
mth
,
block
,
dot
,
conn
);
}
}
String
attrs
=
attributesString
(
mth
);
...
...
@@ -109,8 +113,9 @@ public class DotGraphVisitor extends AbstractVisitor {
String
attrs
=
attributesString
(
block
);
if
(
PRINT_REGISTERS_STATES
)
{
if
(
block
.
getStartState
()
!=
null
)
{
if
(
attrs
.
length
()
!=
0
)
if
(
attrs
.
length
()
!=
0
)
{
attrs
+=
"|"
;
}
attrs
+=
escape
(
"RS: "
+
block
.
getStartState
())
+
NL
;
attrs
+=
escape
(
"RE: "
+
block
.
getEndState
())
+
NL
;
}
...
...
@@ -125,16 +130,17 @@ public class DotGraphVisitor extends AbstractVisitor {
+
(
insns
.
length
()
==
0
?
""
:
"|"
+
insns
)
+
"}\"];"
);
for
(
BlockNode
next
:
block
.
getSuccessors
())
for
(
BlockNode
next
:
block
.
getSuccessors
())
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
";"
);
for
(
BlockNode
next
:
block
.
getDominatesOn
())
}
for
(
BlockNode
next
:
block
.
getDominatesOn
())
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
"[style=dotted];"
);
}
// add all dominators connections
if
(
false
)
{
for
(
BlockNode
next
:
BlockUtils
.
bitsetToBlocks
(
mth
,
block
.
getDoms
()))
for
(
BlockNode
next
:
BlockUtils
.
bitsetToBlocks
(
mth
,
block
.
getDoms
()))
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
"[style=dotted, color=green];"
);
}
}
}
...
...
@@ -168,8 +174,9 @@ public class DotGraphVisitor extends AbstractVisitor {
CodeWriter
code
=
new
CodeWriter
(
0
);
MethodGen
.
makeFallbackInsns
(
code
,
mth
,
block
.
getInstructions
(),
false
);
String
str
=
escape
(
code
.
newLine
().
toString
());
if
(
str
.
startsWith
(
NL
))
if
(
str
.
startsWith
(
NL
))
{
str
=
str
.
substring
(
NL
.
length
());
}
return
str
;
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
View file @
e3606d1b
...
...
@@ -10,9 +10,9 @@ public class FallbackModeVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
for
(
InsnNode
insn
:
mth
.
getInstructions
())
{
// remove 'exception catch' for instruction which don't throw any exceptions
CatchAttr
catchAttr
=
(
CatchAttr
)
insn
.
getAttributes
().
get
(
AttributeType
.
CATCH_BLOCK
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java
View file @
e3606d1b
...
...
@@ -22,18 +22,20 @@ public class CheckRegions extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
{
return
;
}
// check if all blocks included in regions
final
Set
<
BlockNode
>
blocksInRegions
=
new
HashSet
<
BlockNode
>();
IRegionVisitor
collectBlocks
=
new
AbstractRegionVisitor
()
{
@Override
public
void
processBlock
(
MethodNode
mth
,
IBlock
container
)
{
if
(
container
instanceof
BlockNode
)
if
(
container
instanceof
BlockNode
)
{
blocksInRegions
.
add
((
BlockNode
)
container
);
else
}
else
{
LOG
.
warn
(
"Not block node : "
+
container
.
getClass
().
getSimpleName
());
}
}
};
DepthRegionTraverser
.
traverseAll
(
mth
,
collectBlocks
);
...
...
@@ -44,10 +46,11 @@ public class CheckRegions extends AbstractVisitor {
if
(!
block
.
getInstructions
().
isEmpty
()
&&
!
block
.
getAttributes
().
contains
(
AttributeFlag
.
SKIP
))
{
mth
.
getAttributes
().
add
(
AttributeFlag
.
INCONSISTENT_CODE
);
if
(
Consts
.
DEBUG
)
if
(
Consts
.
DEBUG
)
{
LOG
.
debug
(
" Missing block: {} in {}"
,
block
,
mth
);
else
}
else
{
break
;
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CleanRegions.java
View file @
e3606d1b
...
...
@@ -18,14 +18,15 @@ public class CleanRegions extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
{
return
;
}
IRegionVisitor
removeEmptyBlocks
=
new
AbstractRegionVisitor
()
{
@Override
public
void
enterRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(!(
region
instanceof
Region
))
if
(!(
region
instanceof
Region
))
{
return
;
}
for
(
Iterator
<
IContainer
>
it
=
region
.
getSubBlocks
().
iterator
();
it
.
hasNext
();
)
{
IContainer
container
=
it
.
next
();
...
...
@@ -44,6 +45,5 @@ public class CleanRegions extends AbstractVisitor {
}
};
DepthRegionTraverser
.
traverseAll
(
mth
,
removeEmptyBlocks
);
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraverser.java
View file @
e3606d1b
...
...
@@ -25,8 +25,9 @@ public class DepthRegionTraverser {
traverse
(
mth
,
visitor
,
mth
.
getRegion
());
if
(
mth
.
getExceptionHandlers
()
!=
null
)
{
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
traverse
(
mth
,
visitor
,
h
.
getHandlerRegion
());
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
View file @
e3606d1b
...
...
@@ -141,12 +141,13 @@ public class ProcessVariables extends AbstractVisitor {
for
(
Iterator
<
IRegion
>
it
=
set
.
iterator
();
it
.
hasNext
();
)
{
IRegion
r
=
it
.
next
();
IRegion
parent
=
r
.
getParent
();
if
(
parent
!=
null
&&
set
.
contains
(
parent
))
if
(
parent
!=
null
&&
set
.
contains
(
parent
))
{
it
.
remove
();
}
}
if
(
set
.
isEmpty
())
if
(
set
.
isEmpty
())
{
continue
;
}
IRegion
region
=
set
.
iterator
().
next
();
IRegion
parent
=
region
;
boolean
declare
=
false
;
...
...
@@ -178,12 +179,14 @@ public class ProcessVariables extends AbstractVisitor {
private
boolean
canDeclareInRegion
(
Usage
u
,
IRegion
region
)
{
for
(
IRegion
r
:
u
.
getAssigns
())
{
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
{
return
false
;
}
}
for
(
IRegion
r
:
u
.
getUseRegions
())
{
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
{
return
false
;
}
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
View file @
e3606d1b
...
...
@@ -12,9 +12,9 @@ public class RegionMakerVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
RegionMaker
rm
=
new
RegionMaker
(
mth
);
RegionStack
state
=
new
RegionStack
(
mth
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionStack.java
View file @
e3606d1b
...
...
@@ -17,8 +17,9 @@ final class RegionStack {
private
static
final
boolean
DEBUG
=
false
;
static
{
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Debug enabled for {}"
,
RegionStack
.
class
);
}
}
private
static
final
class
State
{
...
...
@@ -47,27 +48,30 @@ final class RegionStack {
private
State
curState
;
public
RegionStack
(
MethodNode
mth
)
{
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"New RegionStack: {}"
,
mth
);
}
this
.
stack
=
new
ArrayDeque
<
State
>();
this
.
curState
=
new
State
();
}
public
void
push
(
IRegion
region
)
{
stack
.
push
(
curState
);
if
(
stack
.
size
()
>
1000
)
if
(
stack
.
size
()
>
1000
)
{
throw
new
StackOverflowError
(
"Deep code hierarchy"
);
}
curState
=
curState
.
copy
();
curState
.
region
=
region
;
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Stack push: {}: {}"
,
size
(),
curState
);
}
}
public
void
pop
()
{
curState
=
stack
.
pop
();
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Stack pop: {}: {}"
,
size
(),
curState
);
}
}
/**
...
...
@@ -76,8 +80,9 @@ final class RegionStack {
* @param exit boundary node, null will be ignored
*/
public
void
addExit
(
BlockNode
exit
)
{
if
(
exit
!=
null
)
if
(
exit
!=
null
)
{
curState
.
exits
.
add
(
exit
);
}
}
public
boolean
containsExit
(
BlockNode
exit
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/FinishTypeResolver.java
View file @
e3606d1b
...
...
@@ -12,31 +12,39 @@ public class FinishTypeResolver extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
boolean
change
;
int
i
=
0
;
do
{
change
=
false
;
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
if
(
PostTypeResolver
.
visit
(
mth
,
insn
))
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
PostTypeResolver
.
visit
(
mth
,
insn
))
{
change
=
true
;
}
}
}
i
++;
if
(
i
>
1000
)
if
(
i
>
1000
)
{
break
;
}
}
while
(
change
);
// last chance to set correct value (just use first type from 'possible' list)
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
InsnNode
insn
:
block
.
getInstructions
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
SelectTypeVisitor
.
visit
(
insn
);
}
}
// check
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
InsnNode
insn
:
block
.
getInstructions
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
CheckTypeVisitor
.
visit
(
mth
,
insn
);
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/TypeResolver.java
View file @
e3606d1b
...
...
@@ -16,9 +16,9 @@ public class TypeResolver extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
prepare
(
mth
);
visitBlocks
(
mth
);
...
...
@@ -60,11 +60,13 @@ public class TypeResolver extends AbstractVisitor {
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(
arg
.
isRegister
())
if
(
arg
.
isRegister
())
{
state
.
use
((
RegisterArg
)
arg
);
}
}
if
(
insn
.
getResult
()
!=
null
)
if
(
insn
.
getResult
()
!=
null
)
{
state
.
assignReg
(
insn
.
getResult
());
}
}
block
.
setEndState
(
new
BlockRegState
(
state
));
...
...
@@ -78,8 +80,9 @@ public class TypeResolver extends AbstractVisitor {
changed
=
false
;
for
(
BlockNode
block
:
preds
)
{
for
(
BlockNode
pred
:
block
.
getPredecessors
())
{
if
(
connectEdges
(
mth
,
pred
,
block
,
true
))
if
(
connectEdges
(
mth
,
pred
,
block
,
true
))
{
changed
=
true
;
}
}
}
}
while
(
changed
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/PostTypeResolver.java
View file @
e3606d1b
...
...
@@ -39,10 +39,12 @@ public class PostTypeResolver {
case
MOVE:
{
boolean
change
=
false
;
if
(
insn
.
getResult
().
merge
(
insn
.
getArg
(
0
)))
if
(
insn
.
getResult
().
merge
(
insn
.
getArg
(
0
)))
{
change
=
true
;
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getResult
()))
}
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getResult
()))
{
change
=
true
;
}
return
change
;
}
...
...
@@ -56,10 +58,12 @@ public class PostTypeResolver {
boolean
change
=
false
;
IfNode
ifnode
=
(
IfNode
)
insn
;
if
(!
ifnode
.
isZeroCmp
())
{
if
(
insn
.
getArg
(
1
).
merge
(
insn
.
getArg
(
0
)))
if
(
insn
.
getArg
(
1
).
merge
(
insn
.
getArg
(
0
)))
{
change
=
true
;
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getArg
(
1
)))
}
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getArg
(
1
)))
{
change
=
true
;
}
}
return
change
;
}
...
...
@@ -94,10 +98,12 @@ public class PostTypeResolver {
private
static
boolean
fixArrayTypes
(
InsnArg
array
,
InsnArg
elem
)
{
boolean
change
=
false
;
if
(!
elem
.
getType
().
isTypeKnown
()
&&
elem
.
merge
(
array
.
getType
().
getArrayElement
()))
if
(!
elem
.
getType
().
isTypeKnown
()
&&
elem
.
merge
(
array
.
getType
().
getArrayElement
()))
{
change
=
true
;
if
(!
array
.
getType
().
isTypeKnown
()
&&
array
.
merge
(
ArgType
.
array
(
elem
.
getType
())))
}
if
(!
array
.
getType
().
isTypeKnown
()
&&
array
.
merge
(
ArgType
.
array
(
elem
.
getType
())))
{
change
=
true
;
}
return
change
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/SelectTypeVisitor.java
View file @
e3606d1b
...
...
@@ -13,8 +13,9 @@ public class SelectTypeVisitor {
}
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(!
arg
.
getType
().
isTypeKnown
())
if
(!
arg
.
getType
().
isTypeKnown
())
{
selectType
(
arg
);
}
}
}
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
e3606d1b
...
...
@@ -33,25 +33,27 @@ public class BlockUtils {
}
assert
list
.
size
()
==
2
:
"too many nodes for selectOther: "
+
node
+
" in "
+
list
;
BlockNode
first
=
list
.
get
(
0
);
if
(
first
!=
node
)
if
(
first
!=
node
)
{
return
first
;
else
}
else
{
return
list
.
get
(
1
);
}
}
private
static
List
<
BlockNode
>
cleanBlockList
(
List
<
BlockNode
>
list
)
{
List
<
BlockNode
>
ret
=
new
ArrayList
<
BlockNode
>(
list
.
size
());
for
(
BlockNode
block
:
list
)
{
if
(!
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(!
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
ret
.
add
(
block
);
}
}
return
ret
;
}
public
static
boolean
isBackEdge
(
BlockNode
from
,
BlockNode
to
)
{
if
(
from
.
getCleanSuccessors
().
contains
(
to
))
if
(
from
.
getCleanSuccessors
().
contains
(
to
))
{
return
false
;
// already checked
}
return
from
.
getSuccessors
().
contains
(
to
);
}
...
...
@@ -61,8 +63,9 @@ public class BlockUtils {
public
static
void
cleanBitSet
(
MethodNode
mth
,
BitSet
bs
)
{
for
(
int
i
=
bs
.
nextSetBit
(
0
);
i
>=
0
;
i
=
bs
.
nextSetBit
(
i
+
1
))
{
BlockNode
block
=
mth
.
getBasicBlocks
().
get
(
i
);
if
(
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
bs
.
clear
(
i
);
}
}
}
...
...
@@ -81,17 +84,18 @@ public class BlockUtils {
*/
public
static
boolean
blockContains
(
BlockNode
block
,
InsnNode
insn
)
{
for
(
InsnNode
bi
:
block
.
getInstructions
())
{
if
(
bi
==
insn
)
if
(
bi
==
insn
)
{
return
true
;
}
}
return
false
;
}
public
static
boolean
lastInsnType
(
BlockNode
block
,
InsnType
type
)
{
List
<
InsnNode
>
insns
=
block
.
getInstructions
();
if
(
insns
.
isEmpty
())
if
(
insns
.
isEmpty
())
{
return
false
;
}
InsnNode
insn
=
insns
.
get
(
insns
.
size
()
-
1
);
return
insn
.
getType
()
==
type
;
}
...
...
@@ -99,8 +103,9 @@ public class BlockUtils {
public
static
BlockNode
getBlockByInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
assert
insn
!=
null
;
for
(
BlockNode
bn
:
mth
.
getBasicBlocks
())
{
if
(
blockContains
(
bn
,
insn
))
if
(
blockContains
(
bn
,
insn
))
{
return
bn
;
}
}
return
null
;
}
...
...
@@ -136,8 +141,9 @@ public class BlockUtils {
public
static
Set
<
BlockNode
>
getAllPathsBlocks
(
BlockNode
start
,
BlockNode
end
)
{
Set
<
BlockNode
>
set
=
new
HashSet
<
BlockNode
>();
set
.
add
(
start
);
if
(
start
!=
end
)
if
(
start
!=
end
)
{
addPredcessors
(
set
,
end
,
start
);
}
return
set
;
}
...
...
@@ -152,29 +158,29 @@ public class BlockUtils {
private
static
boolean
traverseSuccessorsUntil
(
BlockNode
from
,
BlockNode
until
,
Set
<
BlockNode
>
checked
)
{
for
(
BlockNode
s
:
from
.
getCleanSuccessors
())
{
if
(
s
==
until
)
if
(
s
==
until
)
{
return
true
;
}
if
(!
checked
.
contains
(
s
))
{
checked
.
add
(
s
);
if
(
until
.
isDominator
(
s
))
if
(
until
.
isDominator
(
s
))
{
return
true
;
if
(
traverseSuccessorsUntil
(
s
,
until
,
checked
))
}
if
(
traverseSuccessorsUntil
(
s
,
until
,
checked
))
{
return
true
;
}
}
}
return
false
;
}
public
static
boolean
isPathExists
(
BlockNode
start
,
BlockNode
end
)
{
if
(
start
==
end
)
if
(
start
==
end
)
{
return
true
;
if
(
end
.
isDominator
(
start
))
}
if
(
end
.
isDominator
(
start
))
{
return
true
;
}
return
traverseSuccessorsUntil
(
start
,
end
,
new
HashSet
<
BlockNode
>());
}
...
...
@@ -203,8 +209,9 @@ public class BlockUtils {
return
node
;
}
else
{
BlockNode
out
=
traverseWhileDominates
(
block
,
node
);
if
(
out
!=
null
)
if
(
out
!=
null
)
{
return
out
;
}
}
}
return
null
;
...
...
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
View file @
e3606d1b
...
...
@@ -81,10 +81,11 @@ public class ErrorsCounter {
}
private
static
String
formatException
(
Throwable
e
)
{
if
(
e
==
null
||
e
.
getMessage
()
==
null
)
if
(
e
==
null
||
e
.
getMessage
()
==
null
)
{
return
""
;
else
}
else
{
return
"\n error: "
+
e
.
getMessage
();
}
}
public
static
String
formatErrorMsg
(
ClassNode
cls
,
String
msg
,
Throwable
e
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/InsnUtils.java
View file @
e3606d1b
...
...
@@ -40,12 +40,13 @@ public class InsnUtils {
}
public
static
String
indexToString
(
Object
index
)
{
if
(
index
==
null
)
if
(
index
==
null
)
{
return
""
;
if
(
index
instanceof
String
)
}
if
(
index
instanceof
String
)
{
return
"\""
+
index
+
"\""
;
else
}
else
{
return
" "
+
index
.
toString
();
}
}
}
jadx-core/src/main/java/jadx/core/utils/InstructionRemover.java
View file @
e3606d1b
...
...
@@ -32,8 +32,9 @@ public class InstructionRemover {
}
public
static
void
unbindInsnList
(
List
<
InsnNode
>
unbind
)
{
for
(
InsnNode
rem
:
unbind
)
for
(
InsnNode
rem
:
unbind
)
{
unbindInsn
(
rem
);
}
}
public
static
void
unbindInsn
(
InsnNode
insn
)
{
...
...
@@ -56,8 +57,9 @@ public class InstructionRemover {
// and here can be several instructions with same content
public
static
void
removeAll
(
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
if
(
insns
==
toRemove
)
{
for
(
InsnNode
rem
:
toRemove
)
for
(
InsnNode
rem
:
toRemove
)
{
unbindInsn
(
rem
);
}
return
;
}
...
...
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
View file @
e3606d1b
...
...
@@ -19,8 +19,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
List
<
IContainer
>
blocks
=
region
.
getSubBlocks
();
if
(
blocks
.
isEmpty
())
if
(
blocks
.
isEmpty
())
{
return
false
;
}
return
hasExitEdge
(
blocks
.
get
(
blocks
.
size
()
-
1
));
}
else
{
throw
new
JadxRuntimeException
(
"Unknown container type: "
+
container
.
getClass
());
...
...
@@ -33,8 +34,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
for
(
IContainer
block
:
region
.
getSubBlocks
())
{
if
(
notEmpty
(
block
))
if
(
notEmpty
(
block
))
{
return
true
;
}
}
return
false
;
}
else
{
...
...
@@ -61,8 +63,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
for
(
IContainer
b
:
region
.
getSubBlocks
())
{
if
(
isRegionContainsBlock
(
b
,
block
))
if
(
isRegionContainsBlock
(
b
,
block
))
{
return
true
;
}
}
return
false
;
}
else
{
...
...
@@ -71,8 +74,9 @@ public class RegionUtils {
}
private
static
boolean
isRegionContainsExcHandlerRegion
(
IContainer
container
,
IRegion
region
)
{
if
(
container
==
region
)
if
(
container
==
region
)
{
return
true
;
}
if
(
container
instanceof
IRegion
)
{
IRegion
r
=
(
IRegion
)
container
;
...
...
@@ -84,16 +88,19 @@ public class RegionUtils {
if
(
cb
!=
null
&&
(
b
instanceof
IRegion
))
{
TryCatchBlock
tb
=
cb
.
getTryBlock
();
for
(
ExceptionHandler
eh
:
tb
.
getHandlers
())
{
if
(
isRegionContainsRegion
(
eh
.
getHandlerRegion
(),
region
))
if
(
isRegionContainsRegion
(
eh
.
getHandlerRegion
(),
region
))
{
return
true
;
}
}
if
(
tb
.
getFinalBlock
()
!=
null
)
{
if
(
isRegionContainsRegion
(
tb
.
getFinalBlock
(),
region
))
if
(
isRegionContainsRegion
(
tb
.
getFinalBlock
(),
region
))
{
return
true
;
}
}
}
if
(
isRegionContainsRegion
(
b
,
region
))
if
(
isRegionContainsRegion
(
b
,
region
))
{
return
true
;
}
}
}
return
false
;
...
...
@@ -105,16 +112,20 @@ public class RegionUtils {
* otherwise run recursive search because exception handlers can have several parents
*/
public
static
boolean
isRegionContainsRegion
(
IContainer
container
,
IRegion
region
)
{
if
(
container
==
region
)
return
true
;
if
(
region
==
null
)
return
false
;
if
(
container
==
region
)
{
return
true
;
}
if
(
region
==
null
)
{
return
false
;
}
IRegion
parent
=
region
.
getParent
();
while
(
container
!=
parent
)
{
if
(
parent
==
null
)
{
if
(
region
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(
region
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
return
isRegionContainsExcHandlerRegion
(
container
,
region
);
else
}
else
{
return
false
;
}
}
region
=
parent
;
parent
=
region
.
getParent
();
...
...
@@ -123,11 +134,9 @@ public class RegionUtils {
}
public
static
boolean
isDominaterBy
(
BlockNode
dom
,
IContainer
cont
)
{
assert
cont
!=
null
;
if
(
dom
==
cont
)
if
(
dom
==
cont
)
{
return
true
;
}
if
(
cont
instanceof
BlockNode
)
{
BlockNode
block
=
(
BlockNode
)
cont
;
return
block
.
isDominator
(
dom
);
...
...
@@ -145,16 +154,17 @@ public class RegionUtils {
}
public
static
boolean
hasPathThruBlock
(
BlockNode
block
,
IContainer
cont
)
{
if
(
block
==
cont
)
if
(
block
==
cont
)
{
return
true
;
}
if
(
cont
instanceof
BlockNode
)
{
return
BlockUtils
.
isPathExists
(
block
,
(
BlockNode
)
cont
);
}
else
if
(
cont
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
cont
;
for
(
IContainer
c
:
region
.
getSubBlocks
())
{
if
(!
hasPathThruBlock
(
block
,
c
))
if
(!
hasPathThruBlock
(
block
,
c
))
{
return
false
;
}
}
return
true
;
}
else
{
...
...
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
View file @
e3606d1b
...
...
@@ -14,9 +14,9 @@ public class StringUtils {
}
public
static
String
unescapeChar
(
char
ch
)
{
if
(
ch
==
'\''
)
if
(
ch
==
'\''
)
{
return
"'\\\''"
;
}
StringBuilder
res
=
new
StringBuilder
();
processChar
(
ch
,
res
);
return
'\''
+
res
.
toString
()
+
'\''
;
...
...
jadx-core/src/main/java/jadx/core/utils/Utils.java
View file @
e3606d1b
...
...
@@ -16,10 +16,11 @@ public class Utils {
public
static
String
cleanObjectName
(
String
obj
)
{
int
last
=
obj
.
length
()
-
1
;
if
(
obj
.
charAt
(
0
)
==
'L'
&&
obj
.
charAt
(
last
)
==
';'
)
if
(
obj
.
charAt
(
0
)
==
'L'
&&
obj
.
charAt
(
last
)
==
';'
)
{
return
obj
.
substring
(
1
,
last
).
replace
(
'/'
,
'.'
);
else
}
else
{
return
obj
;
}
}
public
static
String
makeQualifiedObjectName
(
String
obj
)
{
...
...
@@ -61,27 +62,29 @@ public class Utils {
}
public
static
String
listToString
(
Iterable
<?>
list
)
{
if
(
list
==
null
)
if
(
list
==
null
)
{
return
""
;
}
StringBuilder
str
=
new
StringBuilder
();
for
(
Iterator
<?>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
Object
o
=
it
.
next
();
str
.
append
(
o
);
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
str
.
append
(
", "
);
}
}
return
str
.
toString
();
}
public
static
String
arrayToString
(
Object
[]
array
)
{
if
(
array
==
null
)
if
(
array
==
null
)
{
return
""
;
}
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
array
.
length
;
i
++)
{
if
(
i
!=
0
)
if
(
i
!=
0
)
{
sb
.
append
(
", "
);
}
sb
.
append
(
array
[
i
]);
}
return
sb
.
toString
();
...
...
@@ -108,11 +111,11 @@ public class Utils {
int
pair
=
1
;
for
(
int
pos
=
1
;
pos
<
sign
.
length
();
pos
++)
{
char
c
=
sign
.
charAt
(
pos
);
if
(
c
==
'<'
)
if
(
c
==
'<'
)
{
pair
++;
else
if
(
c
==
'>'
)
}
else
if
(
c
==
'>'
)
{
pair
--;
}
if
(
pair
==
0
)
{
end
=
pos
;
break
;
...
...
@@ -127,8 +130,9 @@ public class Utils {
if
(!
dir
.
exists
())
{
// if directory already created in other thread mkdirs will return false,
// so check dir existence again
if
(!
dir
.
mkdirs
()
&&
!
dir
.
exists
())
if
(!
dir
.
mkdirs
()
&&
!
dir
.
exists
())
{
throw
new
JadxRuntimeException
(
"Can't create directory "
+
dir
);
}
}
}
}
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
View file @
e3606d1b
...
...
@@ -26,7 +26,6 @@ public class InputFile {
if
(!
file
.
exists
())
{
throw
new
IOException
(
"File not found: "
+
file
.
getAbsolutePath
());
}
String
fileName
=
file
.
getName
();
if
(
fileName
.
endsWith
(
".dex"
))
{
...
...
@@ -49,8 +48,9 @@ public class InputFile {
throw
new
DecodeException
(
"java class to dex conversion error:\n "
+
e
.
getMessage
(),
e
);
}
}
else
}
else
{
throw
new
DecodeException
(
"Unsupported input file: "
+
file
);
}
}
private
byte
[]
openDexFromApk
(
File
file
)
throws
IOException
{
...
...
jadx-core/src/test/java/jadx/tests/internal/TestStringBuilderElimination.java
View file @
e3606d1b
...
...
@@ -29,8 +29,8 @@ public class TestStringBuilderElimination extends InternalJadxTest {
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsString
(
"MyException(String str, Exception e) {"
));
assertThat
(
code
,
containsString
(
"super(\"msg:\" + str, e);"
));
assertThat
(
code
,
containsString
(
"MyException(String str, Exception e) {"
));
assertThat
(
code
,
containsString
(
"super(\"msg:\" + str, e);"
));
assertThat
(
code
,
not
(
containsString
(
"new StringBuilder"
)));
assertThat
(
code
,
containsString
(
"System.out.println(\"k=\" + k);"
));
...
...
jadx-core/src/test/java/jadx/tests/internal/TestSwitchLabels.java
View file @
e3606d1b
...
...
@@ -6,9 +6,7 @@ import jadx.core.dex.nodes.ClassNode;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
mockito
.
AdditionalMatchers
.
or
;
public
class
TestSwitchLabels
extends
InternalJadxTest
{
public
static
class
TestCls
{
...
...
@@ -17,6 +15,7 @@ public class TestSwitchLabels extends InternalJadxTest {
public
static
class
Inner
{
private
static
final
int
CONST_CDE_PRIVATE
=
0xCDE
;
public
int
f1
(
int
arg0
)
{
switch
(
arg0
)
{
case
CONST_CDE_PRIVATE:
...
...
jadx-core/src/test/java/jadx/tests/internal/inline/TestInline3.java
View file @
e3606d1b
...
...
@@ -19,7 +19,7 @@ public class TestInline3 extends InternalJadxTest {
public
TestCls
(
int
a1
,
int
a2
,
int
a3
,
int
a4
,
int
a5
)
{
}
public
class
A
extends
TestCls
{
public
class
A
extends
TestCls
{
public
A
(
int
a
)
{
super
(
a
,
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