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
5cee498e
Commit
5cee498e
authored
Feb 17, 2019
by
Skylot
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into type-inference-wip
parents
b689efcc
db1b027d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1080 additions
and
64 deletions
+1080
-64
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+4
-0
ClassModifier.java
...e/src/main/java/jadx/core/dex/visitors/ClassModifier.java
+13
-3
FixAccessModifiers.java
.../main/java/jadx/core/dex/visitors/FixAccessModifiers.java
+14
-8
BlockProcessor.java
...va/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java
+23
-7
IfMakerHelper.java
...in/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
+12
-1
LiveVarAnalysis.java
...main/java/jadx/core/dex/visitors/ssa/LiveVarAnalysis.java
+11
-12
RenameState.java
...src/main/java/jadx/core/dex/visitors/ssa/RenameState.java
+59
-0
SSATransform.java
...rc/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
+23
-33
TestComplexIf.java
...java/jadx/tests/integration/conditions/TestComplexIf.java
+39
-0
TestInner2Samples.java
.../java/jadx/tests/integration/inner/TestInner2Samples.java
+77
-0
TestSyntheticMthRename.java
.../jadx/tests/integration/inner/TestSyntheticMthRename.java
+44
-0
TestComplexIf.smali
jadx-core/src/test/smali/conditions/TestComplexIf.smali
+636
-0
TestCls$A.smali
...c/test/smali/inner/TestSyntheticMthRename/TestCls$A.smali
+66
-0
TestCls$I.smali
...c/test/smali/inner/TestSyntheticMthRename/TestCls$I.smali
+35
-0
TestCls.smali
...src/test/smali/inner/TestSyntheticMthRename/TestCls.smali
+24
-0
No files found.
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
5cee498e
...
...
@@ -7,6 +7,7 @@ import com.android.dx.rop.code.AccessFlags;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.Consts
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.annotations.MethodParameters
;
...
...
@@ -85,6 +86,9 @@ public class MethodGen {
}
code
.
startLineWithNum
(
mth
.
getSourceLine
());
code
.
add
(
ai
.
makeString
());
if
(
Consts
.
DEBUG
)
{
code
.
add
(
mth
.
isVirtual
()
?
"/* virtual */ "
:
"/* direct */ "
);
}
if
(
classGen
.
addGenericMap
(
code
,
mth
.
getGenericMap
()))
{
code
.
add
(
' '
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java
View file @
5cee498e
...
...
@@ -3,6 +3,8 @@ package jadx.core.dex.visitors;
import
java.util.List
;
import
java.util.Objects
;
import
com.android.dx.rop.code.AccessFlags
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.FieldReplaceAttr
;
...
...
@@ -31,7 +33,10 @@ import jadx.core.utils.exceptions.JadxException;
@JadxVisitor
(
name
=
"ClassModifier"
,
desc
=
"Remove synthetic classes, methods and fields"
,
runAfter
=
ModVisitor
.
class
runAfter
=
{
ModVisitor
.
class
,
FixAccessModifiers
.
class
}
)
public
class
ClassModifier
extends
AbstractVisitor
{
...
...
@@ -218,6 +223,10 @@ public class ClassModifier extends AbstractVisitor {
MethodInfo
callMth
=
((
InvokeNode
)
insn
).
getCallMth
();
MethodNode
wrappedMth
=
mth
.
root
().
deepResolveMethod
(
callMth
);
if
(
wrappedMth
!=
null
)
{
AccessInfo
wrappedAccFlags
=
wrappedMth
.
getAccessFlags
();
if
(
wrappedAccFlags
.
isStatic
())
{
return
false
;
}
if
(
callMth
.
getArgsCount
()
!=
mth
.
getMethodInfo
().
getArgsCount
())
{
return
false
;
}
...
...
@@ -235,8 +244,9 @@ public class ClassModifier extends AbstractVisitor {
if
(
Objects
.
equals
(
wrappedMth
.
getAlias
(),
alias
))
{
return
true
;
}
if
(!
wrappedMth
.
isVirtual
())
{
return
false
;
if
(!
wrappedAccFlags
.
isPublic
())
{
// must be public
FixAccessModifiers
.
changeVisibility
(
wrappedMth
,
AccessFlags
.
ACC_PUBLIC
);
}
wrappedMth
.
getMethodInfo
().
setAlias
(
alias
);
return
true
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/FixAccessModifiers.java
View file @
5cee498e
...
...
@@ -2,6 +2,7 @@ package jadx.core.dex.visitors;
import
com.android.dx.rop.code.AccessFlags
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
...
...
@@ -25,22 +26,27 @@ public class FixAccessModifiers extends AbstractVisitor {
if
(
respectAccessModifiers
)
{
return
;
}
AccessInfo
accessFlags
=
mth
.
getAccessFlags
();
int
newVisFlag
=
fixVisibility
(
mth
,
accessFlags
);
int
newVisFlag
=
fixVisibility
(
mth
);
if
(
newVisFlag
!=
0
)
{
AccessInfo
newAccFlags
=
accessFlags
.
changeVisibility
(
newVisFlag
);
if
(
newAccFlags
!=
accessFlags
)
{
mth
.
setAccFlags
(
newAccFlags
);
mth
.
addComment
(
"Access modifiers changed, original: "
+
accessFlags
.
rawString
());
}
changeVisibility
(
mth
,
newVisFlag
);
}
}
public
static
void
changeVisibility
(
MethodNode
mth
,
int
newVisFlag
)
{
AccessInfo
accessFlags
=
mth
.
getAccessFlags
();
AccessInfo
newAccFlags
=
accessFlags
.
changeVisibility
(
newVisFlag
);
if
(
newAccFlags
!=
accessFlags
)
{
mth
.
setAccFlags
(
newAccFlags
);
mth
.
addAttr
(
AType
.
COMMENTS
,
"access modifiers changed from: "
+
accessFlags
.
rawString
());
}
}
private
int
fixVisibility
(
MethodNode
mth
,
AccessInfo
accessFlags
)
{
private
static
int
fixVisibility
(
MethodNode
mth
)
{
if
(
mth
.
isVirtual
())
{
// make virtual methods public
return
AccessFlags
.
ACC_PUBLIC
;
}
else
{
AccessInfo
accessFlags
=
mth
.
getAccessFlags
();
if
(
accessFlags
.
isAbstract
())
{
// make abstract methods public
return
AccessFlags
.
ACC_PUBLIC
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java
View file @
5cee498e
...
...
@@ -3,6 +3,7 @@ package jadx.core.dex.visitors.blocksmaker;
import
java.util.ArrayList
;
import
java.util.BitSet
;
import
java.util.Collections
;
import
java.util.Deque
;
import
java.util.Iterator
;
import
java.util.LinkedList
;
import
java.util.List
;
...
...
@@ -26,7 +27,6 @@ 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.exceptions.JadxOverflowException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
static
jadx
.
core
.
dex
.
visitors
.
blocksmaker
.
BlockSplitter
.
connect
;
...
...
@@ -207,7 +207,12 @@ public class BlockProcessor extends AbstractVisitor {
markLoops
(
mth
);
// clear self dominance
basicBlocks
.
forEach
(
block
->
block
.
getDoms
().
clear
(
block
.
getId
()));
basicBlocks
.
forEach
(
block
->
{
block
.
getDoms
().
clear
(
block
.
getId
());
if
(
block
.
getDoms
().
isEmpty
())
{
block
.
setDoms
(
EMPTY
);
}
});
calcImmediateDominators
(
basicBlocks
,
entryBlock
);
}
...
...
@@ -271,11 +276,20 @@ public class BlockProcessor extends AbstractVisitor {
for
(
BlockNode
exit
:
mth
.
getExitBlocks
())
{
exit
.
setDomFrontier
(
EMPTY
);
}
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
List
<
BlockNode
>
domSortedBlocks
=
new
ArrayList
<>(
mth
.
getBasicBlocks
().
size
());
Deque
<
BlockNode
>
stack
=
new
LinkedList
<>();
stack
.
push
(
mth
.
getEnterBlock
());
while
(!
stack
.
isEmpty
())
{
BlockNode
node
=
stack
.
pop
();
for
(
BlockNode
dominated
:
node
.
getDominatesOn
())
{
stack
.
push
(
dominated
);
}
domSortedBlocks
.
add
(
node
);
}
Collections
.
reverse
(
domSortedBlocks
);
for
(
BlockNode
block
:
domSortedBlocks
)
{
try
{
computeBlockDF
(
mth
,
block
);
}
catch
(
StackOverflowError
e
)
{
throw
new
JadxOverflowException
(
"Failed compute block dominance frontier"
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Failed compute block dominance frontier"
,
e
);
}
...
...
@@ -286,7 +300,6 @@ public class BlockProcessor extends AbstractVisitor {
if
(
block
.
getDomFrontier
()
!=
null
)
{
return
;
}
block
.
getDominatesOn
().
forEach
(
domBlock
->
computeBlockDF
(
mth
,
domBlock
));
List
<
BlockNode
>
blocks
=
mth
.
getBasicBlocks
();
BitSet
domFrontier
=
null
;
for
(
BlockNode
s
:
block
.
getSuccessors
())
{
...
...
@@ -299,6 +312,9 @@ public class BlockProcessor extends AbstractVisitor {
}
for
(
BlockNode
c
:
block
.
getDominatesOn
())
{
BitSet
frontier
=
c
.
getDomFrontier
();
if
(
frontier
==
null
)
{
throw
new
JadxRuntimeException
(
"Dominance frontier not calculated for dominated block: "
+
c
+
", from: "
+
block
);
}
for
(
int
p
=
frontier
.
nextSetBit
(
0
);
p
>=
0
;
p
=
frontier
.
nextSetBit
(
p
+
1
))
{
if
(
blocks
.
get
(
p
).
getIDom
()
!=
block
)
{
if
(
domFrontier
==
null
)
{
...
...
@@ -308,7 +324,7 @@ public class BlockProcessor extends AbstractVisitor {
}
}
}
if
(
domFrontier
==
null
||
domFrontier
.
cardinality
()
==
0
)
{
if
(
domFrontier
==
null
||
domFrontier
.
isEmpty
()
)
{
domFrontier
=
EMPTY
;
}
block
.
setDomFrontier
(
domFrontier
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/IfMakerHelper.java
View file @
5cee498e
...
...
@@ -266,7 +266,18 @@ public class IfMakerHelper {
result
.
setIfBlock
(
first
.
getIfBlock
());
result
.
merge
(
first
,
second
);
BlockNode
otherPathBlock
=
followThenBranch
?
first
.
getElseBlock
()
:
first
.
getThenBlock
();
BlockNode
otherPathBlock
;
if
(
followThenBranch
)
{
otherPathBlock
=
first
.
getElseBlock
();
if
(!
otherPathBlock
.
equals
(
result
.
getElseBlock
()))
{
result
.
getSkipBlocks
().
add
(
otherPathBlock
);
}
}
else
{
otherPathBlock
=
first
.
getThenBlock
();
if
(!
otherPathBlock
.
equals
(
result
.
getThenBlock
()))
{
result
.
getSkipBlocks
().
add
(
otherPathBlock
);
}
}
skipSimplePath
(
otherPathBlock
,
result
.
getSkipBlocks
());
return
result
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/LiveVarAnalysis.java
View file @
5cee498e
...
...
@@ -80,35 +80,34 @@ public class LiveVarAnalysis {
private
void
processLiveInfo
()
{
int
bbCount
=
mth
.
getBasicBlocks
().
size
();
int
regsCount
=
mth
.
getRegsCount
();
BitSet
[]
liveIn
=
initBitSetArray
(
bbCount
,
regsCount
);
BitSet
[]
liveIn
Blocks
=
initBitSetArray
(
bbCount
,
regsCount
);
List
<
BlockNode
>
blocks
=
mth
.
getBasicBlocks
();
int
blocksSize
=
blocks
.
size
();
int
blocksCount
=
blocks
.
size
();
int
iterationsLimit
=
blocksCount
*
10
;
boolean
changed
;
int
k
=
0
;
do
{
changed
=
false
;
for
(
int
i
=
0
;
i
<
blocksSize
;
i
++)
{
BlockNode
block
=
blocks
.
get
(
i
);
for
(
BlockNode
block
:
blocks
)
{
int
blockId
=
block
.
getId
();
BitSet
prevIn
=
liveIn
[
blockId
];
BitSet
prevIn
=
liveIn
Blocks
[
blockId
];
BitSet
newIn
=
new
BitSet
(
regsCount
);
List
<
BlockNode
>
successors
=
block
.
getSuccessors
();
for
(
int
s
=
0
,
successorsSize
=
successors
.
size
();
s
<
successorsSize
;
s
++)
{
newIn
.
or
(
liveIn
[
successors
.
get
(
s
).
getId
()]);
for
(
BlockNode
successor
:
block
.
getSuccessors
())
{
newIn
.
or
(
liveInBlocks
[
successor
.
getId
()]);
}
newIn
.
andNot
(
defs
[
blockId
]);
newIn
.
or
(
uses
[
blockId
]);
if
(!
prevIn
.
equals
(
newIn
))
{
changed
=
true
;
liveIn
[
blockId
]
=
newIn
;
liveIn
Blocks
[
blockId
]
=
newIn
;
}
}
if
(
k
++
>
1000
)
{
throw
new
JadxRuntimeException
(
"Live variable analysis reach iterations limit
"
);
if
(
k
++
>
iterationsLimit
)
{
throw
new
JadxRuntimeException
(
"Live variable analysis reach iterations limit
, blocks count: "
+
blocksCount
);
}
}
while
(
changed
);
this
.
liveIn
=
liveIn
;
this
.
liveIn
=
liveIn
Blocks
;
}
private
static
BitSet
[]
initBitSetArray
(
int
length
,
int
bitsCount
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/RenameState.java
0 → 100644
View file @
5cee498e
package
jadx
.
core
.
dex
.
visitors
.
ssa
;
import
java.util.Arrays
;
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.MethodNode
;
final
class
RenameState
{
private
final
MethodNode
mth
;
private
final
BlockNode
block
;
private
final
SSAVar
[]
vars
;
private
final
int
[]
versions
;
public
static
RenameState
init
(
MethodNode
mth
)
{
int
regsCount
=
mth
.
getRegsCount
();
RenameState
state
=
new
RenameState
(
mth
,
mth
.
getEnterBlock
(),
new
SSAVar
[
regsCount
],
new
int
[
regsCount
]
);
for
(
RegisterArg
arg
:
mth
.
getArguments
(
true
))
{
state
.
startVar
(
arg
);
}
return
state
;
}
public
static
RenameState
copyFrom
(
RenameState
state
,
BlockNode
block
)
{
return
new
RenameState
(
state
.
mth
,
block
,
Arrays
.
copyOf
(
state
.
vars
,
state
.
vars
.
length
),
state
.
versions
);
}
private
RenameState
(
MethodNode
mth
,
BlockNode
block
,
SSAVar
[]
vars
,
int
[]
versions
)
{
this
.
mth
=
mth
;
this
.
block
=
block
;
this
.
vars
=
vars
;
this
.
versions
=
versions
;
}
public
BlockNode
getBlock
()
{
return
block
;
}
public
SSAVar
getVar
(
int
regNum
)
{
return
vars
[
regNum
];
}
public
void
startVar
(
RegisterArg
regArg
)
{
int
regNum
=
regArg
.
getRegNum
();
int
version
=
versions
[
regNum
]++;
vars
[
regNum
]
=
mth
.
makeNewSVar
(
regNum
,
version
,
regArg
);
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/ssa/SSATransform.java
View file @
5cee498e
package
jadx
.
core
.
dex
.
visitors
.
ssa
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.BitSet
;
import
java.util.Deque
;
import
java.util.Iterator
;
...
...
@@ -123,35 +122,31 @@ public class SSATransform extends AbstractVisitor {
}
private
static
void
renameVariables
(
MethodNode
mth
)
{
int
regsCount
=
mth
.
getRegsCount
();
SSAVar
[]
vars
=
new
SSAVar
[
regsCount
];
int
[]
versions
=
new
int
[
regsCount
];
// init method arguments
for
(
RegisterArg
arg
:
mth
.
getArguments
(
true
))
{
int
regNum
=
arg
.
getRegNum
();
vars
[
regNum
]
=
newSSAVar
(
mth
,
versions
,
arg
,
regNum
);
}
BlockNode
enterBlock
=
mth
.
getEnterBlock
();
initPhiInEnterBlock
(
vars
,
enterBlock
);
renameVar
(
mth
,
vars
,
versions
,
enterBlock
);
}
RenameState
initState
=
RenameState
.
init
(
mth
);
initPhiInEnterBlock
(
initState
);
private
static
SSAVar
newSSAVar
(
MethodNode
mth
,
int
[]
versions
,
RegisterArg
arg
,
int
regNum
)
{
int
version
=
versions
[
regNum
]++;
return
mth
.
makeNewSVar
(
regNum
,
version
,
arg
);
Deque
<
RenameState
>
stack
=
new
LinkedList
<>();
stack
.
push
(
initState
);
while
(!
stack
.
isEmpty
())
{
RenameState
state
=
stack
.
pop
();
renameVarsInBlock
(
state
);
for
(
BlockNode
dominated
:
state
.
getBlock
().
getDominatesOn
())
{
stack
.
push
(
RenameState
.
copyFrom
(
state
,
dominated
));
}
}
}
private
static
void
initPhiInEnterBlock
(
SSAVar
[]
vars
,
BlockNode
enterBlock
)
{
PhiListAttr
phiList
=
enterBlock
.
get
(
AType
.
PHI_LIST
);
private
static
void
initPhiInEnterBlock
(
RenameState
initState
)
{
PhiListAttr
phiList
=
initState
.
getBlock
()
.
get
(
AType
.
PHI_LIST
);
if
(
phiList
!=
null
)
{
for
(
PhiInsn
phiInsn
:
phiList
.
getList
())
{
bindPhiArg
(
vars
,
enterBlock
,
phiInsn
);
bindPhiArg
(
initState
,
phiInsn
);
}
}
}
private
static
void
renameVar
(
MethodNode
mth
,
SSAVar
[]
vars
,
int
[]
vers
,
BlockNode
block
)
{
SSAVar
[]
inputVars
=
Arrays
.
copyOf
(
vars
,
vars
.
length
);
private
static
void
renameVar
sInBlock
(
RenameState
state
)
{
BlockNode
block
=
state
.
getBlock
(
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
insn
.
getType
()
!=
InsnType
.
PHI
)
{
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
...
...
@@ -160,18 +155,17 @@ public class SSATransform extends AbstractVisitor {
}
RegisterArg
reg
=
(
RegisterArg
)
arg
;
int
regNum
=
reg
.
getRegNum
();
SSAVar
var
=
vars
[
regNum
]
;
SSAVar
var
=
state
.
getVar
(
regNum
)
;
if
(
var
==
null
)
{
throw
new
JadxRuntimeException
(
"Not initialized variable reg: "
+
regNum
+
", insn: "
+
insn
+
", block:"
+
block
+
", method: "
+
mth
);
+
", insn: "
+
insn
+
", block:"
+
block
);
}
var
.
use
(
reg
);
}
}
RegisterArg
result
=
insn
.
getResult
();
if
(
result
!=
null
)
{
int
regNum
=
result
.
getRegNum
();
vars
[
regNum
]
=
newSSAVar
(
mth
,
vers
,
result
,
regNum
);
state
.
startVar
(
result
);
}
}
for
(
BlockNode
s
:
block
.
getSuccessors
())
{
...
...
@@ -180,22 +174,18 @@ public class SSATransform extends AbstractVisitor {
continue
;
}
for
(
PhiInsn
phiInsn
:
phiList
.
getList
())
{
bindPhiArg
(
vars
,
block
,
phiInsn
);
bindPhiArg
(
state
,
phiInsn
);
}
}
for
(
BlockNode
domOn
:
block
.
getDominatesOn
())
{
renameVar
(
mth
,
vars
,
vers
,
domOn
);
}
System
.
arraycopy
(
inputVars
,
0
,
vars
,
0
,
vars
.
length
);
}
private
static
void
bindPhiArg
(
SSAVar
[]
vars
,
BlockNode
block
,
PhiInsn
phiInsn
)
{
private
static
void
bindPhiArg
(
RenameState
state
,
PhiInsn
phiInsn
)
{
int
regNum
=
phiInsn
.
getResult
().
getRegNum
();
SSAVar
var
=
vars
[
regNum
]
;
SSAVar
var
=
state
.
getVar
(
regNum
)
;
if
(
var
==
null
)
{
return
;
}
RegisterArg
arg
=
phiInsn
.
bindArg
(
block
);
RegisterArg
arg
=
phiInsn
.
bindArg
(
state
.
getBlock
()
);
var
.
use
(
arg
);
var
.
setUsedInPhi
(
phiInsn
);
}
...
...
jadx-core/src/test/java/jadx/tests/integration/conditions/TestComplexIf.java
0 → 100644
View file @
5cee498e
package
jadx
.
tests
.
integration
.
conditions
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestComplexIf
extends
SmaliTest
{
/*
public final class TestComplexIf {
private String a;
private int b;
private float c;
public final boolean test() {
if (this.a.equals("GT-P6200") || this.a.equals("GT-P6210") || ... ) {
return true;
}
if (this.a.equals("SM-T810") || this.a.equals("SM-T813") || ...) {
return false;
}
return this.c > 160.0f ? true : this.c <= 0.0f && ((this.b & 15) == 4 ? 1 : null) != null;
}
}
*/
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNodeFromSmaliWithPkg
(
"conditions"
,
"TestComplexIf"
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"if (this.a.equals(\"GT-P6200\") || this.a.equals(\"GT-P6210\") || this.a.equals(\"A100\") "
+
"|| this.a.equals(\"A101\") || this.a.equals(\"LIFETAB_S786X\") || this.a.equals(\"VS890 4G\")) {"
));
}
}
jadx-core/src/test/java/jadx/tests/integration/inner/TestInner2Samples.java
0 → 100644
View file @
5cee498e
package
jadx
.
tests
.
integration
.
inner
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestInner2Samples
extends
IntegrationTest
{
public
static
class
TestInner2
{
private
String
a
;
public
class
A
{
public
A
()
{
a
=
"a"
;
}
public
String
a
()
{
return
a
;
}
}
private
static
String
b
;
public
static
class
B
{
public
B
()
{
b
=
"b"
;
}
public
String
b
()
{
return
b
;
}
}
private
String
c
;
private
void
setC
(
String
c
)
{
this
.
c
=
c
;
}
public
class
C
{
public
String
c
()
{
setC
(
"c"
);
return
c
;
}
}
private
static
String
d
;
private
static
void
setD
(
String
s
)
{
d
=
s
;
}
public
static
class
D
{
public
String
d
()
{
setD
(
"d"
);
return
d
;
}
}
}
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNode
(
TestInner2
.
class
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"setD(\"d\");"
));
assertThat
(
code
,
not
(
containsString
(
"synthetic"
)));
assertThat
(
code
,
not
(
containsString
(
"access$"
)));
}
}
jadx-core/src/test/java/jadx/tests/integration/inner/TestSyntheticMthRename.java
0 → 100644
View file @
5cee498e
package
jadx
.
tests
.
integration
.
inner
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
/**
* Issue: https://github.com/skylot/jadx/issues/397
*/
public
class
TestSyntheticMthRename
extends
SmaliTest
{
// public class TestCls {
// public interface I<R, P> {
// R call(P... p);
// }
//
// public static final class A implements I<String, Runnable> {
// public /* synthetic */ /* virtual */ Object call(Object[] objArr) {
// return renamedCall((Runnable[]) objArr);
// }
//
// private /* varargs */ /* direct */ String renamedCall(Runnable... p) {
// return "str";
// }
// }
// }
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNodeFromSmaliFiles
(
"inner"
,
"TestSyntheticMthRename"
,
"TestCls"
,
"TestCls"
,
"TestCls$I"
,
"TestCls$A"
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"public String call(Runnable... p) {"
));
assertThat
(
code
,
not
(
containsString
(
"synthetic"
)));
}
}
jadx-core/src/test/smali/conditions/TestComplexIf.smali
0 → 100644
View file @
5cee498e
This diff is collapsed.
Click to expand it.
jadx-core/src/test/smali/inner/TestSyntheticMthRename/TestCls$A.smali
0 → 100644
View file @
5cee498e
.class public final Linner/TestCls$A;
.super Ljava/lang/Object;
.source "TestCls.java"
# interfaces
.implements Linner/TestCls$I;
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Linner/TestCls;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x19
name = "A"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Object;",
"Linner/TestCls$I",
"<",
"Ljava/lang/String;",
"Ljava/lang/Runnable;",
">;"
}
.end annotation
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 9
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
.method private varargs renamedCall([Ljava/lang/Runnable;)Ljava/lang/String;
.registers 3
.param p1, "p" # [Ljava/lang/Runnable;
.prologue
.line 12
const-string v0, "str"
return-object v0
.end method
# virtual methods
.method public synthetic call([Ljava/lang/Object;)Ljava/lang/Object;
.registers 3
.prologue
.line 9
check-cast p1, [Ljava/lang/Runnable;
invoke-virtual {p0, p1}, Linner/TestCls$A;->renamedCall([Ljava/lang/Runnable;)Ljava/lang/String;
move-result-object v0
return-object v0
.end method
jadx-core/src/test/smali/inner/TestSyntheticMthRename/TestCls$I.smali
0 → 100644
View file @
5cee498e
.class public interface abstract Linner/TestCls$I;
.super Ljava/lang/Object;
.source "TestCls.java"
# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
value = Linner/TestCls;
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x609
name = "I"
.end annotation
.annotation system Ldalvik/annotation/Signature;
value = {
"<R:",
"Ljava/lang/Object;",
"P:",
"Ljava/lang/Object;",
">",
"Ljava/lang/Object;"
}
.end annotation
# virtual methods
.method public varargs abstract call([Ljava/lang/Object;)Ljava/lang/Object;
.annotation system Ldalvik/annotation/Signature;
value = {
"([TP;)TR;"
}
.end annotation
.end method
jadx-core/src/test/smali/inner/TestSyntheticMthRename/TestCls.smali
0 → 100644
View file @
5cee498e
.class public Linner/TestCls;
.super Ljava/lang/Object;
.source "TestCls.java"
# annotations
.annotation system Ldalvik/annotation/MemberClasses;
value = {
Linner/TestCls$A;,
Linner/TestCls$I;
}
.end annotation
# direct methods
.method public constructor <init>()V
.registers 1
.prologue
.line 3
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
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