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
88ccba16
Commit
88ccba16
authored
Aug 08, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: don't inline variables defined in 'try' and used in 'catch'
parent
58998089
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
128 additions
and
21 deletions
+128
-21
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+3
-3
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+4
-0
ConstInlinerVisitor.java
...main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
+34
-15
BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+23
-0
InstructionRemover.java
...ore/src/main/java/jadx/core/utils/InstructionRemover.java
+6
-2
InternalJadxTest.java
jadx-core/src/test/java/jadx/api/InternalJadxTest.java
+12
-0
TestIfInTry.java
...src/test/java/jadx/tests/internal/others/TestIfInTry.java
+0
-1
TestInlineInCatch.java
.../java/jadx/tests/internal/trycatch/TestInlineInCatch.java
+46
-0
No files found.
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
88ccba16
...
...
@@ -57,13 +57,13 @@ public class Jadx {
passes
.
add
(
new
SSATransform
());
passes
.
add
(
new
DebugInfoVisitor
());
passes
.
add
(
new
TypeInference
());
if
(
args
.
isRawCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
,
true
));
}
passes
.
add
(
new
ConstInlinerVisitor
());
passes
.
add
(
new
FinishTypeInference
());
passes
.
add
(
new
EliminatePhiNodes
());
if
(
args
.
isRawCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
,
true
));
}
passes
.
add
(
new
ModVisitor
());
passes
.
add
(
new
EnumVisitor
());
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
88ccba16
...
...
@@ -442,6 +442,10 @@ public class MethodNode extends LineAttrNode implements ILoadable {
return
exceptionHandlers
.
isEmpty
();
}
public
int
getExceptionHandlersCount
()
{
return
exceptionHandlers
.
size
();
}
/**
* Return true if exists method with same name and arguments count
*/
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
View file @
88ccba16
...
...
@@ -8,9 +8,11 @@ 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.instructions.args.RegisterArg
;
import
jadx.core.dex.instructions.args.SSAVar
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.InstructionRemover
;
import
jadx.core.utils.exceptions.JadxException
;
...
...
@@ -24,35 +26,52 @@ public class ConstInlinerVisitor extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
List
<
InsnNode
>
toRemove
=
new
ArrayList
<
InsnNode
>();
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
InstructionRemover
remover
=
new
InstructionRemover
(
mth
,
block
);
toRemove
.
clear
(
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
checkInsn
(
mth
,
block
,
insn
))
{
remover
.
add
(
insn
);
toRemove
.
add
(
insn
);
}
}
remover
.
perform
();
if
(!
toRemove
.
isEmpty
())
{
InstructionRemover
.
removeAll
(
mth
,
block
,
toRemove
);
}
}
}
private
static
boolean
checkInsn
(
MethodNode
mth
,
BlockNode
block
,
InsnNode
insn
)
{
if
(
insn
.
getType
()
==
InsnType
.
CONST
)
{
InsnArg
arg
=
insn
.
getArg
(
0
);
if
(
arg
.
isLiteral
())
{
ArgType
resType
=
insn
.
getResult
().
getType
();
// make sure arg has correct type
if
(!
arg
.
getType
().
isTypeKnown
())
{
arg
.
merge
(
resType
);
if
(
insn
.
getType
()
!=
InsnType
.
CONST
)
{
return
false
;
}
InsnArg
arg
=
insn
.
getArg
(
0
);
if
(!
arg
.
isLiteral
())
{
return
false
;
}
SSAVar
sVar
=
insn
.
getResult
().
getSVar
();
if
(
mth
.
getExceptionHandlersCount
()
!=
0
)
{
for
(
RegisterArg
useArg
:
sVar
.
getUseList
())
{
InsnNode
parentInsn
=
useArg
.
getParentInsn
();
if
(
parentInsn
!=
null
)
{
// TODO: speed up expensive operations
BlockNode
useBlock
=
BlockUtils
.
getBlockByInsn
(
mth
,
parentInsn
);
if
(!
BlockUtils
.
isCleanPathExists
(
block
,
useBlock
))
{
return
false
;
}
}
long
lit
=
((
LiteralArg
)
arg
).
getLiteral
();
return
replaceConst
(
mth
,
insn
,
lit
);
}
}
return
false
;
ArgType
resType
=
insn
.
getResult
().
getType
();
// make sure arg has correct type
if
(!
arg
.
getType
().
isTypeKnown
())
{
arg
.
merge
(
resType
);
}
long
lit
=
((
LiteralArg
)
arg
).
getLiteral
();
return
replaceConst
(
mth
,
sVar
,
lit
);
}
private
static
boolean
replaceConst
(
MethodNode
mth
,
InsnNode
insn
,
long
literal
)
{
List
<
RegisterArg
>
use
=
new
ArrayList
<
RegisterArg
>(
insn
.
getResult
().
getSVar
()
.
getUseList
());
private
static
boolean
replaceConst
(
MethodNode
mth
,
SSAVar
sVar
,
long
literal
)
{
List
<
RegisterArg
>
use
=
new
ArrayList
<
RegisterArg
>(
sVar
.
getUseList
());
int
replaceCount
=
0
;
for
(
RegisterArg
arg
:
use
)
{
// if (arg.getSVar().isUsedInPhi()) {
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
View file @
88ccba16
...
...
@@ -216,6 +216,29 @@ public class BlockUtils {
return
traverseSuccessorsUntil
(
start
,
end
,
new
BitSet
());
}
public
static
boolean
isCleanPathExists
(
BlockNode
start
,
BlockNode
end
)
{
if
(
start
==
end
||
start
.
getCleanSuccessors
().
contains
(
end
))
{
return
true
;
}
return
traverseCleanSuccessorsUntil
(
start
,
end
,
new
BitSet
());
}
private
static
boolean
traverseCleanSuccessorsUntil
(
BlockNode
from
,
BlockNode
until
,
BitSet
visited
)
{
for
(
BlockNode
s
:
from
.
getCleanSuccessors
())
{
if
(
s
==
until
)
{
return
true
;
}
int
id
=
s
.
getId
();
if
(!
visited
.
get
(
id
)
&&
!
s
.
contains
(
AType
.
EXC_HANDLER
))
{
visited
.
set
(
id
);
if
(
traverseSuccessorsUntil
(
s
,
until
,
visited
))
{
return
true
;
}
}
}
return
false
;
}
public
static
boolean
isOnlyOnePathExists
(
BlockNode
start
,
BlockNode
end
)
{
if
(
start
==
end
)
{
return
true
;
...
...
jadx-core/src/main/java/jadx/core/utils/InstructionRemover.java
View file @
88ccba16
...
...
@@ -47,7 +47,7 @@ public class InstructionRemover {
if
(
toRemove
.
isEmpty
())
{
return
;
}
removeAll
(
insns
,
toRemove
);
removeAll
(
mth
,
insns
,
toRemove
);
toRemove
.
clear
();
}
...
...
@@ -86,7 +86,7 @@ public class InstructionRemover {
// Don't use 'insns.removeAll(toRemove)' because it will remove instructions by content
// and here can be several instructions with same content
private
void
removeAll
(
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
private
static
void
removeAll
(
MethodNode
mth
,
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
for
(
InsnNode
rem
:
toRemove
)
{
unbindInsn
(
mth
,
rem
);
int
insnsCount
=
insns
.
size
();
...
...
@@ -119,6 +119,10 @@ public class InstructionRemover {
}
}
public
static
void
removeAll
(
MethodNode
mth
,
BlockNode
block
,
List
<
InsnNode
>
insns
)
{
removeAll
(
mth
,
block
.
getInstructions
(),
insns
);
}
public
static
void
remove
(
MethodNode
mth
,
BlockNode
block
,
int
index
)
{
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
unbindInsn
(
mth
,
instructions
.
get
(
index
));
...
...
jadx-core/src/test/java/jadx/api/InternalJadxTest.java
View file @
88ccba16
...
...
@@ -29,6 +29,7 @@ import static org.junit.Assert.fail;
public
abstract
class
InternalJadxTest
extends
TestUtils
{
protected
boolean
outputCFG
=
false
;
protected
boolean
isFallback
=
false
;
protected
boolean
deleteTmpJar
=
true
;
protected
String
outDir
=
"test-out-tmp"
;
...
...
@@ -76,6 +77,11 @@ public abstract class InternalJadxTest extends TestUtils {
public
boolean
isRawCFGOutput
()
{
return
outputCFG
;
}
@Override
public
boolean
isFallbackMode
()
{
return
isFallback
;
}
},
new
File
(
outDir
));
}
...
...
@@ -138,6 +144,12 @@ public abstract class InternalJadxTest extends TestUtils {
// Use only for debug purpose
@Deprecated
protected
void
setFallback
()
{
this
.
isFallback
=
true
;
}
// Use only for debug purpose
@Deprecated
protected
void
notDeleteTmpJar
()
{
this
.
deleteTmpJar
=
false
;
}
...
...
jadx-core/src/test/java/jadx/tests/internal/others/TestIfInTry.java
View file @
88ccba16
...
...
@@ -41,7 +41,6 @@ public class TestIfInTry extends InternalJadxTest {
@Test
public
void
test
()
{
setOutputCFG
();
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
...
...
jadx-core/src/test/java/jadx/tests/internal/trycatch/TestInlineInCatch.java
0 → 100644
View file @
88ccba16
package
jadx
.
tests
.
internal
.
trycatch
;
import
jadx.api.InternalJadxTest
;
import
jadx.core.dex.nodes.ClassNode
;
import
java.io.File
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestInlineInCatch
extends
InternalJadxTest
{
public
static
class
TestCls
{
private
File
dir
;
public
int
test
()
{
File
output
=
null
;
try
{
output
=
File
.
createTempFile
(
"f"
,
"a"
,
dir
);
return
0
;
}
catch
(
Exception
e
)
{
if
(
output
!=
null
)
{
output
.
delete
();
}
return
2
;
}
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsOne
(
"File output = null;"
));
assertThat
(
code
,
containsOne
(
"output = File.createTempFile(\"f\", \"a\", "
));
assertThat
(
code
,
containsOne
(
"return 0;"
));
assertThat
(
code
,
containsOne
(
"} catch (Exception e) {"
));
assertThat
(
code
,
containsOne
(
"if (output != null) {"
));
assertThat
(
code
,
containsOne
(
"output.delete();"
));
assertThat
(
code
,
containsOne
(
"return 2;"
));
}
}
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