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
b29223c5
Commit
b29223c5
authored
Apr 14, 2018
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix enum processing order, remove synchronization (#257)
parent
d5cfdfb5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
61 additions
and
51 deletions
+61
-51
EnumMapAttr.java
...main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java
+18
-5
ReSugarCode.java
...ore/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
+43
-46
No files found.
jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java
View file @
b29223c5
package
jadx
.
core
.
dex
.
attributes
.
nodes
;
package
jadx
.
core
.
dex
.
attributes
.
nodes
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.IAttribute
;
import
jadx.core.dex.attributes.IAttribute
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
java.util.HashMap
;
import
java.util.Map
;
public
class
EnumMapAttr
implements
IAttribute
{
public
class
EnumMapAttr
implements
IAttribute
{
public
static
class
KeyValueMap
{
public
static
class
KeyValueMap
{
...
@@ -21,9 +23,14 @@ public class EnumMapAttr implements IAttribute {
...
@@ -21,9 +23,14 @@ public class EnumMapAttr implements IAttribute {
}
}
}
}
private
final
Map
<
FieldNode
,
KeyValueMap
>
fieldsMap
=
new
HashMap
<>();
@Nullable
private
Map
<
FieldNode
,
KeyValueMap
>
fieldsMap
;
@Nullable
public
KeyValueMap
getMap
(
FieldNode
field
)
{
public
KeyValueMap
getMap
(
FieldNode
field
)
{
if
(
fieldsMap
==
null
)
{
return
null
;
}
return
fieldsMap
.
get
(
field
);
return
fieldsMap
.
get
(
field
);
}
}
...
@@ -31,11 +38,18 @@ public class EnumMapAttr implements IAttribute {
...
@@ -31,11 +38,18 @@ public class EnumMapAttr implements IAttribute {
KeyValueMap
map
=
getMap
(
field
);
KeyValueMap
map
=
getMap
(
field
);
if
(
map
==
null
)
{
if
(
map
==
null
)
{
map
=
new
KeyValueMap
();
map
=
new
KeyValueMap
();
if
(
fieldsMap
==
null
)
{
fieldsMap
=
new
HashMap
<>();
}
fieldsMap
.
put
(
field
,
map
);
fieldsMap
.
put
(
field
,
map
);
}
}
map
.
put
(
key
,
value
);
map
.
put
(
key
,
value
);
}
}
public
boolean
isEmpty
()
{
return
fieldsMap
==
null
||
fieldsMap
.
isEmpty
();
}
@Override
@Override
public
AType
<
EnumMapAttr
>
getType
()
{
public
AType
<
EnumMapAttr
>
getType
()
{
return
AType
.
ENUM_MAP
;
return
AType
.
ENUM_MAP
;
...
@@ -45,5 +59,4 @@ public class EnumMapAttr implements IAttribute {
...
@@ -45,5 +59,4 @@ public class EnumMapAttr implements IAttribute {
public
String
toString
()
{
public
String
toString
()
{
return
"Enum fields map: "
+
fieldsMap
;
return
"Enum fields map: "
+
fieldsMap
;
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
View file @
b29223c5
package
jadx
.
core
.
dex
.
visitors
;
package
jadx
.
core
.
dex
.
visitors
;
import
jadx.core.ProcessClass
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.EnumMapAttr
;
import
jadx.core.dex.attributes.nodes.EnumMapAttr
;
...
@@ -18,18 +23,13 @@ import jadx.core.dex.instructions.args.InsnWrapArg;
...
@@ -18,18 +23,13 @@ import jadx.core.dex.instructions.args.InsnWrapArg;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.utils.InstructionRemover
;
import
jadx.core.utils.InstructionRemover
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxException
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
@JadxVisitor
(
@JadxVisitor
(
name
=
"ReSugarCode"
,
name
=
"ReSugarCode"
,
desc
=
"Simplify synthetic or verbose code"
,
desc
=
"Simplify synthetic or verbose code"
,
...
@@ -40,6 +40,12 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -40,6 +40,12 @@ public class ReSugarCode extends AbstractVisitor {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ReSugarCode
.
class
);
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ReSugarCode
.
class
);
@Override
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
JadxException
{
initClsEnumMap
(
cls
);
return
true
;
}
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
{
if
(
mth
.
isNoCode
())
{
return
;
return
;
...
@@ -78,7 +84,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -78,7 +84,7 @@ public class ReSugarCode extends AbstractVisitor {
* Replace new array and sequence of array-put to new filled-array instruction.
* Replace new array and sequence of array-put to new filled-array instruction.
*/
*/
private
static
InsnNode
processNewArray
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
private
static
InsnNode
processNewArray
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
InstructionRemover
remover
)
{
InstructionRemover
remover
)
{
NewArrayNode
newArrayInsn
=
(
NewArrayNode
)
instructions
.
get
(
i
);
NewArrayNode
newArrayInsn
=
(
NewArrayNode
)
instructions
.
get
(
i
);
InsnArg
arg
=
newArrayInsn
.
getArg
(
0
);
InsnArg
arg
=
newArrayInsn
.
getArg
(
0
);
if
(!
arg
.
isLiteral
())
{
if
(!
arg
.
isLiteral
())
{
...
@@ -115,7 +121,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -115,7 +121,7 @@ public class ReSugarCode extends AbstractVisitor {
if
(
wrapInsn
.
getType
()
!=
InsnType
.
AGET
)
{
if
(
wrapInsn
.
getType
()
!=
InsnType
.
AGET
)
{
return
;
return
;
}
}
EnumMapInfo
enumMapInfo
=
checkEnumMapAccess
(
mth
,
wrapInsn
);
EnumMapInfo
enumMapInfo
=
checkEnumMapAccess
(
mth
.
dex
()
,
wrapInsn
);
if
(
enumMapInfo
==
null
)
{
if
(
enumMapInfo
==
null
)
{
return
;
return
;
}
}
...
@@ -144,49 +150,40 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -144,49 +150,40 @@ public class ReSugarCode extends AbstractVisitor {
checkAndHideClass
(
enumMapField
.
getParentClass
());
checkAndHideClass
(
enumMapField
.
getParentClass
());
}
}
private
static
EnumMapAttr
.
KeyValueMap
getEnumMap
(
MethodNode
mth
,
FieldNode
field
)
{
private
static
void
initClsEnumMap
(
ClassNode
enumCls
)
{
ClassNode
syntheticClass
=
field
.
getParentClass
();
MethodNode
clsInitMth
=
enumCls
.
getClassInitMth
();
EnumMapAttr
mapAttr
=
syntheticClass
.
get
(
AType
.
ENUM_MAP
);
if
(
clsInitMth
==
null
||
clsInitMth
.
isNoCode
())
{
if
(
mapAttr
!=
null
)
{
return
;
return
mapAttr
.
getMap
(
field
);
}
}
synchronized
(
ProcessClass
.
getSyncObj
(
syntheticClass
))
{
EnumMapAttr
mapAttr
=
new
EnumMapAttr
();
mapAttr
=
new
EnumMapAttr
();
for
(
BlockNode
block
:
clsInitMth
.
getBasicBlocks
())
{
syntheticClass
.
addAttr
(
mapAttr
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
insn
.
getType
()
==
InsnType
.
APUT
)
{
MethodNode
clsInitMth
=
syntheticClass
.
searchMethodByName
(
"<clinit>()V"
);
addToEnumMap
(
enumCls
.
dex
(),
mapAttr
,
insn
);
if
(
clsInitMth
==
null
||
clsInitMth
.
isNoCode
())
{
return
null
;
}
if
(
clsInitMth
.
getBasicBlocks
()
==
null
)
{
try
{
clsInitMth
.
load
();
}
catch
(
DecodeException
e
)
{
LOG
.
error
(
"Load failed"
,
e
);
return
null
;
}
if
(
clsInitMth
.
getBasicBlocks
()
==
null
)
{
// TODO:
return
null
;
}
}
for
(
BlockNode
block
:
clsInitMth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
insn
.
getType
()
==
InsnType
.
APUT
)
{
addToEnumMap
(
mth
,
mapAttr
,
insn
);
}
}
}
}
}
return
mapAttr
.
getMap
(
field
);
}
}
if
(!
mapAttr
.
isEmpty
())
{
enumCls
.
addAttr
(
mapAttr
);
}
}
@Nullable
private
static
EnumMapAttr
.
KeyValueMap
getEnumMap
(
MethodNode
mth
,
FieldNode
field
)
{
ClassNode
syntheticClass
=
field
.
getParentClass
();
EnumMapAttr
mapAttr
=
syntheticClass
.
get
(
AType
.
ENUM_MAP
);
if
(
mapAttr
==
null
)
{
return
null
;
}
return
mapAttr
.
getMap
(
field
);
}
}
private
static
void
addToEnumMap
(
MethodNode
mth
,
EnumMapAttr
mapAttr
,
InsnNode
aputInsn
)
{
private
static
void
addToEnumMap
(
DexNode
dex
,
EnumMapAttr
mapAttr
,
InsnNode
aputInsn
)
{
InsnArg
litArg
=
aputInsn
.
getArg
(
2
);
InsnArg
litArg
=
aputInsn
.
getArg
(
2
);
if
(!
litArg
.
isLiteral
())
{
if
(!
litArg
.
isLiteral
())
{
return
;
return
;
}
}
EnumMapInfo
mapInfo
=
checkEnumMapAccess
(
mth
,
aputInsn
);
EnumMapInfo
mapInfo
=
checkEnumMapAccess
(
dex
,
aputInsn
);
if
(
mapInfo
==
null
)
{
if
(
mapInfo
==
null
)
{
return
;
return
;
}
}
...
@@ -203,7 +200,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -203,7 +200,7 @@ public class ReSugarCode extends AbstractVisitor {
if
(!(
index
instanceof
FieldInfo
))
{
if
(!(
index
instanceof
FieldInfo
))
{
return
;
return
;
}
}
FieldNode
fieldNode
=
mth
.
dex
()
.
resolveField
((
FieldInfo
)
index
);
FieldNode
fieldNode
=
dex
.
resolveField
((
FieldInfo
)
index
);
if
(
fieldNode
==
null
)
{
if
(
fieldNode
==
null
)
{
return
;
return
;
}
}
...
@@ -211,7 +208,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -211,7 +208,7 @@ public class ReSugarCode extends AbstractVisitor {
mapAttr
.
add
(
field
,
literal
,
fieldNode
);
mapAttr
.
add
(
field
,
literal
,
fieldNode
);
}
}
public
static
EnumMapInfo
checkEnumMapAccess
(
MethodNode
mth
,
InsnNode
checkInsn
)
{
public
static
EnumMapInfo
checkEnumMapAccess
(
DexNode
dex
,
InsnNode
checkInsn
)
{
InsnArg
sgetArg
=
checkInsn
.
getArg
(
0
);
InsnArg
sgetArg
=
checkInsn
.
getArg
(
0
);
InsnArg
invArg
=
checkInsn
.
getArg
(
1
);
InsnArg
invArg
=
checkInsn
.
getArg
(
1
);
if
(!
sgetArg
.
isInsnWrap
()
||
!
invArg
.
isInsnWrap
())
{
if
(!
sgetArg
.
isInsnWrap
()
||
!
invArg
.
isInsnWrap
())
{
...
@@ -226,7 +223,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -226,7 +223,7 @@ public class ReSugarCode extends AbstractVisitor {
if
(!
inv
.
getCallMth
().
getShortId
().
equals
(
"ordinal()I"
))
{
if
(!
inv
.
getCallMth
().
getShortId
().
equals
(
"ordinal()I"
))
{
return
null
;
return
null
;
}
}
ClassNode
enumCls
=
mth
.
dex
()
.
resolveClass
(
inv
.
getCallMth
().
getDeclClass
());
ClassNode
enumCls
=
dex
.
resolveClass
(
inv
.
getCallMth
().
getDeclClass
());
if
(
enumCls
==
null
||
!
enumCls
.
isEnum
())
{
if
(
enumCls
==
null
||
!
enumCls
.
isEnum
())
{
return
null
;
return
null
;
}
}
...
@@ -234,7 +231,7 @@ public class ReSugarCode extends AbstractVisitor {
...
@@ -234,7 +231,7 @@ public class ReSugarCode extends AbstractVisitor {
if
(!(
index
instanceof
FieldInfo
))
{
if
(!(
index
instanceof
FieldInfo
))
{
return
null
;
return
null
;
}
}
FieldNode
enumMapField
=
mth
.
dex
()
.
resolveField
((
FieldInfo
)
index
);
FieldNode
enumMapField
=
dex
.
resolveField
((
FieldInfo
)
index
);
if
(
enumMapField
==
null
||
!
enumMapField
.
getAccessFlags
().
isSynthetic
())
{
if
(
enumMapField
==
null
||
!
enumMapField
.
getAccessFlags
().
isSynthetic
())
{
return
null
;
return
null
;
}
}
...
...
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