Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
cb6ff606
Commit
cb6ff606
authored
Jun 15, 2013
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix small issues and improve code
parent
26800fb7
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
154 additions
and
104 deletions
+154
-104
IJadxArgs.java
src/main/java/jadx/IJadxArgs.java
+0
-2
JadxArgs.java
src/main/java/jadx/JadxArgs.java
+0
-8
ClassGen.java
src/main/java/jadx/codegen/ClassGen.java
+24
-15
CodeWriter.java
src/main/java/jadx/codegen/CodeWriter.java
+4
-1
ClassInfo.java
src/main/java/jadx/dex/info/ClassInfo.java
+38
-31
TypedVar.java
src/main/java/jadx/dex/instructions/args/TypedVar.java
+5
-1
BlockNode.java
src/main/java/jadx/dex/nodes/BlockNode.java
+1
-2
ClassNode.java
src/main/java/jadx/dex/nodes/ClassNode.java
+2
-2
RootNode.java
src/main/java/jadx/dex/nodes/RootNode.java
+5
-5
BlockMakerVisitor.java
src/main/java/jadx/dex/visitors/BlockMakerVisitor.java
+15
-13
BlockProcessingHelper.java
src/main/java/jadx/dex/visitors/BlockProcessingHelper.java
+7
-2
ClassModifier.java
src/main/java/jadx/dex/visitors/ClassModifier.java
+14
-5
CodeShrinker.java
src/main/java/jadx/dex/visitors/CodeShrinker.java
+20
-10
EnumVisitor.java
src/main/java/jadx/dex/visitors/EnumVisitor.java
+19
-7
No files found.
src/main/java/jadx/IJadxArgs.java
View file @
cb6ff606
...
...
@@ -18,8 +18,6 @@ public interface IJadxArgs {
boolean
isFallbackMode
();
boolean
isNotObfuscated
();
boolean
isVerbose
();
boolean
isPrintHelp
();
...
...
src/main/java/jadx/JadxArgs.java
View file @
cb6ff606
...
...
@@ -33,9 +33,6 @@ public class JadxArgs implements IJadxArgs {
@Parameter
(
names
=
{
"-f"
,
"--fallback"
},
description
=
"make simple dump (using goto instead of 'if', 'for', etc)"
,
help
=
true
)
protected
boolean
fallbackMode
=
false
;
@Parameter
(
names
=
{
"--not-obfuscated"
},
description
=
"set this flag if code not obfuscated"
)
protected
boolean
notObfuscated
=
false
;
@Parameter
(
names
=
{
"--cfg"
},
description
=
"save methods control flow graph"
)
protected
boolean
cfgOutput
=
false
;
...
...
@@ -178,11 +175,6 @@ public class JadxArgs implements IJadxArgs {
}
@Override
public
boolean
isNotObfuscated
()
{
return
notObfuscated
;
}
@Override
public
boolean
isVerbose
()
{
return
verbose
;
}
...
...
src/main/java/jadx/codegen/ClassGen.java
View file @
cb6ff606
...
...
@@ -82,6 +82,9 @@ public class ClassGen {
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
return
;
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
INCONSISTENT_CODE
))
code
.
startLine
(
"// jadx: inconsistent code"
);
makeClassDeclaration
(
code
);
makeClassBody
(
code
);
code
.
endl
();
...
...
@@ -124,7 +127,7 @@ public class ClassGen {
else
clsCode
.
add
(
"implements "
);
for
(
Iterator
<
ClassInfo
>
it
=
cls
.
getInterfaces
().
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
ClassInfo
>
it
=
cls
.
getInterfaces
().
iterator
();
it
.
hasNext
();
)
{
ClassInfo
interf
=
it
.
next
();
clsCode
.
add
(
useClass
(
interf
));
if
(
it
.
hasNext
())
...
...
@@ -150,7 +153,7 @@ public class ClassGen {
code
.
add
(
useClass
(
type
));
if
(
list
!=
null
&&
!
list
.
isEmpty
())
{
code
.
add
(
" extends "
);
for
(
Iterator
<
ArgType
>
it
=
list
.
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
ArgType
>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
ArgType
g
=
it
.
next
();
code
.
add
(
useClass
(
g
));
if
(
it
.
hasNext
())
{
...
...
@@ -167,11 +170,16 @@ public class ClassGen {
public
void
makeClassBody
(
CodeWriter
clsCode
)
throws
CodegenException
{
clsCode
.
add
(
'{'
);
CodeWriter
mthsCode
=
makeMethods
(
clsCode
,
cls
.
getMethods
());
clsCode
.
add
(
makeFields
(
clsCode
,
cls
,
cls
.
getFields
()));
CodeWriter
fieldsCode
=
makeFields
(
clsCode
,
cls
,
cls
.
getFields
());
clsCode
.
add
(
fieldsCode
);
if
(
fieldsCode
.
notEmpty
()
&&
mthsCode
.
notEmpty
())
clsCode
.
endl
();
// insert inner classes code
if
(
cls
.
getInnerClasses
().
size
()
!=
0
)
{
clsCode
.
add
(
makeInnerClasses
(
cls
,
clsCode
.
getIndent
()));
if
(
mthsCode
.
notEmpty
())
clsCode
.
endl
();
}
clsCode
.
add
(
mthsCode
);
clsCode
.
startLine
(
'}'
);
...
...
@@ -192,7 +200,7 @@ public class ClassGen {
private
CodeWriter
makeMethods
(
CodeWriter
clsCode
,
List
<
MethodNode
>
mthList
)
{
CodeWriter
code
=
new
CodeWriter
(
clsCode
.
getIndent
()
+
1
);
for
(
Iterator
<
MethodNode
>
it
=
mthList
.
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
MethodNode
>
it
=
mthList
.
iterator
();
it
.
hasNext
();
)
{
MethodNode
mth
=
it
.
next
();
if
(
mth
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
continue
;
...
...
@@ -235,16 +243,19 @@ public class ClassGen {
EnumClassAttr
enumFields
=
(
EnumClassAttr
)
cls
.
getAttributes
().
get
(
AttributeType
.
ENUM_CLASS
);
if
(
enumFields
!=
null
)
{
MethodGen
mthGen
=
new
MethodGen
(
this
,
enumFields
.
getStaticMethod
());
InsnGen
igen
=
new
InsnGen
(
mthGen
,
enumFields
.
getStaticMethod
(),
false
);
for
(
Iterator
<
EnumField
>
it
=
enumFields
.
getFields
().
iterator
();
it
.
hasNext
();)
{
InsnGen
igen
=
null
;
for
(
Iterator
<
EnumField
>
it
=
enumFields
.
getFields
().
iterator
();
it
.
hasNext
();
)
{
EnumField
f
=
it
.
next
();
code
.
startLine
(
f
.
getName
());
if
(
f
.
getArgs
().
size
()
!=
0
)
{
code
.
add
(
'('
);
for
(
Iterator
<
InsnArg
>
aIt
=
f
.
getArgs
().
iterator
();
aIt
.
hasNext
();)
{
for
(
Iterator
<
InsnArg
>
aIt
=
f
.
getArgs
().
iterator
();
aIt
.
hasNext
();
)
{
InsnArg
arg
=
aIt
.
next
();
if
(
igen
==
null
)
{
// don't init mth gen if this is simple enum
MethodGen
mthGen
=
new
MethodGen
(
this
,
enumFields
.
getStaticMethod
());
igen
=
new
InsnGen
(
mthGen
,
enumFields
.
getStaticMethod
(),
false
);
}
code
.
add
(
igen
.
arg
(
arg
));
if
(
aIt
.
hasNext
())
code
.
add
(
", "
);
...
...
@@ -281,8 +292,6 @@ public class ClassGen {
}
code
.
add
(
';'
);
}
if
(
fields
.
size
()
!=
0
)
code
.
endl
();
return
code
;
}
...
...
@@ -290,11 +299,11 @@ public class ClassGen {
if
(
clsType
.
isGenericType
())
{
return
clsType
.
getObject
();
}
return
useClass
(
ClassInfo
.
fromType
(
cls
.
dex
(),
cls
Type
));
return
useClass
(
ClassInfo
.
fromType
(
clsType
));
}
public
String
useClass
(
ClassInfo
classInfo
)
{
String
baseClass
=
useClassIn
ner
(
classInfo
);
String
baseClass
=
useClassIn
ternal
(
classInfo
);
ArgType
[]
generics
=
classInfo
.
getType
().
getGenericTypes
();
if
(
generics
!=
null
)
{
StringBuilder
sb
=
new
StringBuilder
();
...
...
@@ -318,9 +327,9 @@ public class ClassGen {
}
}
private
String
useClassIn
ner
(
ClassInfo
classInfo
)
{
private
String
useClassIn
ternal
(
ClassInfo
classInfo
)
{
if
(
parentGen
!=
null
)
return
parentGen
.
useClassIn
ner
(
classInfo
);
return
parentGen
.
useClassIn
ternal
(
classInfo
);
String
clsStr
=
classInfo
.
getFullName
();
if
(
fallback
)
...
...
src/main/java/jadx/codegen/CodeWriter.java
View file @
cb6ff606
...
...
@@ -133,6 +133,10 @@ public class CodeWriter {
}
}
public
boolean
notEmpty
()
{
return
buf
.
length
()
!=
0
;
}
@Override
public
String
toString
()
{
return
buf
.
toString
();
...
...
@@ -183,5 +187,4 @@ public class CodeWriter {
throw
new
JadxRuntimeException
(
"Can't create directory "
+
dir
);
}
}
}
src/main/java/jadx/dex/info/ClassInfo.java
View file @
cb6ff606
...
...
@@ -13,13 +13,6 @@ public final class ClassInfo {
private
static
final
Map
<
ArgType
,
ClassInfo
>
CLASSINFO_CACHE
=
new
WeakHashMap
<
ArgType
,
ClassInfo
>();
private
static
final
String
DEFAULT_PACKAGE_NAME
=
"defpackage"
;
private
final
String
clsName
;
private
final
String
clsPackage
;
private
final
ArgType
type
;
private
final
String
fullName
;
private
final
ClassInfo
parentClass
;
// not equals null if this is inner class
public
static
ClassInfo
fromDex
(
DexNode
dex
,
int
clsIndex
)
{
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
return
null
;
...
...
@@ -28,17 +21,17 @@ public final class ClassInfo {
if
(
type
.
isArray
())
type
=
ArgType
.
OBJECT
;
return
fromType
(
dex
,
type
);
return
fromType
(
type
);
}
public
static
ClassInfo
fromName
(
DexNode
dex
,
String
clsName
)
{
return
fromType
(
dex
,
ArgType
.
object
(
clsName
));
public
static
ClassInfo
fromName
(
String
clsName
)
{
return
fromType
(
ArgType
.
object
(
clsName
));
}
public
static
ClassInfo
fromType
(
DexNode
dex
,
ArgType
type
)
{
public
static
ClassInfo
fromType
(
ArgType
type
)
{
ClassInfo
cls
=
CLASSINFO_CACHE
.
get
(
type
);
if
(
cls
==
null
)
{
cls
=
new
ClassInfo
(
dex
,
type
);
cls
=
new
ClassInfo
(
type
);
CLASSINFO_CACHE
.
put
(
type
,
cls
);
}
return
cls
;
...
...
@@ -48,21 +41,28 @@ public final class ClassInfo {
CLASSINFO_CACHE
.
clear
();
}
private
ClassInfo
(
DexNode
dex
,
ArgType
type
)
{
private
final
ArgType
type
;
private
String
pkg
;
private
String
name
;
private
String
fullName
;
private
ClassInfo
parentClass
;
// not equals null if this is inner class
private
ClassInfo
(
ArgType
type
)
{
assert
type
.
isObject
()
:
"Not class type: "
+
type
;
this
.
type
=
type
;
splitNames
(
true
);
}
private
void
splitNames
(
boolean
canBeInner
)
{
String
fullObjectName
=
type
.
getObject
();
assert
fullObjectName
.
indexOf
(
'/'
)
==
-
1
:
"Raw type: "
+
type
;
boolean
notObfuscated
=
dex
.
root
().
getJadxArgs
().
isNotObfuscated
();
String
name
;
String
pkg
;
int
dot
=
fullObjectName
.
lastIndexOf
(
'.'
);
if
(
dot
==
-
1
)
{
// rename default package if it used from class with package (often for obfuscated apps),
pkg
=
(
notObfuscated
?
""
:
DEFAULT_PACKAGE_NAME
)
;
pkg
=
DEFAULT_PACKAGE_NAME
;
name
=
fullObjectName
;
}
else
{
pkg
=
fullObjectName
.
substring
(
0
,
dot
);
...
...
@@ -70,27 +70,30 @@ public final class ClassInfo {
}
int
sep
=
name
.
lastIndexOf
(
'$'
);
if
(
sep
>
0
&&
sep
!=
name
.
length
()
-
1
)
{
if
(
canBeInner
&&
sep
>
0
&&
sep
!=
name
.
length
()
-
1
)
{
String
parClsName
=
pkg
+
'.'
+
name
.
substring
(
0
,
sep
);
parentClass
=
fromName
(
dex
,
parClsName
);
parentClass
=
fromName
(
parClsName
);
name
=
name
.
substring
(
sep
+
1
);
}
else
{
parentClass
=
null
;
}
if
(
Character
.
isDigit
(
name
.
charAt
(
0
)))
char
firstChar
=
name
.
charAt
(
0
);
if
(
Character
.
isDigit
(
firstChar
))
{
name
=
"InnerClass_"
+
name
;
if
(
NameMapper
.
isReserved
(
name
))
}
else
if
(
firstChar
==
'$'
)
{
name
=
"_"
+
name
;
}
if
(
NameMapper
.
isReserved
(
name
))
{
name
+=
"_"
;
}
this
.
fullName
=
(
parentClass
!=
null
?
parentClass
.
getFullName
()
:
pkg
)
+
"."
+
name
;
this
.
clsName
=
name
;
this
.
clsPackage
=
pkg
;
this
.
name
=
name
;
}
public
String
getFullPath
()
{
return
clsPackage
.
replace
(
'.'
,
File
.
separatorChar
)
+
File
.
separatorChar
return
pkg
.
replace
(
'.'
,
File
.
separatorChar
)
+
File
.
separatorChar
+
getNameWithoutPackage
().
replace
(
'.'
,
'_'
);
}
...
...
@@ -99,19 +102,19 @@ public final class ClassInfo {
}
public
String
getShortName
()
{
return
clsN
ame
;
return
n
ame
;
}
public
String
getPackage
()
{
return
clsPackage
;
return
pkg
;
}
public
boolean
isPackageDefault
()
{
return
clsPackage
.
isEmpty
()
||
clsPackage
.
equals
(
DEFAULT_PACKAGE_NAME
);
return
pkg
.
isEmpty
()
||
pkg
.
equals
(
DEFAULT_PACKAGE_NAME
);
}
public
String
getNameWithoutPackage
()
{
return
(
parentClass
!=
null
?
parentClass
.
getNameWithoutPackage
()
+
"."
:
""
)
+
clsN
ame
;
return
(
parentClass
!=
null
?
parentClass
.
getNameWithoutPackage
()
+
"."
:
""
)
+
n
ame
;
}
public
ClassInfo
getParentClass
()
{
...
...
@@ -122,6 +125,10 @@ public final class ClassInfo {
return
parentClass
!=
null
;
}
public
void
notInner
()
{
splitNames
(
false
);
}
public
ArgType
getType
()
{
return
type
;
}
...
...
@@ -133,7 +140,7 @@ public final class ClassInfo {
@Override
public
int
hashCode
()
{
return
t
his
.
getFullName
()
.
hashCode
();
return
t
ype
.
hashCode
();
}
@Override
...
...
src/main/java/jadx/dex/instructions/args/TypedVar.java
View file @
cb6ff606
...
...
@@ -77,6 +77,10 @@ public class TypedVar {
@Override
public
String
toString
()
{
return
(
name
!=
null
?
"'"
+
name
+
"' "
:
""
)
+
type
.
toString
();
StringBuilder
sb
=
new
StringBuilder
();
if
(
name
!=
null
)
sb
.
append
(
'\''
).
append
(
name
).
append
(
"' "
);
sb
.
append
(
type
);
return
sb
.
toString
();
}
}
src/main/java/jadx/dex/nodes/BlockNode.java
View file @
cb6ff606
...
...
@@ -19,6 +19,7 @@ public class BlockNode extends AttrNode implements IBlock {
private
List
<
BlockNode
>
predecessors
=
new
ArrayList
<
BlockNode
>(
1
);
private
List
<
BlockNode
>
successors
=
new
ArrayList
<
BlockNode
>(
1
);
private
List
<
BlockNode
>
cleanSuccessors
;
private
BitSet
doms
;
// all dominators
private
BlockNode
idom
;
// immediate dominator
...
...
@@ -48,8 +49,6 @@ public class BlockNode extends AttrNode implements IBlock {
return
successors
;
}
private
List
<
BlockNode
>
cleanSuccessors
;
public
List
<
BlockNode
>
getCleanSuccessors
()
{
return
cleanSuccessors
;
}
...
...
src/main/java/jadx/dex/nodes/ClassNode.java
View file @
cb6ff606
...
...
@@ -154,10 +154,10 @@ public class ClassNode extends AttrNode implements ILoadable {
if
(
list
!=
null
&&
!
list
.
isEmpty
())
{
try
{
ArgType
st
=
list
.
remove
(
0
);
this
.
superClass
=
ClassInfo
.
fromType
(
dex
,
st
);
this
.
superClass
=
ClassInfo
.
fromType
(
st
);
int
i
=
0
;
for
(
ArgType
it
:
list
)
{
ClassInfo
interf
=
ClassInfo
.
fromType
(
dex
,
it
);
ClassInfo
interf
=
ClassInfo
.
fromType
(
it
);
interfaces
.
set
(
i
,
interf
);
i
++;
}
...
...
src/main/java/jadx/dex/nodes/RootNode.java
View file @
cb6ff606
...
...
@@ -56,16 +56,16 @@ public class RootNode {
if
(
cls
.
getClassInfo
().
isInner
())
inner
.
add
(
cls
);
}
getClasses
().
removeAll
(
inner
);
for
(
ClassNode
cls
:
inner
)
{
ClassNode
parent
=
resolveClass
(
cls
.
getClassInfo
().
getParentClass
());
if
(
parent
==
null
)
LOG
.
warn
(
"Can't add inner class: {} to {}"
,
cls
,
cls
.
getClassInfo
().
getParentClass
()
);
else
if
(
parent
==
null
)
{
cls
.
getClassInfo
().
notInner
(
);
}
else
{
parent
.
addInnerClass
(
cls
);
getClasses
().
remove
(
cls
);
}
}
inner
.
clear
();
}
public
List
<
ClassNode
>
getClasses
()
{
...
...
src/main/java/jadx/dex/visitors/BlockMakerVisitor.java
View file @
cb6ff606
...
...
@@ -159,7 +159,6 @@ public class BlockMakerVisitor extends AbstractVisitor {
BlockNode
destBlock
=
getBlock
(
h
.
getHandleOffset
(),
blocksMap
);
// skip self loop in handler
if
(
connBlock
!=
destBlock
)
// && !connBlock.getPredecessors().contains(destBlock))
connect
(
connBlock
,
destBlock
);
}
}
...
...
@@ -208,9 +207,10 @@ public class BlockMakerVisitor extends AbstractVisitor {
}
private
static
void
computeDominators
(
MethodNode
mth
)
{
int
nBlocks
=
mth
.
getBasicBlocks
().
size
();
List
<
BlockNode
>
basicBlocks
=
mth
.
getBasicBlocks
();
int
nBlocks
=
basicBlocks
.
size
();
for
(
int
i
=
0
;
i
<
nBlocks
;
i
++)
{
BlockNode
block
=
mth
.
getBasicBlocks
()
.
get
(
i
);
BlockNode
block
=
basicBlocks
.
get
(
i
);
block
.
setId
(
i
);
block
.
setDoms
(
new
BitSet
(
nBlocks
));
block
.
getDoms
().
set
(
0
,
nBlocks
);
...
...
@@ -224,7 +224,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
boolean
changed
;
do
{
changed
=
false
;
for
(
BlockNode
block
:
mth
.
getBasicBlocks
()
)
{
for
(
BlockNode
block
:
basicBlocks
)
{
if
(
block
==
entryBlock
)
continue
;
...
...
@@ -245,35 +245,36 @@ public class BlockMakerVisitor extends AbstractVisitor {
markLoops
(
mth
);
// clear self dominance
for
(
BlockNode
block
:
mth
.
getBasicBlocks
()
)
{
for
(
BlockNode
block
:
basicBlocks
)
{
block
.
getDoms
().
clear
(
block
.
getId
());
}
// calculate immediate dominators
for
(
BlockNode
block
:
mth
.
getBasicBlocks
()
)
{
for
(
BlockNode
block
:
basicBlocks
)
{
if
(
block
==
entryBlock
)
continue
;
if
(
block
.
getPredecessors
().
size
()
==
1
)
{
block
.
setIDom
(
block
.
getPredecessors
().
get
(
0
));
List
<
BlockNode
>
preds
=
block
.
getPredecessors
();
if
(
preds
.
size
()
==
1
)
{
block
.
setIDom
(
preds
.
get
(
0
));
}
else
{
BitSet
bs
=
new
BitSet
(
block
.
getDoms
().
length
());
bs
.
or
(
block
.
getDoms
());
for
(
int
i
=
bs
.
nextSetBit
(
0
);
i
>=
0
;
i
=
bs
.
nextSetBit
(
i
+
1
))
{
BlockNode
dom
=
mth
.
getBasicBlocks
()
.
get
(
i
);
BlockNode
dom
=
basicBlocks
.
get
(
i
);
bs
.
andNot
(
dom
.
getDoms
());
}
int
c
=
bs
.
cardinality
();
if
(
c
==
1
)
{
int
id
=
bs
.
nextSetBit
(
0
);
BlockNode
idom
=
mth
.
getBasicBlocks
()
.
get
(
id
);
BlockNode
idom
=
basicBlocks
.
get
(
id
);
block
.
setIDom
(
idom
);
idom
.
getDominatesOn
().
add
(
block
);
}
else
{
throw
new
JadxRuntimeException
(
"Can't find immediate dominator for block "
+
block
+
" in "
+
bs
+
" prec:"
+
block
.
getPredecessors
()
);
+
" in "
+
bs
+
" preds:"
+
preds
);
}
}
}
...
...
@@ -298,8 +299,9 @@ public class BlockMakerVisitor extends AbstractVisitor {
private
static
void
markReturnBlocks
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
if
(
block
.
getInstructions
().
size
()
==
1
)
{
if
(
block
.
getInstructions
().
get
(
0
).
getType
()
==
InsnType
.
RETURN
)
List
<
InsnNode
>
insns
=
block
.
getInstructions
();
if
(
insns
.
size
()
==
1
)
{
if
(
insns
.
get
(
0
).
getType
()
==
InsnType
.
RETURN
)
block
.
getAttributes
().
add
(
AttributeFlag
.
RETURN
);
}
}
...
...
src/main/java/jadx/dex/visitors/BlockProcessingHelper.java
View file @
cb6ff606
...
...
@@ -10,6 +10,7 @@ import jadx.dex.nodes.MethodNode;
import
jadx.dex.trycatch.CatchAttr
;
import
jadx.dex.trycatch.ExcHandlerAttr
;
import
jadx.dex.trycatch.ExceptionHandler
;
import
jadx.dex.trycatch.TryCatchBlock
;
import
jadx.utils.BlockUtils
;
public
class
BlockProcessingHelper
{
...
...
@@ -81,8 +82,12 @@ public class BlockProcessingHelper {
if
(
insn
.
getType
()
==
InsnType
.
THROW
)
{
CatchAttr
catchAttr
=
(
CatchAttr
)
insn
.
getAttributes
().
get
(
AttributeType
.
CATCH_BLOCK
);
if
(
catchAttr
!=
null
)
{
handlerAttr
.
getTryBlock
().
merge
(
mth
,
catchAttr
.
getTryBlock
());
catchAttr
.
getTryBlock
().
removeInsn
(
insn
);
TryCatchBlock
handlerBlock
=
handlerAttr
.
getTryBlock
();
TryCatchBlock
catchBlock
=
catchAttr
.
getTryBlock
();
if
(
handlerBlock
!=
catchBlock
)
{
// TODO: why it can be?
handlerBlock
.
merge
(
mth
,
catchBlock
);
catchBlock
.
removeInsn
(
insn
);
}
}
}
}
...
...
src/main/java/jadx/dex/visitors/ClassModifier.java
View file @
cb6ff606
...
...
@@ -18,7 +18,7 @@ public class ClassModifier extends AbstractVisitor {
visit
(
inner
);
}
for
(
Iterator
<
MethodNode
>
it
=
cls
.
getMethods
().
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
MethodNode
>
it
=
cls
.
getMethods
().
iterator
();
it
.
hasNext
();
)
{
MethodNode
mth
=
it
.
next
();
AccessInfo
af
=
mth
.
getAccessFlags
();
...
...
@@ -34,17 +34,26 @@ public class ClassModifier extends AbstractVisitor {
if
(
af
.
isConstructor
()
&&
af
.
isPublic
()
&&
mth
.
getArguments
(
false
).
isEmpty
())
{
List
<
BlockNode
>
bb
=
mth
.
getBasicBlocks
();
if
(
bb
.
isEmpty
()
||
(
bb
.
size
()
==
1
&&
bb
.
get
(
0
).
getInstructions
().
isEmpty
()))
{
if
(
mth
.
getSuperCall
()
==
null
)
if
(
mth
.
getSuperCall
()
==
null
)
{
List
<
BlockNode
>
bb
=
mth
.
getBasicBlocks
();
if
(
bb
.
isEmpty
()
||
allBlocksEmpty
(
bb
))
{
it
.
remove
();
}
}
}
}
return
false
;
}
private
boolean
isMethodUniq
(
ClassNode
cls
,
MethodNode
mth
)
{
private
static
boolean
allBlocksEmpty
(
List
<
BlockNode
>
blocks
)
{
for
(
BlockNode
block
:
blocks
)
{
if
(
block
.
getInstructions
().
size
()
!=
0
)
return
false
;
}
return
true
;
}
private
static
boolean
isMethodUniq
(
ClassNode
cls
,
MethodNode
mth
)
{
MethodInfo
mi
=
mth
.
getMethodInfo
();
for
(
MethodNode
otherMth
:
cls
.
getMethods
())
{
MethodInfo
omi
=
otherMth
.
getMethodInfo
();
...
...
src/main/java/jadx/dex/visitors/CodeShrinker.java
View file @
cb6ff606
...
...
@@ -36,24 +36,26 @@ public class CodeShrinker extends AbstractVisitor {
private
static
void
shrink
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
InstructionRemover
remover
=
new
InstructionRemover
(
block
.
getInstructions
()
);
for
(
int
i
=
0
;
i
<
block
.
getInstructions
().
size
();
i
++)
{
InsnNode
insn
=
block
.
getInstructions
().
get
(
i
);
List
<
InsnNode
>
insnList
=
block
.
getInstructions
(
);
InstructionRemover
remover
=
new
InstructionRemover
(
insnList
);
for
(
InsnNode
insn
:
insnList
)
{
// wrap instructions
if
(
insn
.
getResult
()
!=
null
)
{
List
<
InsnArg
>
use
=
insn
.
getResult
().
getTypedVar
().
getUseList
();
if
(
use
.
size
()
==
1
)
{
RegisterArg
result
=
insn
.
getResult
();
if
(
result
!=
null
)
{
List
<
InsnArg
>
useList
=
result
.
getTypedVar
().
getUseList
();
if
(
useList
.
size
()
==
1
)
{
// variable is used only in this instruction
// TODO not correct sometimes :(
remover
.
add
(
insn
);
}
else
if
(
use
.
size
()
==
2
)
{
InsnArg
useInsnArg
=
use
.
get
(
1
);
}
else
if
(
use
List
.
size
()
==
2
)
{
InsnArg
useInsnArg
=
selectOther
(
useList
,
result
);
InsnNode
useInsn
=
useInsnArg
.
getParentInsn
();
if
(
useInsn
==
null
)
{
LOG
.
debug
(
"parent insn null in "
+
useInsnArg
+
" from "
+
insn
+
" mth: "
+
mth
);
}
else
if
(
useInsn
!=
insn
)
{
boolean
wrap
=
false
;
if
(
false
&&
insn
.
getResult
().
getTypedVar
().
getName
()
!=
null
)
{
// TODO
if
(
false
&&
result
.
getTypedVar
().
getName
()
!=
null
)
{
// don't wrap if result variable has name from debug info
wrap
=
false
;
}
else
if
(
BlockUtils
.
blockContains
(
block
,
useInsn
))
{
...
...
@@ -181,10 +183,18 @@ public class CodeShrinker extends AbstractVisitor {
list
.
removeAll
(
args
);
}
i
++;
if
(
i
>
1000
0
)
if
(
i
>
1000
)
throw
new
JadxRuntimeException
(
"Can't inline arguments for: "
+
arg
+
" insn: "
+
assignInsn
);
}
while
(!
list
.
isEmpty
());
return
arg
.
wrapInstruction
(
assignInsn
);
}
private
static
InsnArg
selectOther
(
List
<
InsnArg
>
list
,
RegisterArg
insn
)
{
InsnArg
first
=
list
.
get
(
0
);
if
(
first
==
insn
)
return
list
.
get
(
1
);
else
return
first
;
}
}
src/main/java/jadx/dex/visitors/EnumVisitor.java
View file @
cb6ff606
...
...
@@ -22,7 +22,11 @@ import java.util.ArrayList;
import
java.util.Iterator
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
EnumVisitor
extends
AbstractVisitor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
EnumVisitor
.
class
);
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
JadxException
{
...
...
@@ -32,7 +36,7 @@ public class EnumVisitor extends AbstractVisitor {
// collect enum fields, remove synthetic
List
<
FieldNode
>
enumFields
=
new
ArrayList
<
FieldNode
>();
for
(
Iterator
<
FieldNode
>
it
=
cls
.
getFields
().
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
FieldNode
>
it
=
cls
.
getFields
().
iterator
();
it
.
hasNext
();
)
{
FieldNode
f
=
it
.
next
();
if
(
f
.
getAccessFlags
().
isEnum
())
{
enumFields
.
add
(
f
);
...
...
@@ -45,7 +49,7 @@ public class EnumVisitor extends AbstractVisitor {
MethodNode
staticMethod
=
null
;
// remove synthetic methods
for
(
Iterator
<
MethodNode
>
it
=
cls
.
getMethods
().
iterator
();
it
.
hasNext
();)
{
for
(
Iterator
<
MethodNode
>
it
=
cls
.
getMethods
().
iterator
();
it
.
hasNext
();
)
{
MethodNode
mth
=
it
.
next
();
MethodInfo
mi
=
mth
.
getMethodInfo
();
if
(
mi
.
isClassInit
())
{
...
...
@@ -60,11 +64,18 @@ public class EnumVisitor extends AbstractVisitor {
}
}
if
(
staticMethod
==
null
)
throw
new
JadxException
(
"Enum class init method not found"
);
EnumClassAttr
attr
=
new
EnumClassAttr
(
enumFields
.
size
());
cls
.
getAttributes
().
add
(
attr
);
if
(
staticMethod
==
null
)
{
LOG
.
warn
(
"Enum class init method not found: {}"
,
cls
);
// for this broken enum puts found fields and mark as inconsistent
cls
.
getAttributes
().
add
(
AttributeFlag
.
INCONSISTENT_CODE
);
for
(
FieldNode
field
:
enumFields
)
{
attr
.
getFields
().
add
(
new
EnumField
(
field
.
getName
(),
0
));
}
return
false
;
}
attr
.
setStaticMethod
(
staticMethod
);
// move enum specific instruction from static method to separate list
...
...
@@ -117,7 +128,8 @@ public class EnumVisitor extends AbstractVisitor {
constrArg
=
iArg
;
}
else
{
constrArg
=
CodeShrinker
.
inlineArgument
(
staticMethod
,
(
RegisterArg
)
iArg
);
assert
constrArg
!=
null
;
if
(
constrArg
==
null
)
throw
new
JadxException
(
"Can't inline constructor arg in enum: "
+
cls
);
}
field
.
getArgs
().
add
(
constrArg
);
}
...
...
@@ -127,7 +139,7 @@ public class EnumVisitor extends AbstractVisitor {
for
(
ClassNode
innerCls
:
cls
.
getInnerClasses
())
{
if
(
innerCls
.
getClassInfo
().
equals
(
co
.
getClassType
()))
{
// remove constructor, because it is anonymous class
for
(
Iterator
<?>
mit
=
innerCls
.
getMethods
().
iterator
();
mit
.
hasNext
();)
{
for
(
Iterator
<?>
mit
=
innerCls
.
getMethods
().
iterator
();
mit
.
hasNext
();
)
{
MethodNode
innerMth
=
(
MethodNode
)
mit
.
next
();
if
(
innerMth
.
getAccessFlags
().
isConstructor
())
mit
.
remove
();
...
...
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