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
e2018535
Commit
e2018535
authored
Aug 19, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: add ternary conditions processing
parent
ee56610f
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
133 additions
and
18 deletions
+133
-18
ConditionGen.java
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
+13
-1
TernaryInsn.java
...ain/java/jadx/core/dex/instructions/mods/TernaryInsn.java
+19
-1
IfCondition.java
...core/src/main/java/jadx/core/dex/regions/IfCondition.java
+17
-1
SimplifyVisitor.java
...src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
+3
-1
IfMakerHelper.java
...in/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
+45
-5
TestConditions14.java
...java/jadx/tests/internal/conditions/TestConditions14.java
+0
-9
TestTernaryInIf.java
.../java/jadx/tests/internal/conditions/TestTernaryInIf.java
+36
-0
No files found.
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
View file @
e2018535
...
...
@@ -33,6 +33,10 @@ public class ConditionGen extends InsnGen {
addCompare
(
code
,
condition
.
getCompare
());
break
;
case
TERNARY:
addTernary
(
code
,
condition
);
break
;
case
NOT:
addNot
(
code
,
condition
);
break
;
...
...
@@ -43,7 +47,7 @@ public class ConditionGen extends InsnGen {
break
;
default
:
throw
new
JadxRuntimeException
(
"Unknown condition mode: "
+
condition
);
throw
new
JadxRuntimeException
(
"Unknown condition mode: "
+
condition
.
getMode
()
);
}
}
...
...
@@ -94,6 +98,14 @@ public class ConditionGen extends InsnGen {
addArg
(
code
,
secondArg
,
isArgWrapNeeded
(
secondArg
));
}
private
void
addTernary
(
CodeWriter
code
,
IfCondition
condition
)
throws
CodegenException
{
add
(
code
,
condition
.
first
());
code
.
add
(
" ? "
);
add
(
code
,
condition
.
second
());
code
.
add
(
" : "
);
add
(
code
,
condition
.
third
());
}
private
void
addNot
(
CodeWriter
code
,
IfCondition
condition
)
throws
CodegenException
{
code
.
add
(
'!'
);
wrap
(
code
,
condition
.
getArgs
().
get
(
0
));
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java
View file @
e2018535
...
...
@@ -11,7 +11,11 @@ import jadx.core.utils.Utils;
public
class
TernaryInsn
extends
InsnNode
{
private
final
IfCondition
condition
;
private
IfCondition
condition
;
public
TernaryInsn
(
IfCondition
condition
,
RegisterArg
result
)
{
this
(
condition
,
result
,
LiteralArg
.
TRUE
,
LiteralArg
.
FALSE
);
}
public
TernaryInsn
(
IfCondition
condition
,
RegisterArg
result
,
InsnArg
th
,
InsnArg
els
)
{
super
(
InsnType
.
TERNARY
,
2
);
...
...
@@ -33,6 +37,20 @@ public class TernaryInsn extends InsnNode {
return
condition
;
}
public
void
simplifyCondition
()
{
condition
=
IfCondition
.
simplify
(
condition
);
if
(
condition
.
getMode
()
==
IfCondition
.
Mode
.
NOT
)
{
invert
();
}
}
private
void
invert
()
{
condition
=
IfCondition
.
invert
(
condition
);
InsnArg
tmp
=
getArg
(
0
);
setArg
(
0
,
getArg
(
1
));
setArg
(
1
,
tmp
);
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java
View file @
e2018535
...
...
@@ -22,6 +22,7 @@ public final class IfCondition {
public
enum
Mode
{
COMPARE
,
TERNARY
,
NOT
,
AND
,
OR
...
...
@@ -64,6 +65,10 @@ public final class IfCondition {
return
new
IfCondition
(
new
Compare
(
insn
));
}
public
static
IfCondition
ternary
(
IfCondition
a
,
IfCondition
b
,
IfCondition
c
)
{
return
new
IfCondition
(
Mode
.
TERNARY
,
Arrays
.
asList
(
a
,
b
,
c
));
}
public
static
IfCondition
merge
(
Mode
mode
,
IfCondition
a
,
IfCondition
b
)
{
if
(
a
.
getMode
()
==
mode
)
{
IfCondition
n
=
new
IfCondition
(
a
);
...
...
@@ -89,6 +94,10 @@ public final class IfCondition {
return
args
.
get
(
1
);
}
public
IfCondition
third
()
{
return
args
.
get
(
2
);
}
public
void
addArg
(
IfCondition
c
)
{
args
.
add
(
c
);
}
...
...
@@ -106,6 +115,8 @@ public final class IfCondition {
switch
(
mode
)
{
case
COMPARE:
return
new
IfCondition
(
cond
.
getCompare
().
invert
());
case
TERNARY:
return
ternary
(
not
(
cond
.
first
()),
cond
.
third
(),
cond
.
second
());
case
NOT:
return
cond
.
first
();
case
AND:
...
...
@@ -154,7 +165,10 @@ public final class IfCondition {
cond
=
new
IfCondition
(
cond
.
getMode
(),
args
);
}
if
(
cond
.
getMode
()
==
Mode
.
NOT
&&
cond
.
first
().
getMode
()
==
Mode
.
NOT
)
{
cond
=
cond
.
first
().
first
();
cond
=
invert
(
cond
.
first
());
}
if
(
cond
.
getMode
()
==
Mode
.
TERNARY
&&
cond
.
first
().
getMode
()
==
Mode
.
NOT
)
{
cond
=
invert
(
cond
);
}
// for condition with a lot of negations => make invert
...
...
@@ -216,6 +230,8 @@ public final class IfCondition {
switch
(
mode
)
{
case
COMPARE:
return
compare
.
toString
();
case
TERNARY:
return
first
()
+
" ? "
+
second
()
+
" : "
+
third
();
case
NOT:
return
"!"
+
first
();
case
AND:
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
View file @
e2018535
...
...
@@ -65,7 +65,7 @@ public class SimplifyVisitor extends AbstractVisitor {
simplifyIf
((
IfNode
)
insn
);
break
;
case
TERNARY:
simplifyTernary
((
TernaryInsn
)
insn
);
simplifyTernary
((
TernaryInsn
)
insn
);
break
;
case
INVOKE:
...
...
@@ -117,6 +117,8 @@ public class SimplifyVisitor extends AbstractVisitor {
IfCondition
condition
=
insn
.
getCondition
();
if
(
condition
.
isCompare
())
{
simplifyIf
(
condition
.
getCompare
().
getInsn
());
}
else
{
insn
.
simplifyCondition
();
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
View file @
e2018535
...
...
@@ -101,6 +101,11 @@ public class IfMakerHelper {
return
c1
.
size
()
==
c2
.
size
()
&&
c1
.
containsAll
(
c2
);
}
static
IfInfo
searchNestedIf
(
IfInfo
info
)
{
IfInfo
tmp
=
mergeNestedIfNodes
(
info
);
return
tmp
!=
null
?
tmp
:
info
;
}
static
IfInfo
mergeNestedIfNodes
(
IfInfo
currentIf
)
{
BlockNode
curThen
=
currentIf
.
getThenBlock
();
BlockNode
curElse
=
currentIf
.
getElseBlock
();
...
...
@@ -126,12 +131,13 @@ public class IfMakerHelper {
if
(!
RegionMaker
.
isEqualPaths
(
curElse
,
nextIf
.
getElseBlock
())
&&
!
RegionMaker
.
isEqualPaths
(
curThen
,
nextIf
.
getThenBlock
()))
{
// complex condition, run additional checks
if
(
checkConditionBranches
(
curThen
,
curElse
)
||
checkConditionBranches
(
curElse
,
curThen
))
{
if
(
checkConditionBranches
(
curThen
,
curElse
)
||
checkConditionBranches
(
curElse
,
curThen
))
{
return
null
;
}
BlockNode
otherBranchBlock
=
followThenBranch
?
curElse
:
curThen
;
if
(!
isPathExists
(
nextIf
.
getIfBlock
(),
otherBranchBlock
))
{
return
null
;
return
checkForTernaryInCondition
(
currentIf
)
;
}
if
(
isPathExists
(
nextIf
.
getThenBlock
(),
otherBranchBlock
)
&&
isPathExists
(
nextIf
.
getElseBlock
(),
otherBranchBlock
))
{
...
...
@@ -152,9 +158,43 @@ public class IfMakerHelper {
IfInfo
result
=
mergeIfInfo
(
currentIf
,
nextIf
,
followThenBranch
);
// search next nested if block
IfInfo
next
=
mergeNestedIfNodes
(
result
);
if
(
next
!=
null
)
{
return
next
;
return
searchNestedIf
(
result
);
}
private
static
IfInfo
checkForTernaryInCondition
(
IfInfo
currentIf
)
{
IfInfo
nextThen
=
getNextIf
(
currentIf
,
currentIf
.
getThenBlock
());
IfInfo
nextElse
=
getNextIf
(
currentIf
,
currentIf
.
getElseBlock
());
if
(
nextThen
==
null
||
nextElse
==
null
)
{
return
null
;
}
if
(!
nextThen
.
getIfBlock
().
getDomFrontier
().
equals
(
nextElse
.
getIfBlock
().
getDomFrontier
()))
{
return
null
;
}
nextThen
=
searchNestedIf
(
nextThen
);
nextElse
=
searchNestedIf
(
nextElse
);
if
(
nextThen
.
getThenBlock
()
==
nextElse
.
getThenBlock
()
&&
nextThen
.
getElseBlock
()
==
nextElse
.
getElseBlock
())
{
return
mergeTernaryConditions
(
currentIf
,
nextThen
,
nextElse
);
}
if
(
nextThen
.
getThenBlock
()
==
nextElse
.
getElseBlock
()
&&
nextThen
.
getElseBlock
()
==
nextElse
.
getThenBlock
())
{
nextElse
=
IfInfo
.
invert
(
nextElse
);
return
mergeTernaryConditions
(
currentIf
,
nextThen
,
nextElse
);
}
return
null
;
}
private
static
IfInfo
mergeTernaryConditions
(
IfInfo
currentIf
,
IfInfo
nextThen
,
IfInfo
nextElse
)
{
IfCondition
newCondition
=
IfCondition
.
ternary
(
currentIf
.
getCondition
(),
nextThen
.
getCondition
(),
nextElse
.
getCondition
());
IfInfo
result
=
new
IfInfo
(
newCondition
,
nextThen
.
getThenBlock
(),
nextThen
.
getElseBlock
());
result
.
setIfBlock
(
currentIf
.
getIfBlock
());
result
.
getMergedBlocks
().
addAll
(
currentIf
.
getMergedBlocks
());
result
.
getMergedBlocks
().
addAll
(
nextThen
.
getMergedBlocks
());
result
.
getMergedBlocks
().
addAll
(
nextElse
.
getMergedBlocks
());
for
(
BlockNode
blockNode
:
result
.
getMergedBlocks
())
{
blockNode
.
add
(
AFlag
.
SKIP
);
}
return
result
;
}
...
...
jadx-core/src/test/java/jadx/tests/internal/conditions/TestConditions14.java
View file @
e2018535
...
...
@@ -20,15 +20,6 @@ public class TestConditions14 extends InternalJadxTest {
System
.
out
.
println
(
"1"
);
return
true
;
}
// public static boolean test2(Object a, Object b) {
// if (a == null ? b != null : !a.equals(b)) {
// return false;
// }
// System.out.println("2");
// return true;
// }
}
@Test
...
...
jadx-core/src/test/java/jadx/tests/internal/conditions/TestTernaryInIf.java
0 → 100644
View file @
e2018535
package
jadx
.
tests
.
internal
.
conditions
;
import
jadx.api.InternalJadxTest
;
import
jadx.core.dex.nodes.ClassNode
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestTernaryInIf
extends
InternalJadxTest
{
public
static
class
TestCls
{
public
boolean
test1
(
boolean
a
,
boolean
b
,
boolean
c
)
{
return
a
?
b
:
c
;
}
public
int
test2
(
boolean
a
,
boolean
b
,
boolean
c
)
{
return
(
a
?
b
:
c
)
?
1
:
2
;
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsOne
(
"return a ? b : c;"
));
assertThat
(
code
,
containsOne
(
"return (a ? b : c) ? 1 : 2;"
));
assertThat
(
code
,
not
(
containsString
(
"if"
)));
assertThat
(
code
,
not
(
containsString
(
"else"
)));
}
}
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