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
86b04586
Commit
86b04586
authored
Oct 26, 2013
by
13.beta2
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: replace switch labels with matched static final fields, searching up to root ClassNode
parent
36cfc9d1
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
67 additions
and
28 deletions
+67
-28
RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+19
-4
InsnDecoder.java
...src/main/java/jadx/core/dex/instructions/InsnDecoder.java
+5
-3
SwitchNode.java
.../src/main/java/jadx/core/dex/instructions/SwitchNode.java
+3
-3
ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+9
-1
SwitchRegion.java
...ore/src/main/java/jadx/core/dex/regions/SwitchRegion.java
+4
-4
ModVisitor.java
...core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
+19
-5
RegionMaker.java
...main/java/jadx/core/dex/visitors/regions/RegionMaker.java
+8
-8
No files found.
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
View file @
86b04586
...
...
@@ -5,8 +5,10 @@ import jadx.core.dex.attributes.AttributeType;
import
jadx.core.dex.attributes.DeclareVariableAttr
;
import
jadx.core.dex.attributes.ForceReturnAttr
;
import
jadx.core.dex.attributes.IAttribute
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.instructions.ArithNode
;
import
jadx.core.dex.instructions.IfOp
;
import
jadx.core.dex.instructions.IndexInsnNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.SwitchNode
;
import
jadx.core.dex.instructions.args.ArgType
;
...
...
@@ -236,11 +238,16 @@ public class RegionGen extends InsnGen {
int
size
=
sw
.
getKeys
().
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
List
<
Integer
>
keys
=
sw
.
getKeys
().
get
(
i
);
List
<
Object
>
keys
=
sw
.
getKeys
().
get
(
i
);
IContainer
c
=
sw
.
getCases
().
get
(
i
);
for
(
Integer
k
:
keys
)
{
for
(
Object
k
:
keys
)
{
code
.
startLine
(
"case "
);
code
.
add
(
TypeGen
.
literalToString
(
k
,
arg
.
getType
()));
if
(
k
instanceof
IndexInsnNode
)
{
code
.
add
(
sfield
((
FieldInfo
)
((
IndexInsnNode
)
k
).
getIndex
()));
}
else
{
code
.
add
(
TypeGen
.
literalToString
((
Integer
)
k
,
arg
.
getType
()));
}
code
.
add
(
':'
);
}
makeCaseBlock
(
c
,
code
);
...
...
@@ -305,4 +312,12 @@ public class RegionGen extends InsnGen {
}
}
}
private
String
sfield
(
FieldInfo
field
)
{
String
thisClass
=
mth
.
getParentClass
().
getFullName
();
if
(
field
.
getDeclClass
().
getFullName
().
equals
(
thisClass
))
{
return
field
.
getName
();
}
else
{
return
useClass
(
field
.
getDeclClass
())
+
'.'
+
field
.
getName
();
}
}
}
\ No newline at end of file
jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java
View file @
86b04586
...
...
@@ -571,19 +571,21 @@ public class InsnDecoder {
private
InsnNode
decodeSwitch
(
DecodedInstruction
insn
,
int
offset
,
boolean
packed
)
{
int
payloadOffset
=
insn
.
getTarget
();
DecodedInstruction
payload
=
insnArr
[
payloadOffset
];
in
t
[]
keys
;
Objec
t
[]
keys
;
int
[]
targets
;
if
(
packed
)
{
PackedSwitchPayloadDecodedInstruction
ps
=
(
PackedSwitchPayloadDecodedInstruction
)
payload
;
targets
=
ps
.
getTargets
();
keys
=
new
in
t
[
targets
.
length
];
keys
=
new
Objec
t
[
targets
.
length
];
int
k
=
ps
.
getFirstKey
();
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
keys
[
i
]
=
k
++;
}
else
{
SparseSwitchPayloadDecodedInstruction
ss
=
(
SparseSwitchPayloadDecodedInstruction
)
payload
;
targets
=
ss
.
getTargets
();
keys
=
ss
.
getKeys
();
keys
=
new
Object
[
targets
.
length
];
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
++)
{
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
View file @
86b04586
...
...
@@ -8,11 +8,11 @@ import java.util.Arrays;
public
class
SwitchNode
extends
InsnNode
{
private
final
in
t
[]
keys
;
private
final
Objec
t
[]
keys
;
private
final
int
[]
targets
;
private
final
int
def
;
// next instruction
public
SwitchNode
(
InsnArg
arg
,
in
t
[]
keys
,
int
[]
targets
,
int
def
)
{
public
SwitchNode
(
InsnArg
arg
,
Objec
t
[]
keys
,
int
[]
targets
,
int
def
)
{
super
(
InsnType
.
SWITCH
,
1
);
this
.
keys
=
keys
;
this
.
targets
=
targets
;
...
...
@@ -24,7 +24,7 @@ public class SwitchNode extends InsnNode {
return
keys
.
length
;
}
public
in
t
[]
getKeys
()
{
public
Objec
t
[]
getKeys
()
{
return
keys
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
View file @
86b04586
...
...
@@ -237,7 +237,15 @@ public class ClassNode extends LineAttrNode implements ILoadable {
}
public
FieldNode
getConstField
(
Object
o
)
{
FieldNode
field
=
constFields
.
get
(
o
);
ClassNode
cn
=
this
;
FieldNode
field
;
do
{
field
=
cn
.
constFields
.
get
(
o
);
}
while
(
field
==
null
&&
(
cn
.
clsInfo
.
getParentClass
()
!=
null
)
&&
(
cn
=
dex
.
resolveClass
(
cn
.
clsInfo
.
getParentClass
()))
!=
null
);
if
(
field
==
null
)
field
=
dex
.
getConstFields
().
get
(
o
);
return
field
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
View file @
86b04586
...
...
@@ -12,14 +12,14 @@ public final class SwitchRegion extends AbstractRegion {
private
final
BlockNode
header
;
private
final
List
<
List
<
Integer
>>
keys
;
private
final
List
<
List
<
Object
>>
keys
;
private
final
List
<
IContainer
>
cases
;
private
IContainer
defCase
;
public
SwitchRegion
(
IRegion
parent
,
BlockNode
header
)
{
super
(
parent
);
this
.
header
=
header
;
this
.
keys
=
new
ArrayList
<
List
<
Integer
>>();
this
.
keys
=
new
ArrayList
<
List
<
Object
>>();
this
.
cases
=
new
ArrayList
<
IContainer
>();
}
...
...
@@ -27,7 +27,7 @@ public final class SwitchRegion extends AbstractRegion {
return
header
;
}
public
void
addCase
(
List
<
Integer
>
keysList
,
IContainer
c
)
{
public
void
addCase
(
List
<
Object
>
keysList
,
IContainer
c
)
{
keys
.
add
(
keysList
);
cases
.
add
(
c
);
}
...
...
@@ -40,7 +40,7 @@ public final class SwitchRegion extends AbstractRegion {
return
defCase
;
}
public
List
<
List
<
Integer
>>
getKeys
()
{
public
List
<
List
<
Object
>>
getKeys
()
{
return
keys
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
View file @
86b04586
...
...
@@ -9,6 +9,7 @@ import jadx.core.dex.instructions.FillArrayNode;
import
jadx.core.dex.instructions.IndexInsnNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.SwitchNode
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
...
...
@@ -114,16 +115,16 @@ public class ModVisitor extends AbstractVisitor {
LiteralArg
arg
=
(
LiteralArg
)
insn
.
getArg
(
0
);
ArgType
type
=
arg
.
getType
();
long
lit
=
arg
.
getLiteral
();
if
(
Math
.
abs
(
lit
)
>
0xFF
)
{
if
(
type
.
equals
(
ArgType
.
DOUBLE
))
f
=
parentClass
.
getConstField
(
Double
.
longBitsToDouble
(
lit
));
else
if
(
type
.
equals
(
ArgType
.
FLOAT
))
f
=
parentClass
.
getConstField
(
Float
.
intBitsToFloat
((
int
)
lit
));
else
if
(
Math
.
abs
(
lit
)
>
0x1
)
{
if
(
type
.
equals
(
ArgType
.
INT
))
f
=
parentClass
.
getConstField
((
int
)
lit
);
else
if
(
type
.
equals
(
ArgType
.
LONG
))
f
=
parentClass
.
getConstField
(
lit
);
}
if
(
type
.
equals
(
ArgType
.
DOUBLE
))
f
=
parentClass
.
getConstField
(
Double
.
longBitsToDouble
(
lit
));
else
if
(
type
.
equals
(
ArgType
.
FLOAT
))
f
=
parentClass
.
getConstField
(
Float
.
intBitsToFloat
((
int
)
lit
));
}
if
(
f
!=
null
)
{
InsnNode
inode
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
...
...
@@ -132,6 +133,19 @@ public class ModVisitor extends AbstractVisitor {
}
break
;
case
SWITCH:
SwitchNode
sn
=
(
SwitchNode
)
insn
;
parentClass
=
mth
.
getParentClass
();
f
=
null
;
for
(
int
k
=
0
;
k
<
sn
.
getCasesCount
();
k
++)
{
f
=
parentClass
.
getConstField
((
Integer
)
sn
.
getKeys
()[
k
]);
if
(
f
!=
null
)
{
InsnNode
inode
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
sn
.
getKeys
()[
k
]
=
inode
;
}
}
break
;
default
:
break
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
View file @
86b04586
...
...
@@ -583,21 +583,21 @@ public class RegionMaker {
int
len
=
insn
.
getTargets
().
length
;
// sort by target
Map
<
Integer
,
List
<
Integer
>>
casesMap
=
new
LinkedHashMap
<
Integer
,
List
<
Integer
>>(
len
);
Map
<
Integer
,
List
<
Object
>>
casesMap
=
new
LinkedHashMap
<
Integer
,
List
<
Object
>>(
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
in
t
key
=
insn
.
getKeys
()[
i
];
Objec
t
key
=
insn
.
getKeys
()[
i
];
int
targ
=
insn
.
getTargets
()[
i
];
List
<
Integer
>
keys
=
casesMap
.
get
(
targ
);
List
<
Object
>
keys
=
casesMap
.
get
(
targ
);
if
(
keys
==
null
)
{
keys
=
new
ArrayList
<
Integer
>(
1
);
keys
=
new
ArrayList
<
Object
>(
2
);
casesMap
.
put
(
targ
,
keys
);
}
keys
.
add
(
key
);
}
Map
<
BlockNode
,
List
<
Integer
>>
blocksMap
=
new
LinkedHashMap
<
BlockNode
,
List
<
Integer
>>(
len
);
for
(
Entry
<
Integer
,
List
<
Integer
>>
entry
:
casesMap
.
entrySet
())
{
BlockNode
c
=
getBlockByOffset
(
entry
.
getKey
(),
block
.
getSuccessors
());
Map
<
BlockNode
,
List
<
Object
>>
blocksMap
=
new
LinkedHashMap
<
BlockNode
,
List
<
Object
>>(
len
);
for
(
Entry
<
Integer
,
List
<
Object
>>
entry
:
casesMap
.
entrySet
())
{
BlockNode
c
=
getBlockByOffset
(
(
int
)
entry
.
getKey
(),
block
.
getSuccessors
());
assert
c
!=
null
;
blocksMap
.
put
(
c
,
entry
.
getValue
());
}
...
...
@@ -650,7 +650,7 @@ public class RegionMaker {
if
(!
stack
.
containsExit
(
defCase
))
{
sw
.
setDefaultCase
(
makeRegion
(
defCase
,
stack
));
}
for
(
Entry
<
BlockNode
,
List
<
Integer
>>
entry
:
blocksMap
.
entrySet
())
{
for
(
Entry
<
BlockNode
,
List
<
Object
>>
entry
:
blocksMap
.
entrySet
())
{
BlockNode
c
=
entry
.
getKey
();
if
(
stack
.
containsExit
(
c
))
{
// empty case block
...
...
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