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
f31c2dcd
Commit
f31c2dcd
authored
Oct 24, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix processing 'if' at loop end
parent
7699cfac
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
116 additions
and
10 deletions
+116
-10
AttributeStorage.java
.../main/java/jadx/core/dex/attributes/AttributeStorage.java
+1
-1
CodeShrinker.java
...re/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
+2
-4
IfMakerHelper.java
...in/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
+23
-2
LoopRegionVisitor.java
...ava/jadx/core/dex/visitors/regions/LoopRegionVisitor.java
+29
-3
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+19
-0
TestIfInLoop2.java
...test/java/jadx/tests/integration/loops/TestIfInLoop2.java
+42
-0
No files found.
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java
View file @
f31c2dcd
...
...
@@ -72,7 +72,7 @@ public class AttributeStorage {
if
(
attrList
==
null
)
{
return
Collections
.
emptyList
();
}
return
attrList
.
getList
(
);
return
Collections
.
unmodifiableList
(
attrList
.
getList
()
);
}
public
void
remove
(
AFlag
flag
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
View file @
f31c2dcd
...
...
@@ -2,6 +2,7 @@ package jadx.core.dex.visitors;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.PhiInsn
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
...
...
@@ -194,15 +195,12 @@ public class CodeShrinker extends AbstractVisitor {
// continue;
// }
SSAVar
sVar
=
arg
.
getSVar
();
if
(
sVar
.
getAssign
()
==
null
)
{
continue
;
}
// allow inline only one use arg or 'this'
if
(
sVar
.
getVariableUseCount
()
!=
1
&&
!
arg
.
isThis
())
{
continue
;
}
InsnNode
assignInsn
=
sVar
.
getAssign
().
getParentInsn
();
if
(
assignInsn
==
null
)
{
if
(
assignInsn
==
null
||
assignInsn
instanceof
PhiInsn
)
{
continue
;
}
int
assignPos
=
insnList
.
getIndex
(
assignInsn
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
View file @
f31c2dcd
...
...
@@ -2,6 +2,7 @@ package jadx.core.dex.visitors.regions;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.LoopInfo
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.InsnArg
;
...
...
@@ -53,8 +54,8 @@ public class IfMakerHelper {
info
.
setOutBlock
(
null
);
return
info
;
}
boolean
badThen
=
thenBlock
.
contains
(
AFlag
.
LOOP_START
)
||
!
allPathsFromIf
(
thenBlock
,
info
);
boolean
badElse
=
elseBlock
.
contains
(
AFlag
.
LOOP_START
)
||
!
allPathsFromIf
(
elseBlock
,
info
);
boolean
badThen
=
isBadBranchBlock
(
info
,
thenBlock
);
boolean
badElse
=
isBadBranchBlock
(
info
,
elseBlock
);
if
(
badThen
&&
badElse
)
{
LOG
.
debug
(
"Stop processing blocks after 'if': {}, method: {}"
,
info
.
getIfBlock
(),
mth
);
return
null
;
...
...
@@ -92,6 +93,26 @@ public class IfMakerHelper {
return
info
;
}
private
static
boolean
isBadBranchBlock
(
IfInfo
info
,
BlockNode
block
)
{
// check if block at end of loop edge
if
(
block
.
contains
(
AFlag
.
LOOP_START
)
&&
block
.
getPredecessors
().
size
()
==
1
)
{
BlockNode
pred
=
block
.
getPredecessors
().
get
(
0
);
if
(
pred
.
contains
(
AFlag
.
LOOP_END
))
{
List
<
LoopInfo
>
startLoops
=
block
.
getAll
(
AType
.
LOOP
);
List
<
LoopInfo
>
endLoops
=
pred
.
getAll
(
AType
.
LOOP
);
// search for same loop
for
(
LoopInfo
startLoop
:
startLoops
)
{
for
(
LoopInfo
endLoop
:
endLoops
)
{
if
(
startLoop
==
endLoop
)
{
return
true
;
}
}
}
}
}
return
!
allPathsFromIf
(
block
,
info
);
}
private
static
boolean
allPathsFromIf
(
BlockNode
block
,
IfInfo
info
)
{
List
<
BlockNode
>
preds
=
block
.
getPredecessors
();
Set
<
BlockNode
>
ifBlocks
=
info
.
getMergedBlocks
();
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java
View file @
f31c2dcd
...
...
@@ -84,7 +84,8 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
return
false
;
}
PhiInsn
phiInsn
=
incrArg
.
getSVar
().
getUsedInPhi
();
if
(
phiInsn
.
getArgsCount
()
!=
2
if
(
phiInsn
==
null
||
phiInsn
.
getArgsCount
()
!=
2
||
!
phiInsn
.
getArg
(
1
).
equals
(
incrArg
)
||
incrArg
.
getSVar
().
getUseCount
()
!=
1
)
{
return
false
;
...
...
@@ -102,6 +103,12 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
if
(!
usedOnlyInLoop
(
mth
,
loopRegion
,
arg
))
{
return
false
;
}
// can't make loop if argument from increment instruction is assign in loop
for
(
InsnArg
iArg
:
incrInsn
.
getArguments
())
{
if
(
iArg
.
isRegister
()
&&
assignOnlyInLoop
(
mth
,
loopRegion
,
(
RegisterArg
)
iArg
))
{
return
false
;
}
}
// all checks passed
initInsn
.
add
(
AFlag
.
SKIP
);
...
...
@@ -188,7 +195,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
if
(
wrapArg
!=
null
)
{
wrapArg
.
getParentInsn
().
replaceArg
(
wrapArg
,
iterVar
);
}
else
{
LOG
.
debug
(
" Wrapped insn not found: {}, mth: {}"
,
arrGetInsn
,
mth
);
LOG
.
debug
(
"
checkArrayForEach:
Wrapped insn not found: {}, mth: {}"
,
arrGetInsn
,
mth
);
}
}
return
new
ForEachLoop
(
iterVar
,
len
.
getArg
(
0
));
...
...
@@ -237,7 +244,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
}
}
}
else
{
LOG
.
warn
(
" Wrapped insn not found: {}, mth: {}"
,
nextCall
,
mth
);
LOG
.
warn
(
"
checkIterableForEach:
Wrapped insn not found: {}, mth: {}"
,
nextCall
,
mth
);
return
false
;
}
}
else
{
...
...
@@ -295,6 +302,25 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
return
false
;
}
private
static
boolean
assignOnlyInLoop
(
MethodNode
mth
,
LoopRegion
loopRegion
,
RegisterArg
arg
)
{
InsnNode
assignInsn
=
arg
.
getAssignInsn
();
if
(
assignInsn
==
null
)
{
return
true
;
}
if
(!
argInLoop
(
mth
,
loopRegion
,
assignInsn
.
getResult
()))
{
return
false
;
}
if
(
assignInsn
instanceof
PhiInsn
)
{
PhiInsn
phiInsn
=
(
PhiInsn
)
assignInsn
;
for
(
InsnArg
phiArg
:
phiInsn
.
getArguments
())
{
if
(!
assignOnlyInLoop
(
mth
,
loopRegion
,
(
RegisterArg
)
phiArg
))
{
return
false
;
}
}
}
return
true
;
}
private
static
boolean
usedOnlyInLoop
(
MethodNode
mth
,
LoopRegion
loopRegion
,
RegisterArg
arg
)
{
List
<
RegisterArg
>
useList
=
arg
.
getSVar
().
getUseList
();
for
(
RegisterArg
useArg
:
useList
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
f31c2dcd
...
...
@@ -2,8 +2,10 @@ package jadx.core.utils;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.PhiListAttr
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.PhiInsn
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.instructions.mods.TernaryInsn
;
...
...
@@ -119,6 +121,9 @@ public class BlockUtils {
}
public
static
BlockNode
getBlockByInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
if
(
insn
instanceof
PhiInsn
)
{
return
searchBlockWithPhi
(
mth
,
(
PhiInsn
)
insn
);
}
if
(
insn
.
contains
(
AFlag
.
WRAPPED
))
{
return
getBlockByWrappedInsn
(
mth
,
insn
);
}
...
...
@@ -130,6 +135,20 @@ public class BlockUtils {
return
null
;
}
private
static
BlockNode
searchBlockWithPhi
(
MethodNode
mth
,
PhiInsn
insn
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
PhiListAttr
phiListAttr
=
block
.
get
(
AType
.
PHI_LIST
);
if
(
phiListAttr
!=
null
)
{
for
(
PhiInsn
phiInsn
:
phiListAttr
.
getList
())
{
if
(
phiInsn
==
insn
)
{
return
block
;
}
}
}
}
return
null
;
}
private
static
BlockNode
getBlockByWrappedInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
for
(
BlockNode
bn
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
bi
:
bn
.
getInstructions
())
{
...
...
jadx-core/src/test/java/jadx/tests/integration/loops/TestIfInLoop2.java
0 → 100644
View file @
f31c2dcd
package
jadx
.
tests
.
integration
.
loops
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestIfInLoop2
extends
IntegrationTest
{
public
static
class
TestCls
{
public
static
void
test
(
String
str
)
{
int
len
=
str
.
length
();
int
at
=
0
;
while
(
at
<
len
)
{
char
c
=
str
.
charAt
(
at
);
int
endAt
=
at
+
1
;
if
(
c
==
'A'
)
{
while
(
endAt
<
len
)
{
c
=
str
.
charAt
(
endAt
);
if
(
c
==
'B'
)
{
break
;
}
endAt
++;
}
}
at
=
endAt
;
}
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
not
(
containsString
(
"for (int at = 0; at < len; at = endAt) {"
)));
}
}
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