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
17d8516d
Commit
17d8516d
authored
Mar 03, 2019
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: made correct instructions remove in new filled array replacement (#461)
parent
b78349ae
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
229 additions
and
100 deletions
+229
-100
build.gradle
build.gradle
+0
-1
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+1
-1
PhiInsn.java
...ore/src/main/java/jadx/core/dex/instructions/PhiInsn.java
+2
-2
InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+12
-10
ClassModifier.java
...e/src/main/java/jadx/core/dex/visitors/ClassModifier.java
+2
-2
ConstInlineVisitor.java
.../main/java/jadx/core/dex/visitors/ConstInlineVisitor.java
+2
-2
ConstructorVisitor.java
.../main/java/jadx/core/dex/visitors/ConstructorVisitor.java
+14
-15
ExtractFieldInit.java
...rc/main/java/jadx/core/dex/visitors/ExtractFieldInit.java
+3
-3
ModVisitor.java
...core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
+8
-8
ReSugarCode.java
...ore/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
+11
-11
BlockExceptionHandler.java
.../core/dex/visitors/blocksmaker/BlockExceptionHandler.java
+3
-3
RegionMaker.java
...main/java/jadx/core/dex/visitors/regions/RegionMaker.java
+2
-2
RegionMakerVisitor.java
...va/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
+3
-3
ProcessVariables.java
...core/dex/visitors/regions/variables/ProcessVariables.java
+2
-3
SSATransform.java
...rc/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
+5
-5
InsnRemover.java
jadx-core/src/main/java/jadx/core/utils/InsnRemover.java
+13
-11
TestInline7.java
.../test/java/jadx/tests/integration/inline/TestInline7.java
+39
-0
TestConstructorInvoke.java
.../jadx/tests/integration/invoke/TestConstructorInvoke.java
+27
-15
TestContinueInLoop2.java
...ava/jadx/tests/integration/loops/TestContinueInLoop2.java
+3
-3
TestInline7.smali
jadx-core/src/test/smali/inline/TestInline7.smali
+77
-0
No files found.
build.gradle
View file @
17d8516d
...
...
@@ -10,7 +10,6 @@ println("jadx version: ${jadxVersion}")
allprojects
{
apply
plugin:
'java'
apply
plugin:
'groovy'
apply
plugin:
'jacoco'
version
=
jadxVersion
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
17d8516d
...
...
@@ -495,7 +495,7 @@ public class InsnGen {
case
NEW_INSTANCE:
// only fallback - make new instance in constructor invoke
fallbackOnlyInsn
(
insn
);
code
.
add
(
"new "
).
add
(
insn
.
getResult
().
getType
().
toString
());
code
.
add
(
"new "
).
add
(
insn
.
getResult
().
get
Init
Type
().
toString
());
break
;
case
PHI:
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/PhiInsn.java
View file @
17d8516d
...
...
@@ -11,7 +11,7 @@ import jadx.core.dex.instructions.args.InsnArg;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -64,7 +64,7 @@ public final class PhiInsn extends InsnNode {
if
(
super
.
removeArg
(
reg
))
{
blockBinds
.
remove
(
reg
);
reg
.
getSVar
().
removeUse
(
reg
);
Ins
tructio
nRemover
.
fixUsedInPhiFlag
(
reg
);
InsnRemover
.
fixUsedInPhiFlag
(
reg
);
return
true
;
}
return
false
;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
View file @
17d8516d
...
...
@@ -19,8 +19,8 @@ import jadx.core.dex.instructions.args.LiteralArg;
import
jadx.core.dex.instructions.args.NamedArg
;
import
jadx.core.dex.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.InstructionRemover
;
import
jadx.core.utils.Utils
;
public
class
InsnNode
extends
LineAttrNode
{
...
...
@@ -68,6 +68,15 @@ public class InsnNode extends LineAttrNode {
public
void
addArg
(
InsnArg
arg
)
{
arguments
.
add
(
arg
);
attachArg
(
arg
);
}
public
void
setArg
(
int
n
,
InsnArg
arg
)
{
arguments
.
set
(
n
,
arg
);
attachArg
(
arg
);
}
private
void
attachArg
(
InsnArg
arg
)
{
arg
.
setParentInsn
(
this
);
if
(
arg
.
isRegister
())
{
RegisterArg
reg
=
(
RegisterArg
)
arg
;
...
...
@@ -108,22 +117,15 @@ public class InsnNode extends LineAttrNode {
return
false
;
}
public
void
setArg
(
int
n
,
InsnArg
arg
)
{
arg
.
setParentInsn
(
this
);
arguments
.
set
(
n
,
arg
);
}
/**
* Replace instruction arg with another using recursive search.
* <br>
* <b>Caution:</b> this method don't change usage information for replaced argument.
*/
public
boolean
replaceArg
(
InsnArg
from
,
InsnArg
to
)
{
int
count
=
getArgsCount
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
InsnArg
arg
=
arguments
.
get
(
i
);
if
(
arg
==
from
)
{
Ins
tructio
nRemover
.
unbindArgUsage
(
null
,
arg
);
InsnRemover
.
unbindArgUsage
(
null
,
arg
);
setArg
(
i
,
to
);
return
true
;
}
...
...
@@ -139,7 +141,7 @@ public class InsnNode extends LineAttrNode {
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
if
(
arg
==
arguments
.
get
(
i
))
{
arguments
.
remove
(
i
);
Ins
tructio
nRemover
.
unbindArgUsage
(
null
,
arg
);
InsnRemover
.
unbindArgUsage
(
null
,
arg
);
return
true
;
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java
View file @
17d8516d
...
...
@@ -29,7 +29,7 @@ import jadx.core.dex.nodes.FieldNode;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.exceptions.JadxException
;
@JadxVisitor
(
...
...
@@ -131,7 +131,7 @@ public class ClassModifier extends AbstractVisitor {
return
false
;
}
mth
.
skipFirstArgument
();
Ins
tructio
nRemover
.
remove
(
mth
,
block
,
insn
);
InsnRemover
.
remove
(
mth
,
block
,
insn
);
// other arg usage -> wrap with IGET insn
if
(
arg
.
getSVar
().
getUseCount
()
!=
0
)
{
InsnNode
iget
=
new
IndexInsnNode
(
InsnType
.
IGET
,
fieldInfo
,
1
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java
View file @
17d8516d
...
...
@@ -20,7 +20,7 @@ import jadx.core.dex.nodes.InsnNode;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.visitors.ssa.SSATransform
;
import
jadx.core.dex.visitors.typeinference.TypeInferenceVisitor
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxOverflowException
;
...
...
@@ -46,7 +46,7 @@ public class ConstInlineVisitor extends AbstractVisitor {
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
checkInsn
(
mth
,
insn
,
toRemove
);
}
Ins
tructionRemover
.
removeAll
(
mth
,
block
,
toRemove
);
Ins
nRemover
.
removeAllAndUnbind
(
mth
,
block
,
toRemove
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstructorVisitor.java
View file @
17d8516d
...
...
@@ -17,7 +17,7 @@ import jadx.core.dex.nodes.MethodNode;
import
jadx.core.dex.visitors.ssa.SSATransform
;
import
jadx.core.dex.visitors.typeinference.TypeInferenceVisitor
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
@JadxVisitor
(
name
=
"ConstructorVisitor"
,
...
...
@@ -36,7 +36,7 @@ public class ConstructorVisitor extends AbstractVisitor {
}
private
static
void
replaceInvoke
(
MethodNode
mth
)
{
Ins
tructionRemover
remover
=
new
Instructio
nRemover
(
mth
);
Ins
nRemover
remover
=
new
Ins
nRemover
(
mth
);
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
int
size
=
block
.
getInstructions
().
size
();
...
...
@@ -50,7 +50,7 @@ public class ConstructorVisitor extends AbstractVisitor {
}
}
private
static
void
processInvoke
(
MethodNode
mth
,
BlockNode
block
,
int
indexInBlock
,
Ins
tructio
nRemover
remover
)
{
private
static
void
processInvoke
(
MethodNode
mth
,
BlockNode
block
,
int
indexInBlock
,
InsnRemover
remover
)
{
ClassNode
parentClass
=
mth
.
getParentClass
();
InsnNode
insn
=
block
.
getInstructions
().
get
(
indexInBlock
);
InvokeNode
inv
=
(
InvokeNode
)
insn
;
...
...
@@ -75,25 +75,24 @@ public class ConstructorVisitor extends AbstractVisitor {
remove
=
true
;
}
if
(
remove
)
{
remover
.
add
(
insn
);
remover
.
add
AndUnbind
(
insn
);
return
;
}
if
(
co
.
isNewInstance
())
{
InsnNode
newInstInsn
=
removeAssignChain
(
mth
,
instArgAssignInsn
,
remover
,
InsnType
.
NEW_INSTANCE
);
if
(
newInstInsn
!=
null
)
{
remover
.
addWithoutUnbind
(
newInstInsn
);
RegisterArg
instArg
=
newInstInsn
.
getResult
();
RegisterArg
resultArg
=
co
.
getResult
();
if
(!
resultArg
.
equals
(
instArg
))
{
// replace all usages of 'instArg' with result of this constructor instruction
for
(
RegisterArg
useArg
:
new
ArrayList
<>(
instArg
.
getSVar
().
getUseList
()))
{
RegisterArg
dup
=
resultArg
.
duplicate
();
InsnNode
parentInsn
=
useArg
.
getParentInsn
();
parentInsn
.
replaceArg
(
useArg
,
dup
);
dup
.
setParentInsn
(
parentInsn
);
resultArg
.
getSVar
().
use
(
dup
);
if
(
parentInsn
!=
null
)
{
parentInsn
.
replaceArg
(
useArg
,
resultArg
.
duplicate
()
);
}
}
}
newInstInsn
.
setResult
(
null
);
// don't unbind result arg on remove
}
}
ConstructorInsn
replace
=
processConstructor
(
mth
,
co
);
...
...
@@ -146,19 +145,19 @@ public class ConstructorVisitor extends AbstractVisitor {
/**
* Remove instructions on 'move' chain until instruction with type 'insnType'
*/
private
static
InsnNode
removeAssignChain
(
MethodNode
mth
,
InsnNode
insn
,
Ins
tructio
nRemover
remover
,
InsnType
insnType
)
{
private
static
InsnNode
removeAssignChain
(
MethodNode
mth
,
InsnNode
insn
,
InsnRemover
remover
,
InsnType
insnType
)
{
if
(
insn
==
null
)
{
return
null
;
}
if
(
insn
.
isAttrStorageEmpty
())
{
remover
.
add
(
insn
);
}
else
{
BlockUtils
.
replaceInsn
(
mth
,
insn
,
new
InsnNode
(
InsnType
.
NOP
,
0
));
}
InsnType
type
=
insn
.
getType
();
if
(
type
==
insnType
)
{
return
insn
;
}
if
(
insn
.
isAttrStorageEmpty
())
{
remover
.
addWithoutUnbind
(
insn
);
}
else
{
BlockUtils
.
replaceInsn
(
mth
,
insn
,
new
InsnNode
(
InsnType
.
NOP
,
0
));
}
if
(
type
==
InsnType
.
MOVE
)
{
RegisterArg
arg
=
(
RegisterArg
)
insn
.
getArg
(
0
);
return
removeAssignChain
(
mth
,
arg
.
getAssignInsn
(),
remover
,
insnType
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ExtractFieldInit.java
View file @
17d8516d
...
...
@@ -22,7 +22,7 @@ import jadx.core.dex.nodes.InsnNode;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.parser.FieldInitAttr
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.exceptions.JadxException
;
@JadxVisitor
(
...
...
@@ -92,7 +92,7 @@ public class ExtractFieldInit extends AbstractVisitor {
if
(
initInsns
.
size
()
==
1
)
{
InsnNode
insn
=
initInsns
.
get
(
0
);
if
(
checkInsn
(
insn
))
{
Ins
tructio
nRemover
.
remove
(
classInitMth
,
insn
);
InsnRemover
.
remove
(
classInitMth
,
insn
);
addFieldInitAttr
(
classInitMth
,
field
,
insn
);
}
}
...
...
@@ -165,7 +165,7 @@ public class ExtractFieldInit extends AbstractVisitor {
// all checks passed
for
(
InitInfo
info
:
infoList
)
{
for
(
InsnNode
putInsn
:
info
.
getPutInsns
())
{
Ins
tructio
nRemover
.
remove
(
info
.
getConstrMth
(),
putInsn
);
InsnRemover
.
remove
(
info
.
getConstrMth
(),
putInsn
);
}
}
for
(
InsnNode
insn
:
common
.
getPutInsns
())
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
View file @
17d8516d
...
...
@@ -40,7 +40,7 @@ import jadx.core.dex.trycatch.ExceptionHandler;
import
jadx.core.dex.visitors.shrink.CodeShrinkVisitor
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
static
jadx
.
core
.
utils
.
BlockUtils
.
replaceInsn
;
...
...
@@ -63,12 +63,12 @@ public class ModVisitor extends AbstractVisitor {
return
;
}
Ins
tructionRemover
remover
=
new
Instructio
nRemover
(
mth
);
Ins
nRemover
remover
=
new
Ins
nRemover
(
mth
);
replaceStep
(
mth
,
remover
);
removeStep
(
mth
,
remover
);
}
private
static
void
replaceStep
(
MethodNode
mth
,
Ins
tructio
nRemover
remover
)
{
private
static
void
replaceStep
(
MethodNode
mth
,
InsnRemover
remover
)
{
ClassNode
parentClass
=
mth
.
getParentClass
();
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
...
...
@@ -120,7 +120,7 @@ public class ModVisitor extends AbstractVisitor {
InsnNode
filledArr
=
makeFilledArrayInsn
(
mth
,
(
NewArrayNode
)
insn
,
(
FillArrayNode
)
ni
);
if
(
filledArr
!=
null
)
{
replaceInsn
(
block
,
i
,
filledArr
);
remover
.
add
(
ni
);
remover
.
add
AndUnbind
(
ni
);
}
}
}
...
...
@@ -182,7 +182,7 @@ public class ModVisitor extends AbstractVisitor {
/**
* Remove unnecessary instructions
*/
private
static
void
removeStep
(
MethodNode
mth
,
Ins
tructio
nRemover
remover
)
{
private
static
void
removeStep
(
MethodNode
mth
,
InsnRemover
remover
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
...
...
@@ -190,7 +190,7 @@ public class ModVisitor extends AbstractVisitor {
case
NOP:
case
GOTO:
case
NEW_INSTANCE:
remover
.
add
(
insn
);
remover
.
add
AndUnbind
(
insn
);
break
;
default
:
...
...
@@ -335,7 +335,7 @@ public class ModVisitor extends AbstractVisitor {
return
filledArr
;
}
private
static
void
processMoveException
(
BlockNode
block
,
InsnNode
insn
,
Ins
tructio
nRemover
remover
)
{
private
static
void
processMoveException
(
BlockNode
block
,
InsnNode
insn
,
InsnRemover
remover
)
{
ExcHandlerAttr
excHandlerAttr
=
block
.
get
(
AType
.
EXC_HANDLER
);
if
(
excHandlerAttr
==
null
)
{
return
;
...
...
@@ -352,7 +352,7 @@ public class ModVisitor extends AbstractVisitor {
SSAVar
sVar
=
insn
.
getResult
().
getSVar
();
if
(
sVar
.
getUseCount
()
==
0
)
{
excHandler
.
setArg
(
new
NamedArg
(
name
,
type
));
remover
.
add
(
insn
);
remover
.
add
AndUnbind
(
insn
);
}
else
if
(
sVar
.
isUsedInPhi
())
{
// exception var moved to external variable => replace with 'move' insn
InsnNode
moveInsn
=
new
InsnNode
(
InsnType
.
MOVE
,
1
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
View file @
17d8516d
...
...
@@ -33,7 +33,7 @@ import jadx.core.dex.nodes.MethodNode;
import
jadx.core.dex.visitors.shrink.CodeShrinkVisitor
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxException
;
...
...
@@ -57,7 +57,7 @@ public class ReSugarCode extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
Ins
tructionRemover
remover
=
new
Instructio
nRemover
(
mth
);
Ins
nRemover
remover
=
new
Ins
nRemover
(
mth
);
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
...
...
@@ -69,14 +69,14 @@ public class ReSugarCode extends AbstractVisitor {
}
}
private
static
void
process
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
Ins
tructio
nRemover
remover
)
{
private
static
void
process
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
InsnRemover
remover
)
{
InsnNode
insn
=
instructions
.
get
(
i
);
if
(
insn
.
contains
(
AFlag
.
REMOVE
))
{
return
;
}
switch
(
insn
.
getType
())
{
case
NEW_ARRAY:
processNewArray
(
mth
,
instructions
,
i
,
remover
);
processNewArray
(
mth
,
(
NewArrayNode
)
insn
,
instructions
,
remover
);
break
;
case
SWITCH:
...
...
@@ -91,9 +91,8 @@ public class ReSugarCode extends AbstractVisitor {
/**
* Replace new array and sequence of array-put to new filled-array instruction.
*/
private
static
void
processNewArray
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
InstructionRemover
remover
)
{
NewArrayNode
newArrayInsn
=
(
NewArrayNode
)
instructions
.
get
(
i
);
private
static
void
processNewArray
(
MethodNode
mth
,
NewArrayNode
newArrayInsn
,
List
<
InsnNode
>
instructions
,
InsnRemover
remover
)
{
InsnArg
arrLenArg
=
newArrayInsn
.
getArg
(
0
);
if
(!
arrLenArg
.
isLiteral
())
{
return
;
...
...
@@ -136,12 +135,13 @@ public class ReSugarCode extends AbstractVisitor {
// checks complete, apply
ArgType
arrType
=
newArrayInsn
.
getArrayType
();
InsnNode
filledArr
=
new
FilledNewArrayNode
(
arrType
.
getArrayElement
(),
len
);
filledArr
.
setResult
(
arrArg
.
duplicate
()
);
filledArr
.
setResult
(
arrArg
);
for
(
InsnNode
put
:
arrPuts
)
{
filledArr
.
addArg
(
put
.
getArg
(
2
).
duplicate
());
remover
.
addAndUnbind
(
mth
,
put
);
filledArr
.
addArg
(
put
.
getArg
(
2
));
remover
.
addWithoutUnbind
(
put
);
InsnRemover
.
unbindArgUsage
(
mth
,
put
.
getArg
(
0
));
}
remover
.
add
AndUnbind
(
mth
,
newArrayInsn
);
remover
.
add
WithoutUnbind
(
newArrayInsn
);
int
replaceIndex
=
InsnList
.
getIndex
(
instructions
,
Utils
.
last
(
arrPuts
));
instructions
.
set
(
replaceIndex
,
filledArr
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockExceptionHandler.java
View file @
17d8516d
...
...
@@ -16,7 +16,7 @@ import jadx.core.dex.trycatch.ExceptionHandler;
import
jadx.core.dex.trycatch.TryCatchBlock
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
public
class
BlockExceptionHandler
extends
AbstractVisitor
{
...
...
@@ -77,13 +77,13 @@ public class BlockExceptionHandler extends AbstractVisitor {
}
for
(
BlockNode
excBlock
:
excHandler
.
getBlocks
())
{
// remove 'monitor-exit' from exception handler blocks
Ins
tructionRemover
remover
=
new
Instructio
nRemover
(
mth
,
excBlock
);
Ins
nRemover
remover
=
new
Ins
nRemover
(
mth
,
excBlock
);
for
(
InsnNode
insn
:
excBlock
.
getInstructions
())
{
if
(
insn
.
getType
()
==
InsnType
.
MONITOR_ENTER
)
{
break
;
}
if
(
insn
.
getType
()
==
InsnType
.
MONITOR_EXIT
)
{
remover
.
add
(
insn
);
remover
.
add
AndUnbind
(
insn
);
}
}
remover
.
perform
();
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
View file @
17d8516d
...
...
@@ -41,7 +41,7 @@ import jadx.core.dex.trycatch.SplitterBlockAttr;
import
jadx.core.dex.trycatch.TryCatchBlock
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -567,7 +567,7 @@ public class RegionMaker {
}
exitInsn
.
add
(
AFlag
.
DONT_GENERATE
);
exitInsn
.
add
(
AFlag
.
REMOVE
);
Ins
tructio
nRemover
.
unbindInsn
(
mth
,
exitInsn
);
InsnRemover
.
unbindInsn
(
mth
,
exitInsn
);
}
BlockNode
body
=
getNextBlock
(
block
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
View file @
17d8516d
...
...
@@ -25,7 +25,7 @@ import jadx.core.dex.regions.SwitchRegion;
import
jadx.core.dex.regions.SynchronizedRegion
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.exceptions.JadxException
;
...
...
@@ -176,10 +176,10 @@ public class RegionMakerVisitor extends AbstractVisitor {
// replace synchronized block with inner region
startRegion
.
getSubBlocks
().
set
(
0
,
synchRegion
.
getRegion
());
// remove 'monitor-enter' instruction
Ins
tructio
nRemover
.
remove
(
mth
,
synchInsn
);
InsnRemover
.
remove
(
mth
,
synchInsn
);
// remove 'monitor-exit' instruction
for
(
InsnNode
exit
:
synchRegion
.
getExitInsns
())
{
Ins
tructio
nRemover
.
remove
(
mth
,
exit
);
InsnRemover
.
remove
(
mth
,
exit
);
}
// run region cleaner again
CleanRegions
.
process
(
mth
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/variables/ProcessVariables.java
View file @
17d8516d
...
...
@@ -28,6 +28,7 @@ import jadx.core.dex.regions.loops.LoopRegion;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.dex.visitors.regions.DepthRegionTraversal
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxException
;
public
class
ProcessVariables
extends
AbstractVisitor
{
...
...
@@ -148,9 +149,7 @@ public class ProcessVariables extends AbstractVisitor {
list
.
add
(
usage
);
}
}
if
(!
list
.
isEmpty
())
{
codeVarUsage
.
put
(
codeVar
,
list
);
}
codeVarUsage
.
put
(
codeVar
,
Utils
.
lockList
(
list
));
}
return
codeVarUsage
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
View file @
17d8516d
...
...
@@ -22,7 +22,7 @@ import jadx.core.dex.visitors.AbstractVisitor;
import
jadx.core.dex.visitors.JadxVisitor
;
import
jadx.core.dex.visitors.blocksmaker.BlockFinish
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -235,7 +235,7 @@ public class SSATransform extends AbstractVisitor {
InsnNode
parentInsn
=
arg
.
getAssignInsn
();
if
(
parentInsn
!=
null
&&
parentInsn
.
contains
(
AFlag
.
REMOVE
))
{
phi
.
removeArg
(
arg
);
Ins
tructio
nRemover
.
remove
(
mth
,
block
,
parentInsn
);
InsnRemover
.
remove
(
mth
,
block
,
parentInsn
);
removed
=
true
;
}
}
...
...
@@ -283,7 +283,7 @@ public class SSATransform extends AbstractVisitor {
phi
.
removeArg
(
useArg
);
}
}
Ins
tructio
nRemover
.
remove
(
mth
,
block
,
phi
);
InsnRemover
.
remove
(
mth
,
block
,
phi
);
return
true
;
}
boolean
allSame
=
phi
.
getArgsCount
()
==
1
||
isSameArgs
(
phi
);
...
...
@@ -326,7 +326,7 @@ public class SSATransform extends AbstractVisitor {
sVar
.
setUsedInPhi
(
null
);
}
}
Ins
tructio
nRemover
.
remove
(
mth
,
block
,
phiInsn
);
InsnRemover
.
remove
(
mth
,
block
,
phiInsn
);
}
}
if
(
list
.
isEmpty
())
{
...
...
@@ -396,7 +396,7 @@ public class SSATransform extends AbstractVisitor {
assignInsn
.
add
(
AFlag
.
DONT_INLINE
);
}
}
Ins
tructio
nRemover
.
unbindInsn
(
mth
,
phi
);
InsnRemover
.
unbindInsn
(
mth
,
phi
);
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/utils/Ins
tructio
nRemover.java
→
jadx-core/src/main/java/jadx/core/utils/InsnRemover.java
View file @
17d8516d
...
...
@@ -19,17 +19,17 @@ import jadx.core.dex.nodes.MethodNode;
* Helper class for correct instructions removing,
* can be used while iterating over instructions list
*/
public
class
Ins
tructio
nRemover
{
public
class
InsnRemover
{
private
final
MethodNode
mth
;
private
final
List
<
InsnNode
>
toRemove
;
private
List
<
InsnNode
>
instrList
;
public
Ins
tructio
nRemover
(
MethodNode
mth
)
{
public
InsnRemover
(
MethodNode
mth
)
{
this
(
mth
,
null
);
}
public
Ins
tructio
nRemover
(
MethodNode
mth
,
BlockNode
block
)
{
public
InsnRemover
(
MethodNode
mth
,
BlockNode
block
)
{
this
.
mth
=
mth
;
this
.
toRemove
=
new
ArrayList
<>();
if
(
block
!=
null
)
{
...
...
@@ -41,20 +41,20 @@ public class InstructionRemover {
this
.
instrList
=
block
.
getInstructions
();
}
public
void
add
(
InsnNode
insn
)
{
public
void
add
AndUnbind
(
InsnNode
insn
)
{
toRemove
.
add
(
insn
);
unbindInsn
(
mth
,
insn
);
}
public
void
add
AndUnbind
(
MethodNode
mth
,
InsnNode
insn
)
{
public
void
add
WithoutUnbind
(
InsnNode
insn
)
{
toRemove
.
add
(
insn
);
unbindInsn
(
mth
,
insn
);
}
public
void
perform
()
{
if
(
toRemove
.
isEmpty
())
{
return
;
}
removeAll
(
mth
,
instrList
,
toRemove
);
removeAll
(
instrList
,
toRemove
);
toRemove
.
clear
();
}
...
...
@@ -111,7 +111,7 @@ public class InstructionRemover {
// Don't use 'instrList.removeAll(toRemove)' because it will remove instructions by content
// and here can be several instructions with same content
private
static
void
removeAll
(
MethodNode
mth
,
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
private
static
void
removeAll
(
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
if
(
toRemove
==
null
||
toRemove
.
isEmpty
())
{
return
;
}
...
...
@@ -120,7 +120,6 @@ public class InstructionRemover {
for
(
int
i
=
0
;
i
<
insnsCount
;
i
++)
{
if
(
insns
.
get
(
i
)
==
rem
)
{
insns
.
remove
(
i
);
unbindInsn
(
mth
,
rem
);
break
;
}
}
...
...
@@ -147,8 +146,11 @@ public class InstructionRemover {
}
}
public
static
void
removeAll
(
MethodNode
mth
,
BlockNode
block
,
List
<
InsnNode
>
insns
)
{
removeAll
(
mth
,
block
.
getInstructions
(),
insns
);
public
static
void
removeAllAndUnbind
(
MethodNode
mth
,
BlockNode
block
,
List
<
InsnNode
>
insns
)
{
for
(
InsnNode
insn
:
insns
)
{
unbindInsn
(
mth
,
insn
);
}
removeAll
(
block
.
getInstructions
(),
insns
);
}
public
static
void
remove
(
MethodNode
mth
,
BlockNode
block
,
int
index
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/inline/TestInline7.java
0 → 100644
View file @
17d8516d
package
jadx
.
tests
.
integration
.
inline
;
import
org.junit.jupiter.api.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
public
class
TestInline7
extends
SmaliTest
{
/*
public void onViewCreated(View view, @Nullable Bundle bundle) {
super.onViewCreated(view, bundle);
view.findViewById(R.id.done_button_early_release_failure).setOnClickListener(new SafeClickListener(this));
Bundle arguments = getArguments();
if (arguments != null) {
((TextView) view.findViewById(R.id.summary_content_early_release_failure)).setText(
getString(R.string.withdraw_id_capture_failure_content,
new Object[]{arguments.getString("withdrawAmount"), arguments.getString ("withdrawHoldTime")})
);
}
}
*/
@Test
public
void
test
()
{
disableCompilation
();
ClassNode
cls
=
getClassNodeFromSmaliWithPkg
(
"inline"
,
"TestInline7"
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
not
(
containsString
(
"Bundle arguments;"
)));
assertThat
(
code
,
containsOne
(
"Bundle arguments = getArguments();"
));
assertThat
(
code
,
containsOne
(
"@Nullable Bundle bundle"
));
}
}
jadx-core/src/test/java/jadx/tests/integration/invoke/TestConstructorInvoke.java
View file @
17d8516d
...
...
@@ -2,36 +2,48 @@ package jadx.tests.integration.invoke;
import
org.junit.jupiter.api.Test
;
import
jadx.NotYetImplemented
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
MatcherAssert
.
assertThat
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
public
class
TestConstructorInvoke
extends
IntegrationTest
{
public
class
TestCls
{
void
test
(
String
root
,
String
name
)
{
ViewHolder
viewHolder
=
new
ViewHolder
(
root
,
name
);
}
private
final
class
ViewHolder
{
private
int
mElements
=
0
;
private
final
String
mRoot
;
private
String
mName
;
void
test
(
String
root
,
String
name
)
{
ViewHolder
holder
=
new
ViewHolder
(
root
,
name
);
}
private
ViewHolder
(
String
root
,
String
name
)
{
this
.
mRoot
=
root
;
this
.
mName
=
name
;
}
private
final
class
ViewHolder
{
private
ViewHolder
(
String
root
,
String
name
)
{
}
}
@Test
@NotYetImplemented
(
"Variable lost name from debug info"
)
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestConstructorInvoke
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsString
(
"new ViewHolder(root, name);"
));
assertThat
(
code
,
containsOne
(
indent
()
+
"ViewHolder holder = new ViewHolder(root, name);"
));
}
// Remove after fix above @NYI
@Test
public
void
test2
()
{
ClassNode
cls
=
getClassNode
(
TestConstructorInvoke
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
indent
()
+
"ViewHolder viewHolder = new ViewHolder(root, name);"
));
}
@Test
public
void
testNoDebug
()
{
noDebugInfo
();
ClassNode
cls
=
getClassNode
(
TestConstructorInvoke
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
indent
()
+
"ViewHolder viewHolder = new ViewHolder("
));
}
}
jadx-core/src/test/java/jadx/tests/integration/loops/TestContinueInLoop2.java
View file @
17d8516d
...
...
@@ -13,7 +13,7 @@ import jadx.core.dex.trycatch.ExcHandlerAttr;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.trycatch.TryCatchBlock
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.Ins
tructio
nRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
...
...
@@ -33,13 +33,13 @@ public class TestContinueInLoop2 extends IntegrationTest {
excHandler
.
addBlock
(
node
);
}
for
(
BlockNode
excBlock
:
excHandler
.
getBlocks
())
{
Ins
tructionRemover
remover
=
new
Instructio
nRemover
(
mth
,
excBlock
);
Ins
nRemover
remover
=
new
Ins
nRemover
(
mth
,
excBlock
);
for
(
InsnNode
insn
:
excBlock
.
getInstructions
())
{
if
(
insn
.
getType
()
==
InsnType
.
MONITOR_ENTER
)
{
break
;
}
if
(
insn
.
getType
()
==
InsnType
.
MONITOR_EXIT
)
{
remover
.
add
(
insn
);
remover
.
add
AndUnbind
(
insn
);
}
}
remover
.
perform
();
...
...
jadx-core/src/test/smali/inline/TestInline7.smali
0 → 100644
View file @
17d8516d
.class public Linline/TestInline7;
.super Ljava/lang/Object;
.method public onViewCreated(Landroid/view/View;Landroid/os/Bundle;)V
.locals 4
.param p2 # Landroid/os/Bundle;
.annotation build Landroid/support/annotation/Nullable;
.end annotation
.end param
.line 42
invoke-super {p0, p1, p2}, Lapp/navigation/fragment/NodeFragment;->onViewCreated(Landroid/view/View;Landroid/os/Bundle;)V
.line 43
sget p2, Lapp/wallet/R$id;->done_button_early_release_failure:I
invoke-virtual {p1, p2}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object p2
new-instance v0, Lapp/common/utils/SafeClickListener;
invoke-direct {v0, p0}, Lapp/common/utils/SafeClickListener;-><init>(Lapp/common/utils/ISafeClickVerifierListener;)V
invoke-virtual {p2, v0}, Landroid/view/View;->setOnClickListener(Landroid/view/View$OnClickListener;)V
.line 44
invoke-virtual {p0}, Linline/TestInline7;->getArguments()Landroid/os/Bundle;
move-result-object p2
if-eqz p2, :cond_0
.line 46
sget v0, Lapp/wallet/R$id;->summary_content_early_release_failure:I
invoke-virtual {p1, v0}, Landroid/view/View;->findViewById(I)Landroid/view/View;
move-result-object p1
check-cast p1, Landroid/widget/TextView;
sget v0, Lapp/wallet/R$string;->withdraw_id_capture_failure_content:I
const/4 v1, 0x2
new-array v1, v1, [Ljava/lang/Object;
const/4 v2, 0x0
const-string v3, "withdrawAmount"
invoke-virtual {p2, v3}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object v3
aput-object v3, v1, v2
const/4 v2, 0x1
const-string v3, "withdrawHoldTime"
invoke-virtual {p2, v3}, Landroid/os/Bundle;->getString(Ljava/lang/String;)Ljava/lang/String;
move-result-object p2
aput-object p2, v1, v2
invoke-virtual {p0, v0, v1}, Linline/TestInline7;->getString(I[Ljava/lang/Object;)Ljava/lang/String;
move-result-object p2
invoke-virtual {p1, p2}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
:cond_0
return-void
.end method
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