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
b5a9389c
Commit
b5a9389c
authored
Nov 03, 2014
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: fix variables inline in 'catch' block
parent
d905c96f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
136 additions
and
32 deletions
+136
-32
NameGen.java
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+15
-8
InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+12
-0
BlockMakerVisitor.java
...c/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
+6
-6
CodeShrinker.java
...re/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
+18
-5
ConstInlinerVisitor.java
...main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
+19
-9
ReturnVisitor.java
...in/java/jadx/core/dex/visitors/regions/ReturnVisitor.java
+3
-1
SSATransform.java
...rc/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
+0
-1
EmptyBitSet.java
jadx-core/src/main/java/jadx/core/utils/EmptyBitSet.java
+9
-2
IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+3
-0
TestInvokeInCatch.java
...java/jadx/tests/integration/invoke/TestInvokeInCatch.java
+51
-0
No files found.
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
View file @
b5a9389c
...
...
@@ -72,8 +72,10 @@ public class NameGen {
}
public
String
useArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
varNames
.
add
(
name
);
String
name
=
arg
.
getName
();
if
(
name
==
null
)
{
return
getFallbackName
(
arg
);
}
return
name
;
}
...
...
@@ -96,14 +98,10 @@ public class NameGen {
}
private
String
makeArgName
(
RegisterArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
fallback
)
{
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
name
!=
null
&&
!
name
.
equals
(
"this"
))
{
return
base
+
"_"
+
name
;
}
return
base
;
return
getFallbackName
(
arg
);
}
String
name
=
arg
.
getName
();
String
varName
;
if
(
name
!=
null
)
{
if
(
"this"
.
equals
(
name
))
{
...
...
@@ -119,6 +117,15 @@ public class NameGen {
return
varName
;
}
private
String
getFallbackName
(
RegisterArg
arg
)
{
String
name
=
arg
.
getName
();
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
name
!=
null
&&
!
name
.
equals
(
"this"
))
{
return
base
+
"_"
+
name
;
}
return
base
;
}
private
static
String
makeNameForType
(
ArgType
type
)
{
if
(
type
.
isPrimitive
())
{
return
makeNameForPrimitive
(
type
);
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
View file @
b5a9389c
...
...
@@ -152,6 +152,18 @@ public class InsnNode extends LineAttrNode {
}
}
public
boolean
isConstInsn
()
{
switch
(
getType
())
{
case
CONST:
case
CONST_STR:
case
CONST_CLASS:
return
true
;
default
:
return
false
;
}
}
public
boolean
canReorder
()
{
switch
(
getType
())
{
case
CONST:
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/BlockMakerVisitor.java
View file @
b5a9389c
...
...
@@ -16,7 +16,6 @@ import jadx.core.dex.trycatch.CatchAttr;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.trycatch.SplitterBlockAttr
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.EmptyBitSet
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
java.util.ArrayList
;
...
...
@@ -28,6 +27,8 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
static
jadx
.
core
.
utils
.
EmptyBitSet
.
EMPTY
;
public
class
BlockMakerVisitor
extends
AbstractVisitor
{
// leave these instructions alone in block node
...
...
@@ -36,9 +37,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
InsnType
.
IF
,
InsnType
.
SWITCH
,
InsnType
.
MONITOR_ENTER
,
InsnType
.
MONITOR_EXIT
);
private
static
final
BitSet
EMPTY_BITSET
=
new
EmptyBitSet
();
InsnType
.
MONITOR_EXIT
);
@Override
public
void
visit
(
MethodNode
mth
)
{
...
...
@@ -298,7 +298,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
private
static
void
computeDominanceFrontier
(
MethodNode
mth
)
{
for
(
BlockNode
exit
:
mth
.
getExitBlocks
())
{
exit
.
setDomFrontier
(
EMPTY
_BITSET
);
exit
.
setDomFrontier
(
EMPTY
);
}
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
computeBlockDF
(
mth
,
block
);
...
...
@@ -330,7 +330,7 @@ public class BlockMakerVisitor extends AbstractVisitor {
}
}
if
(
domFrontier
==
null
||
domFrontier
.
cardinality
()
==
0
)
{
domFrontier
=
EMPTY
_BITSET
;
domFrontier
=
EMPTY
;
}
block
.
setDomFrontier
(
domFrontier
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/CodeShrinker.java
View file @
b5a9389c
...
...
@@ -13,6 +13,7 @@ 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.EmptyBitSet
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -97,7 +98,8 @@ public class CodeShrinker extends AbstractVisitor {
}
private
boolean
canMove
(
int
from
,
int
to
)
{
List
<
RegisterArg
>
movedArgs
=
argsList
.
get
(
from
).
getArgs
();
ArgsInfo
startInfo
=
argsList
.
get
(
from
);
List
<
RegisterArg
>
movedArgs
=
startInfo
.
getArgs
();
int
start
=
from
+
1
;
if
(
start
==
to
)
{
// previous instruction or on edge of inline border
...
...
@@ -106,9 +108,17 @@ public class CodeShrinker extends AbstractVisitor {
if
(
start
>
to
)
{
throw
new
JadxRuntimeException
(
"Invalid inline insn positions: "
+
start
+
" - "
+
to
);
}
BitSet
movedSet
=
new
BitSet
();
for
(
RegisterArg
arg
:
movedArgs
)
{
movedSet
.
set
(
arg
.
getRegNum
());
BitSet
movedSet
;
if
(
movedArgs
.
isEmpty
())
{
if
(
startInfo
.
insn
.
isConstInsn
())
{
return
true
;
}
movedSet
=
EmptyBitSet
.
EMPTY
;
}
else
{
movedSet
=
new
BitSet
();
for
(
RegisterArg
arg
:
movedArgs
)
{
movedSet
.
set
(
arg
.
getRegNum
());
}
}
for
(
int
i
=
start
;
i
<
to
;
i
++)
{
ArgsInfo
argsInfo
=
argsList
.
get
(
i
);
...
...
@@ -188,6 +198,9 @@ public class CodeShrinker extends AbstractVisitor {
List
<
WrapInfo
>
wrapList
=
new
ArrayList
<
WrapInfo
>();
for
(
ArgsInfo
argsInfo
:
argsList
)
{
List
<
RegisterArg
>
args
=
argsInfo
.
getArgs
();
if
(
args
.
isEmpty
())
{
continue
;
}
ListIterator
<
RegisterArg
>
it
=
args
.
listIterator
(
args
.
size
());
while
(
it
.
hasPrevious
())
{
RegisterArg
arg
=
it
.
previous
();
...
...
@@ -234,7 +247,7 @@ public class CodeShrinker extends AbstractVisitor {
}
private
static
boolean
canMoveBetweenBlocks
(
InsnNode
assignInsn
,
BlockNode
assignBlock
,
BlockNode
useBlock
,
InsnNode
useInsn
)
{
BlockNode
useBlock
,
InsnNode
useInsn
)
{
if
(!
BlockUtils
.
isPathExists
(
assignBlock
,
useBlock
))
{
return
false
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
View file @
b5a9389c
...
...
@@ -4,6 +4,7 @@ import jadx.core.dex.info.FieldInfo;
import
jadx.core.dex.instructions.IndexInsnNode
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.InvokeType
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
...
...
@@ -12,7 +13,6 @@ 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
;
...
...
@@ -30,7 +30,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
toRemove
.
clear
();
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
checkInsn
(
mth
,
block
,
insn
))
{
if
(
checkInsn
(
mth
,
insn
))
{
toRemove
.
add
(
insn
);
}
}
...
...
@@ -40,7 +40,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
}
}
private
static
boolean
checkInsn
(
MethodNode
mth
,
BlockNode
block
,
InsnNode
insn
)
{
private
static
boolean
checkInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
if
(
insn
.
getType
()
!=
InsnType
.
CONST
)
{
return
false
;
}
...
...
@@ -48,15 +48,22 @@ public class ConstInlinerVisitor extends AbstractVisitor {
if
(!
arg
.
isLiteral
())
{
return
false
;
}
long
lit
=
((
LiteralArg
)
arg
).
getLiteral
();
SSAVar
sVar
=
insn
.
getResult
().
getSVar
();
if
(
mth
.
getExceptionHandlersCount
()
!=
0
)
{
if
(
lit
==
0
)
{
// don't inline null object if:
// - used as instance arg in invoke instruction
for
(
RegisterArg
useArg
:
sVar
.
getUseList
())
{
InsnNode
parentInsn
=
useArg
.
getParentInsn
();
if
(
parentInsn
!=
null
)
{
// TODO: speed up expensive operations
BlockNode
useBlock
=
BlockUtils
.
getBlockByInsn
(
mth
,
parentInsn
);
if
(
useBlock
==
null
||
!
BlockUtils
.
isCleanPathExists
(
block
,
useBlock
))
{
return
false
;
InsnType
insnType
=
parentInsn
.
getType
();
if
(
insnType
==
InsnType
.
INVOKE
)
{
InvokeNode
inv
=
(
InvokeNode
)
parentInsn
;
if
(
inv
.
getInvokeType
()
!=
InvokeType
.
STATIC
&&
inv
.
getArg
(
0
)
==
useArg
)
{
return
false
;
}
}
}
}
...
...
@@ -66,7 +73,6 @@ public class ConstInlinerVisitor extends AbstractVisitor {
if
(!
arg
.
getType
().
isTypeKnown
())
{
arg
.
merge
(
resType
);
}
long
lit
=
((
LiteralArg
)
arg
).
getLiteral
();
return
replaceConst
(
mth
,
sVar
,
lit
);
}
...
...
@@ -85,6 +91,10 @@ public class ConstInlinerVisitor extends AbstractVisitor {
if
(
use
.
size
()
==
1
||
arg
.
isTypeImmutable
())
{
// arg used only in one place
litArg
=
InsnArg
.
lit
(
literal
,
arg
.
getType
());
}
else
if
(
useInsn
.
getType
()
==
InsnType
.
MOVE
&&
!
useInsn
.
getResult
().
getType
().
isTypeKnown
())
{
// save type for 'move' instructions (hard to find type in chains of 'move')
litArg
=
InsnArg
.
lit
(
literal
,
arg
.
getType
());
}
else
{
// in most cases type not equal arg.getType()
// just set unknown type and run type fixer
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ReturnVisitor.java
View file @
b5a9389c
...
...
@@ -9,6 +9,7 @@ import jadx.core.dex.nodes.IRegion;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.TryCatchRegion
;
import
jadx.core.dex.regions.conditions.IfRegion
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
...
...
@@ -72,7 +73,8 @@ public class ReturnVisitor extends AbstractVisitor {
for
(
IRegion
region
:
regionStack
)
{
// ignore paths on other branches
if
(
region
instanceof
IfRegion
||
region
instanceof
SwitchRegion
)
{
||
region
instanceof
SwitchRegion
||
region
instanceof
TryCatchRegion
)
{
curContainer
=
region
;
continue
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
View file @
b5a9389c
...
...
@@ -45,7 +45,6 @@ public class SSATransform extends AbstractVisitor {
if
(
removeUselessPhi
(
mth
))
{
renameVariables
(
mth
);
}
}
private
static
void
placePhi
(
MethodNode
mth
,
int
regNum
,
LiveVarAnalysis
la
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/EmptyBitSet.java
View file @
b5a9389c
...
...
@@ -2,10 +2,12 @@ package jadx.core.utils;
import
java.util.BitSet
;
public
class
EmptyBitSet
extends
BitSet
{
public
final
class
EmptyBitSet
extends
BitSet
{
private
static
final
long
serialVersionUID
=
-
1194884945157778639L
;
public
static
final
BitSet
EMPTY
=
new
EmptyBitSet
();
public
EmptyBitSet
()
{
super
(
0
);
}
...
...
@@ -62,7 +64,7 @@ public class EmptyBitSet extends BitSet {
@Override
public
BitSet
get
(
int
fromIndex
,
int
toIndex
)
{
throw
new
UnsupportedOperationException
()
;
return
EMPTY
;
}
@Override
...
...
@@ -84,4 +86,9 @@ public class EmptyBitSet extends BitSet {
public
void
andNot
(
BitSet
set
)
{
throw
new
UnsupportedOperationException
();
}
@Override
public
Object
clone
()
{
return
this
;
}
}
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
View file @
b5a9389c
...
...
@@ -82,7 +82,9 @@ public abstract class IntegrationTest extends TestUtils {
}
// don't unload class
System
.
out
.
println
(
"-----------------------------------------------------------"
);
System
.
out
.
println
(
cls
.
getCode
());
System
.
out
.
println
(
"-----------------------------------------------------------"
);
checkCode
(
cls
);
compile
(
cls
);
...
...
@@ -163,6 +165,7 @@ public abstract class IntegrationTest extends TestUtils {
}
catch
(
InvocationTargetException
ie
)
{
rethrow
(
"Decompiled check failed"
,
ie
);
}
System
.
out
.
println
(
"Auto check: PASSED"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
"Auto check exception: "
+
e
.
getMessage
());
...
...
jadx-core/src/test/java/jadx/tests/integration/invoke/TestInvokeInCatch.java
0 → 100644
View file @
b5a9389c
package
jadx
.
tests
.
integration
.
invoke
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
java.io.IOException
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestInvokeInCatch
extends
IntegrationTest
{
public
static
class
TestCls
{
private
static
final
String
TAG
=
"TAG"
;
private
void
test
(
int
[]
a
,
int
b
)
{
try
{
exc
();
}
catch
(
IOException
e
)
{
if
(
b
==
1
)
{
log
(
TAG
,
"Error: {}"
,
e
.
getMessage
());
}
}
}
private
static
void
log
(
String
tag
,
String
str
,
String
...
args
)
{
}
private
void
exc
()
throws
IOException
{
throw
new
IOException
();
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"try {"
));
assertThat
(
code
,
containsOne
(
"exc();"
));
assertThat
(
code
,
not
(
containsString
(
"return;"
)));
assertThat
(
code
,
containsOne
(
"} catch (IOException e) {"
));
assertThat
(
code
,
containsOne
(
"if (b == 1) {"
));
// assertThat(code, containsOne("log(TAG, \"Error: {}\", e.getMessage());"));
assertThat
(
code
,
containsOne
(
"log(TAG, \"Error: {}\", new String[]{e.getMessage()});"
));
}
}
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