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
195eeceb
Commit
195eeceb
authored
Aug 30, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: restore simple indexed loops
parent
ec8309af
Hide whitespace changes
Inline
Side-by-side
Showing
34 changed files
with
403 additions
and
62 deletions
+403
-62
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+2
-0
ConditionGen.java
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
+3
-3
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+9
-4
RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+26
-5
AFlag.java
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
+2
-0
InsnArg.java
...rc/main/java/jadx/core/dex/instructions/args/InsnArg.java
+28
-6
TernaryInsn.java
...ain/java/jadx/core/dex/instructions/mods/TernaryInsn.java
+1
-1
Compare.java
...c/main/java/jadx/core/dex/regions/conditions/Compare.java
+1
-1
IfCondition.java
...in/java/jadx/core/dex/regions/conditions/IfCondition.java
+1
-1
IfInfo.java
...rc/main/java/jadx/core/dex/regions/conditions/IfInfo.java
+1
-1
IfRegion.java
.../main/java/jadx/core/dex/regions/conditions/IfRegion.java
+3
-2
IndexLoop.java
.../src/main/java/jadx/core/dex/regions/loops/IndexLoop.java
+22
-0
LoopRegion.java
...src/main/java/jadx/core/dex/regions/loops/LoopRegion.java
+14
-1
LoopType.java
...e/src/main/java/jadx/core/dex/regions/loops/LoopType.java
+4
-0
CodeShrinker.java
...re/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
+1
-0
PrepareForCodeGen.java
...c/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
+1
-0
SimplifyVisitor.java
...src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
+1
-1
CheckRegions.java
...ain/java/jadx/core/dex/visitors/regions/CheckRegions.java
+1
-1
IfMakerHelper.java
...in/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
+3
-3
IfRegionVisitor.java
.../java/jadx/core/dex/visitors/regions/IfRegionVisitor.java
+3
-3
LoopRegionVisitor.java
...ava/jadx/core/dex/visitors/regions/LoopRegionVisitor.java
+120
-0
ProcessVariables.java
...java/jadx/core/dex/visitors/regions/ProcessVariables.java
+1
-1
RegionMaker.java
...main/java/jadx/core/dex/visitors/regions/RegionMaker.java
+3
-3
RegionMakerVisitor.java
...va/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
+1
-1
ReturnVisitor.java
...in/java/jadx/core/dex/visitors/regions/ReturnVisitor.java
+2
-2
TernaryMod.java
.../main/java/jadx/core/dex/visitors/regions/TernaryMod.java
+1
-1
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+29
-1
RegionUtils.java
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
+26
-0
TestIfCondition.java
.../src/test/java/jadx/tests/functional/TestIfCondition.java
+6
-6
TestInline2.java
...src/test/java/jadx/tests/internal/inline/TestInline2.java
+3
-5
TestBreakInLoop.java
.../test/java/jadx/tests/internal/loops/TestBreakInLoop.java
+5
-6
TestIndexForLoop.java
...test/java/jadx/tests/internal/loops/TestIndexForLoop.java
+38
-0
TestLoopDetection2.java
...st/java/jadx/tests/internal/loops/TestLoopDetection2.java
+3
-3
TestNestedLoops2.java
...test/java/jadx/tests/internal/loops/TestNestedLoops2.java
+38
-0
No files found.
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
195eeceb
...
...
@@ -18,6 +18,7 @@ import jadx.core.dex.visitors.ReSugarCode;
import
jadx.core.dex.visitors.SimplifyVisitor
;
import
jadx.core.dex.visitors.regions.CheckRegions
;
import
jadx.core.dex.visitors.regions.IfRegionVisitor
;
import
jadx.core.dex.visitors.regions.LoopRegionVisitor
;
import
jadx.core.dex.visitors.regions.ProcessVariables
;
import
jadx.core.dex.visitors.regions.RegionMakerVisitor
;
import
jadx.core.dex.visitors.regions.ReturnVisitor
;
...
...
@@ -91,6 +92,7 @@ public class Jadx {
passes
.
add
(
new
MethodInlineVisitor
());
passes
.
add
(
new
ClassModifier
());
passes
.
add
(
new
PrepareForCodeGen
());
passes
.
add
(
new
LoopRegionVisitor
());
}
passes
.
add
(
new
CodeGen
(
args
));
return
passes
;
...
...
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
View file @
195eeceb
...
...
@@ -8,9 +8,9 @@ import jadx.core.dex.instructions.args.InsnArg;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.regions.Compare
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.IfCondition.Mode
;
import
jadx.core.dex.regions.
conditions.
Compare
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
jadx.core.dex.regions.
conditions.
IfCondition.Mode
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
195eeceb
...
...
@@ -58,9 +58,10 @@ public class InsnGen {
protected
final
RootNode
root
;
protected
final
boolean
fallback
;
pr
ivate
enum
Flags
{
pr
otected
enum
Flags
{
BODY_ONLY
,
BODY_ONLY_NOWRAP
,
INLINE
}
public
InsnGen
(
MethodGen
mgen
,
boolean
fallback
)
{
...
...
@@ -186,7 +187,7 @@ public class InsnGen {
return
makeInsn
(
insn
,
code
,
null
);
}
pr
ivate
boolean
makeInsn
(
InsnNode
insn
,
CodeWriter
code
,
Flags
flag
)
throws
CodegenException
{
pr
otected
boolean
makeInsn
(
InsnNode
insn
,
CodeWriter
code
,
Flags
flag
)
throws
CodegenException
{
try
{
if
(
insn
.
getType
()
==
InsnType
.
NOP
)
{
return
false
;
...
...
@@ -196,13 +197,17 @@ public class InsnGen {
state
.
add
(
flag
);
makeInsnBody
(
code
,
insn
,
state
);
}
else
{
code
.
startLineWithNum
(
insn
.
getSourceLine
());
if
(
flag
!=
Flags
.
INLINE
)
{
code
.
startLineWithNum
(
insn
.
getSourceLine
());
}
if
(
insn
.
getResult
()
!=
null
&&
insn
.
getType
()
!=
InsnType
.
ARITH_ONEARG
)
{
assignVar
(
code
,
insn
);
code
.
add
(
" = "
);
}
makeInsnBody
(
code
,
insn
,
state
);
code
.
add
(
';'
);
if
(
flag
!=
Flags
.
INLINE
)
{
code
.
add
(
';'
);
}
}
}
catch
(
Throwable
th
)
{
throw
new
CodegenException
(
mth
,
"Error generate insn: "
+
insn
,
th
);
...
...
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
View file @
195eeceb
...
...
@@ -14,17 +14,20 @@ import jadx.core.dex.nodes.IBlock;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.LoopRegion
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.SynchronizedRegion
;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
jadx.core.dex.regions.conditions.IfRegion
;
import
jadx.core.dex.regions.loops.IndexLoop
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.regions.loops.LoopType
;
import
jadx.core.dex.trycatch.CatchAttr
;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.trycatch.TryCatchBlock
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
java.util.List
;
...
...
@@ -92,7 +95,9 @@ public class RegionGen extends InsnGen {
private
void
makeSimpleBlock
(
IBlock
block
,
CodeWriter
code
)
throws
CodegenException
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
makeInsn
(
insn
,
code
);
if
(!
insn
.
contains
(
AFlag
.
SKIP
))
{
makeInsn
(
insn
,
code
);
}
}
ForceReturnAttr
retAttr
=
block
.
get
(
AType
.
FORCE_RETURN
);
if
(
retAttr
!=
null
)
{
...
...
@@ -166,8 +171,24 @@ public class RegionGen extends InsnGen {
code
.
startLine
(
'}'
);
return
code
;
}
ConditionGen
conditionGen
=
new
ConditionGen
(
this
);
LoopType
type
=
region
.
getType
();
if
(
type
!=
null
)
{
if
(
type
instanceof
IndexLoop
)
{
IndexLoop
indexLoop
=
(
IndexLoop
)
type
;
code
.
startLine
(
"for ("
);
makeInsn
(
indexLoop
.
getInitInsn
(),
code
,
Flags
.
INLINE
);
code
.
add
(
"; "
);
conditionGen
.
add
(
code
,
condition
);
code
.
add
(
"; "
);
makeInsn
(
indexLoop
.
getIncrInsn
(),
code
,
Flags
.
INLINE
);
code
.
add
(
") {"
);
makeRegionIndent
(
code
,
region
.
getBody
());
code
.
startLine
(
'}'
);
return
code
;
}
throw
new
JadxRuntimeException
(
"Unknown loop type: "
+
type
.
getClass
());
}
if
(
region
.
isConditionAtEnd
())
{
code
.
startLine
(
"do {"
);
makeRegionIndent
(
code
,
region
.
getBody
());
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AFlag.java
View file @
195eeceb
...
...
@@ -23,5 +23,7 @@ public enum AFlag {
ELSE_IF_CHAIN
,
WRAPPED
,
INCONSISTENT_CODE
,
// warning about incorrect decompilation
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
instructions
.
args
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.utils.InsnUtils
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -76,18 +80,36 @@ public abstract class InsnArg extends Typed {
return
null
;
}
if
(
parent
==
insn
)
{
LOG
.
debug
(
"Can't wrap instruction info itself: "
+
insn
);
LOG
.
debug
(
"Can't wrap instruction info itself: {}"
,
insn
);
Thread
.
dumpStack
();
return
null
;
}
int
i
=
getArgIndex
(
parent
,
this
);
if
(
i
==
-
1
)
{
return
null
;
}
insn
.
add
(
AFlag
.
WRAPPED
);
InsnArg
arg
=
wrapArg
(
insn
);
parent
.
setArg
(
i
,
arg
);
return
arg
;
}
public
static
void
updateParentInsn
(
InsnNode
fromInsn
,
InsnNode
toInsn
)
{
List
<
RegisterArg
>
args
=
new
ArrayList
<
RegisterArg
>();
fromInsn
.
getRegisterArgs
(
args
);
for
(
RegisterArg
reg
:
args
)
{
reg
.
setParentInsn
(
toInsn
);
}
}
private
static
int
getArgIndex
(
InsnNode
parent
,
InsnArg
arg
)
{
int
count
=
parent
.
getArgsCount
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
if
(
parent
.
getArg
(
i
)
==
this
)
{
InsnArg
arg
=
wrapArg
(
insn
);
parent
.
setArg
(
i
,
arg
);
return
arg
;
if
(
parent
.
getArg
(
i
)
==
arg
)
{
return
i
;
}
}
return
null
;
return
-
1
;
}
public
static
InsnArg
wrapArg
(
InsnNode
insn
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/mods/TernaryInsn.java
View file @
195eeceb
...
...
@@ -5,7 +5,7 @@ import jadx.core.dex.instructions.args.InsnArg;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.Utils
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/Compare.java
→
jadx-core/src/main/java/jadx/core/dex/regions/
conditions/
Compare.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
;
package
jadx
.
core
.
dex
.
regions
.
conditions
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.IfOp
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java
→
jadx-core/src/main/java/jadx/core/dex/regions/
conditions/
IfCondition.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
;
package
jadx
.
core
.
dex
.
regions
.
conditions
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.IfOp
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfInfo.java
→
jadx-core/src/main/java/jadx/core/dex/regions/
conditions/
IfInfo.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
;
package
jadx
.
core
.
dex
.
regions
.
conditions
;
import
jadx.core.dex.nodes.BlockNode
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
→
jadx-core/src/main/java/jadx/core/dex/regions/
conditions/
IfRegion.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
;
package
jadx
.
core
.
dex
.
regions
.
conditions
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.regions.AbstractRegion
;
import
java.util.ArrayList
;
import
java.util.Collections
;
...
...
@@ -77,7 +78,7 @@ public final class IfRegion extends AbstractRegion {
@Override
public
List
<
IContainer
>
getSubBlocks
()
{
Array
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
all
.
add
(
header
);
if
(
thenRegion
!=
null
)
{
all
.
add
(
thenRegion
);
...
...
jadx-core/src/main/java/jadx/core/dex/regions/loops/IndexLoop.java
0 → 100644
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
.
loops
;
import
jadx.core.dex.nodes.InsnNode
;
public
class
IndexLoop
extends
LoopType
{
private
final
InsnNode
initInsn
;
private
final
InsnNode
incrInsn
;
public
IndexLoop
(
InsnNode
initInsn
,
InsnNode
incrInsn
)
{
this
.
initInsn
=
initInsn
;
this
.
incrInsn
=
incrInsn
;
}
public
InsnNode
getInitInsn
()
{
return
initInsn
;
}
public
InsnNode
getIncrInsn
()
{
return
incrInsn
;
}
}
jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
→
jadx-core/src/main/java/jadx/core/dex/regions/
loops/
LoopRegion.java
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
;
package
jadx
.
core
.
dex
.
regions
.
loops
;
import
jadx.core.dex.instructions.IfNode
;
import
jadx.core.dex.instructions.args.RegisterArg
;
...
...
@@ -6,6 +6,8 @@ import jadx.core.dex.nodes.BlockNode;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.regions.AbstractRegion
;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
java.util.ArrayList
;
import
java.util.Collections
;
...
...
@@ -21,6 +23,8 @@ public final class LoopRegion extends AbstractRegion {
private
IContainer
body
;
private
final
boolean
conditionAtEnd
;
private
LoopType
type
;
public
LoopRegion
(
IRegion
parent
,
BlockNode
header
,
boolean
reversed
)
{
super
(
parent
);
this
.
conditionBlock
=
header
;
...
...
@@ -116,6 +120,15 @@ public final class LoopRegion extends AbstractRegion {
}
}
public
LoopType
getType
()
{
return
type
;
}
public
void
setType
(
LoopType
type
)
{
this
.
type
=
type
;
}
@Override
public
List
<
IContainer
>
getSubBlocks
()
{
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
...
...
jadx-core/src/main/java/jadx/core/dex/regions/loops/LoopType.java
0 → 100644
View file @
195eeceb
package
jadx
.
core
.
dex
.
regions
.
loops
;
public
abstract
class
LoopType
{
}
jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
View file @
195eeceb
...
...
@@ -214,6 +214,7 @@ public class CodeShrinker extends AbstractVisitor {
// another block
BlockNode
assignBlock
=
BlockUtils
.
getBlockByInsn
(
mth
,
assignInsn
);
if
(
assignBlock
!=
null
&&
assignInsn
!=
arg
.
getParentInsn
()
&&
canMoveBetweenBlocks
(
assignInsn
,
assignBlock
,
block
,
argsInfo
.
getInsn
()))
{
arg
.
wrapInstruction
(
assignInsn
);
InsnList
.
remove
(
assignBlock
,
assignInsn
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
View file @
195eeceb
...
...
@@ -141,6 +141,7 @@ public class PrepareForCodeGen extends AbstractVisitor {
}
if
(
replace
)
{
ArithNode
newArith
=
new
ArithNode
(
arith
.
getOp
(),
res
,
arith
.
getArg
(
1
));
InsnArg
.
updateParentInsn
(
arith
,
newArith
);
list
.
set
(
i
,
newArith
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
View file @
195eeceb
...
...
@@ -19,7 +19,7 @@ import jadx.core.dex.instructions.mods.TernaryInsn;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
java.util.ArrayList
;
import
java.util.Collections
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java
View file @
195eeceb
...
...
@@ -6,7 +6,7 @@ import jadx.core.dex.nodes.BlockNode;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.LoopRegion
;
import
jadx.core.dex.regions.
loops.
LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.JadxException
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
View file @
195eeceb
...
...
@@ -9,9 +9,9 @@ import jadx.core.dex.instructions.args.RegisterArg;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.IfCondition.Mode
;
import
jadx.core.dex.regions.IfInfo
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
jadx.core.dex.regions.
conditions.
IfCondition.Mode
;
import
jadx.core.dex.regions.
conditions.
IfInfo
;
import
jadx.core.utils.BlockUtils
;
import
java.util.Collection
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfRegionVisitor.java
View file @
195eeceb
...
...
@@ -6,9 +6,9 @@ import jadx.core.dex.nodes.IBlock;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.IfCondition.Mode
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
jadx.core.dex.regions.
conditions.
IfCondition.Mode
;
import
jadx.core.dex.regions.
conditions.
IfRegion
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.RegionUtils
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java
0 → 100644
View file @
195eeceb
package
jadx
.
core
.
dex
.
visitors
.
regions
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.instructions.PhiInsn
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
jadx.core.dex.regions.loops.IndexLoop
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.RegionUtils
;
import
java.util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
LoopRegionVisitor
extends
AbstractVisitor
implements
IRegionVisitor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
LoopRegionVisitor
.
class
);
@Override
public
void
visit
(
MethodNode
mth
)
{
DepthRegionTraversal
.
traverseAll
(
mth
,
this
);
}
@Override
public
void
enterRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(
region
instanceof
LoopRegion
)
{
processLoopRegion
(
mth
,
(
LoopRegion
)
region
);
}
}
private
static
void
processLoopRegion
(
MethodNode
mth
,
LoopRegion
loopRegion
)
{
if
(
loopRegion
.
isConditionAtEnd
())
{
return
;
}
IfCondition
condition
=
loopRegion
.
getCondition
();
if
(
condition
==
null
)
{
return
;
}
List
<
RegisterArg
>
args
=
condition
.
getRegisterArgs
();
if
(
checkForIndexedLoop
(
mth
,
loopRegion
,
args
))
{
return
;
}
}
/**
* Check for indexed loop.
*/
private
static
boolean
checkForIndexedLoop
(
MethodNode
mth
,
LoopRegion
loopRegion
,
List
<
RegisterArg
>
condArgs
)
{
InsnNode
incrInsn
=
RegionUtils
.
getLastInsn
(
loopRegion
);
if
(
incrInsn
==
null
)
{
return
false
;
}
RegisterArg
incrArg
=
incrInsn
.
getResult
();
if
(
incrArg
==
null
||
incrArg
.
getSVar
()
==
null
||
!
incrArg
.
getSVar
().
isUsedInPhi
())
{
return
false
;
}
PhiInsn
phiInsn
=
incrArg
.
getSVar
().
getUsedInPhi
();
if
(
phiInsn
.
getArgsCount
()
!=
2
||
!
phiInsn
.
getArg
(
1
).
equals
(
incrArg
)
||
incrArg
.
getSVar
().
getUseCount
()
!=
1
)
{
return
false
;
}
RegisterArg
arg
=
phiInsn
.
getResult
();
if
(!
condArgs
.
contains
(
arg
)
||
arg
.
getSVar
().
isUsedInPhi
())
{
return
false
;
}
RegisterArg
initArg
=
phiInsn
.
getArg
(
0
);
InsnNode
initInsn
=
initArg
.
getAssignInsn
();
if
(
initInsn
==
null
||
initArg
.
getSVar
().
getUseCount
()
!=
1
)
{
return
false
;
}
if
(!
usedOnlyInLoop
(
mth
,
loopRegion
,
arg
))
{
return
false
;
}
initInsn
.
add
(
AFlag
.
SKIP
);
incrInsn
.
add
(
AFlag
.
SKIP
);
loopRegion
.
setType
(
new
IndexLoop
(
initInsn
,
incrInsn
));
return
true
;
}
private
static
boolean
usedOnlyInLoop
(
MethodNode
mth
,
LoopRegion
loopRegion
,
RegisterArg
arg
)
{
List
<
RegisterArg
>
useList
=
arg
.
getSVar
().
getUseList
();
for
(
RegisterArg
useArg
:
useList
)
{
if
(!
argInLoop
(
mth
,
loopRegion
,
useArg
))
{
return
false
;
}
}
return
true
;
}
private
static
boolean
argInLoop
(
MethodNode
mth
,
LoopRegion
loopRegion
,
RegisterArg
arg
)
{
InsnNode
parentInsn
=
arg
.
getParentInsn
();
if
(
parentInsn
==
null
)
{
return
false
;
}
BlockNode
block
=
BlockUtils
.
getBlockByInsn
(
mth
,
parentInsn
);
if
(
block
==
null
)
{
LOG
.
debug
(
"Instruction not found: {}, mth: {}"
,
parentInsn
,
mth
);
return
false
;
}
return
RegionUtils
.
isRegionContainsBlock
(
loopRegion
,
block
);
}
@Override
public
void
leaveRegion
(
MethodNode
mth
,
IRegion
region
)
{
}
@Override
public
void
processBlock
(
MethodNode
mth
,
IBlock
container
)
{
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
View file @
195eeceb
...
...
@@ -12,7 +12,7 @@ import jadx.core.dex.nodes.IContainer;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.
conditions.
IfRegion
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.RegionUtils
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
View file @
195eeceb
...
...
@@ -13,9 +13,9 @@ import jadx.core.dex.nodes.Edge;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfInfo
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.LoopRegion
;
import
jadx.core.dex.regions.
conditions.
IfInfo
;
import
jadx.core.dex.regions.
conditions.
IfRegion
;
import
jadx.core.dex.regions.
loops.
LoopRegion
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.SynchronizedRegion
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
View file @
195eeceb
...
...
@@ -4,7 +4,7 @@ import jadx.core.dex.nodes.IContainer;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.LoopRegion
;
import
jadx.core.dex.regions.
loops.
LoopRegion
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.regions.SynchronizedRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ReturnVisitor.java
View file @
195eeceb
...
...
@@ -8,8 +8,8 @@ import jadx.core.dex.nodes.IContainer;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.LoopRegion
;
import
jadx.core.dex.regions.
conditions.
IfRegion
;
import
jadx.core.dex.regions.
loops.
LoopRegion
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.exceptions.JadxException
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/TernaryMod.java
View file @
195eeceb
...
...
@@ -12,7 +12,7 @@ import jadx.core.dex.nodes.BlockNode;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.IfRegion
;
import
jadx.core.dex.regions.
conditions.
IfRegion
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.visitors.CodeShrinker
;
import
jadx.core.utils.InsnList
;
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
195eeceb
package
jadx
.
core
.
utils
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -113,7 +116,9 @@ public class BlockUtils {
}
public
static
BlockNode
getBlockByInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
assert
insn
!=
null
;
if
(
insn
.
contains
(
AFlag
.
WRAPPED
))
{
return
getBlockByWrappedInsn
(
mth
,
insn
);
}
for
(
BlockNode
bn
:
mth
.
getBasicBlocks
())
{
if
(
blockContains
(
bn
,
insn
))
{
return
bn
;
...
...
@@ -122,6 +127,29 @@ public class BlockUtils {
return
null
;
}
private
static
BlockNode
getBlockByWrappedInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
for
(
BlockNode
bn
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
bi
:
bn
.
getInstructions
())
{
if
(
bi
==
insn
||
foundWrappedInsn
(
bi
,
insn
))
{
return
bn
;
}
}
}
return
null
;
}
private
static
boolean
foundWrappedInsn
(
InsnNode
container
,
InsnNode
insn
)
{
for
(
InsnArg
arg
:
container
.
getArguments
())
{
if
(
arg
.
isInsnWrap
())
{
InsnNode
wrapInsn
=
((
InsnWrapArg
)
arg
).
getWrapInsn
();
if
(
wrapInsn
==
insn
||
foundWrappedInsn
(
wrapInsn
,
insn
))
{
return
true
;
}
}
}
return
false
;
}
public
static
BitSet
blocksToBitSet
(
MethodNode
mth
,
List
<
BlockNode
>
blocks
)
{
BitSet
bs
=
new
BitSet
(
mth
.
getBasicBlocks
().
size
());
for
(
BlockNode
block
:
blocks
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
View file @
195eeceb
...
...
@@ -6,6 +6,9 @@ import jadx.core.dex.instructions.InsnType;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.conditions.IfRegion
;
import
jadx.core.dex.trycatch.CatchAttr
;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.trycatch.TryCatchBlock
;
...
...
@@ -35,6 +38,29 @@ public class RegionUtils {
}
}
public
static
InsnNode
getLastInsn
(
IContainer
container
)
{
if
(
container
instanceof
BlockNode
)
{
BlockNode
block
=
(
BlockNode
)
container
;
List
<
InsnNode
>
insnList
=
block
.
getInstructions
();
if
(
insnList
.
isEmpty
())
{
return
null
;
}
return
insnList
.
get
(
insnList
.
size
()
-
1
);
}
else
if
(
container
instanceof
IfRegion
||
container
instanceof
SwitchRegion
)
{
return
null
;
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
List
<
IContainer
>
blocks
=
region
.
getSubBlocks
();
if
(
blocks
.
isEmpty
())
{
return
null
;
}
return
getLastInsn
(
blocks
.
get
(
blocks
.
size
()
-
1
));
}
else
{
throw
new
JadxRuntimeException
(
"Unknown container type: "
+
container
.
getClass
());
}
}
/**
* Return true if last block in region has no successors
*/
...
...
jadx-core/src/test/java/jadx/tests/functional/TestIfCondition.java
View file @
195eeceb
...
...
@@ -5,15 +5,15 @@ import jadx.core.dex.instructions.IfOp;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.regions.Compare
;
import
jadx.core.dex.regions.IfCondition
;
import
jadx.core.dex.regions.
conditions.
Compare
;
import
jadx.core.dex.regions.
conditions.
IfCondition
;
import
org.junit.Test
;
import
static
jadx
.
core
.
dex
.
regions
.
IfCondition
.
Mode
;
import
static
jadx
.
core
.
dex
.
regions
.
IfCondition
.
merge
;
import
static
jadx
.
core
.
dex
.
regions
.
IfCondition
.
not
;
import
static
jadx
.
core
.
dex
.
regions
.
IfCondition
.
simplify
;
import
static
jadx
.
core
.
dex
.
regions
.
conditions
.
IfCondition
.
Mode
;
import
static
jadx
.
core
.
dex
.
regions
.
conditions
.
IfCondition
.
merge
;
import
static
jadx
.
core
.
dex
.
regions
.
conditions
.
IfCondition
.
not
;
import
static
jadx
.
core
.
dex
.
regions
.
conditions
.
IfCondition
.
simplify
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
public
class
TestIfCondition
{
...
...
jadx-core/src/test/java/jadx/tests/internal/inline/TestInline2.java
View file @
195eeceb
...
...
@@ -5,7 +5,7 @@ import jadx.core.dex.nodes.ClassNode;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestInline2
extends
InternalJadxTest
{
...
...
@@ -30,9 +30,7 @@ public class TestInline2 extends InternalJadxTest {
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsString
(
"i < a.length"
));
assertThat
(
code
,
containsString
(
"long i2 ="
));
assertThat
(
code
,
containsString
(
"+ i2"
));
assertThat
(
code
,
containsString
(
"i2--;"
));
assertThat
(
code
,
containsOne
(
"for (int i = 0; i < a.length; i++) {"
));
assertThat
(
code
,
containsOne
(
"for (long i2 = (long) b; i2 > 0; i2--) {"
));
}
}
jadx-core/src/test/java/jadx/tests/internal/loops/TestBreakInLoop.java
View file @
195eeceb
...
...
@@ -6,6 +6,7 @@ import jadx.core.dex.nodes.ClassNode;
import
org.junit.Test
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsOne
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
countString
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestBreakInLoop
extends
InternalJadxTest
{
...
...
@@ -14,13 +15,11 @@ public class TestBreakInLoop extends InternalJadxTest {
private
int
f
;
private
void
test
(
int
[]
a
,
int
b
)
{
int
i
=
0
;
while
(
i
<
a
.
length
)
{
for
(
int
i
=
0
;
i
<
a
.
length
;
i
++)
{
a
[
i
]++;
if
(
i
<
b
)
{
break
;
}
i
++;
}
this
.
f
++;
}
...
...
@@ -32,12 +31,12 @@ public class TestBreakInLoop extends InternalJadxTest {
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsOne
(
"
this.f++;
"
));
assertThat
(
code
,
containsOne
(
"
for (int i = 0; i < a.length; i++) {
"
));
// assertThat(code, containsOne("a[i]++;"));
assertThat
(
code
,
containsOne
(
"if (i < b) {"
));
assertThat
(
code
,
containsOne
(
"break;"
));
assertThat
(
code
,
containsOne
(
"
i
++;"
));
assertThat
(
code
,
containsOne
(
"
this.f
++;"
));
//
assertThat(code, countString(0, "else"));
assertThat
(
code
,
countString
(
0
,
"else"
));
}
}
jadx-core/src/test/java/jadx/tests/internal/loops/TestIndexForLoop.java
0 → 100644
View file @
195eeceb
package
jadx
.
tests
.
internal
.
loops
;
import
jadx.api.InternalJadxTest
;
import
jadx.core.dex.nodes.ClassNode
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsLines
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestIndexForLoop
extends
InternalJadxTest
{
public
static
class
TestCls
{
private
int
test
(
int
[]
a
,
int
b
)
{
int
sum
=
0
;
for
(
int
i
=
0
;
i
<
b
;
i
++)
{
sum
+=
a
[
i
];
}
return
sum
;
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsLines
(
2
,
"int sum = 0;"
,
"for (int i = 0; i < b; i++) {"
,
indent
(
1
)
+
"sum += a[i];"
,
"}"
,
"return sum;"
));
}
}
jadx-core/src/test/java/jadx/tests/internal/loops/TestLoopDetection2.java
View file @
195eeceb
...
...
@@ -5,6 +5,7 @@ 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
;
...
...
@@ -33,9 +34,8 @@ public class TestLoopDetection2 extends InternalJadxTest {
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
contains
String
(
"while (i < b) {
"
));
assertThat
(
code
,
contains
String
(
"int c = a + b;
"
));
assertThat
(
code
,
contains
One
(
"int c = a + b;
"
));
assertThat
(
code
,
contains
One
(
"for (int i = a; i < b; i++) {
"
));
assertThat
(
code
,
not
(
containsString
(
"c_2"
)));
assertThat
(
code
,
containsString
(
"i++"
));
}
}
jadx-core/src/test/java/jadx/tests/internal/loops/TestNestedLoops2.java
0 → 100644
View file @
195eeceb
package
jadx
.
tests
.
internal
.
loops
;
import
jadx.api.InternalJadxTest
;
import
jadx.core.dex.nodes.ClassNode
;
import
java.util.List
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestNestedLoops2
extends
InternalJadxTest
{
public
static
class
TestCls
{
private
boolean
test
(
List
<
String
>
list
)
{
int
j
=
0
;
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
String
s
=
list
.
get
(
i
);
while
(
j
<
s
.
length
())
{
j
++;
}
}
return
j
>
10
;
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsOne
(
"for (int i = 0; i < list.size(); i++) {"
));
assertThat
(
code
,
containsOne
(
"while (j < ((String) list.get(i)).length()) {"
));
}
}
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