Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
b66293a2
J
jadx
项目概览
2301_76393173
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b66293a2
编写于
4月 18, 2022
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: handle wildcard in invoke type resolver (#1238)
上级
abcaafa8
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
249 addition
and
6 deletion
+249
-6
jadx-core/src/main/java/jadx/core/dex/instructions/args/SSAVar.java
...src/main/java/jadx/core/dex/instructions/args/SSAVar.java
+5
-0
jadx-core/src/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
...c/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
+7
-0
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeBoundCheckCastAssign.java
.../dex/visitors/typeinference/TypeBoundCheckCastAssign.java
+4
-0
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeBoundInvokeAssign.java
...ore/dex/visitors/typeinference/TypeBoundInvokeAssign.java
+16
-2
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInferenceVisitor.java
...core/dex/visitors/typeinference/TypeInferenceVisitor.java
+56
-1
jadx-core/src/main/java/jadx/core/utils/ListUtils.java
jadx-core/src/main/java/jadx/core/utils/ListUtils.java
+3
-3
jadx-core/src/test/java/jadx/tests/integration/types/TestTypeResolver20.java
...java/jadx/tests/integration/types/TestTypeResolver20.java
+75
-0
jadx-core/src/test/smali/types/TestTypeResolver20/Sequence.smali
...re/src/test/smali/types/TestTypeResolver20/Sequence.smali
+22
-0
jadx-core/src/test/smali/types/TestTypeResolver20/TestTypeResolver20.smali
...t/smali/types/TestTypeResolver20/TestTypeResolver20.smali
+61
-0
未找到文件。
jadx-core/src/main/java/jadx/core/dex/instructions/args/SSAVar.java
浏览文件 @
b66293a2
...
@@ -192,6 +192,11 @@ public class SSAVar {
...
@@ -192,6 +192,11 @@ public class SSAVar {
return
usedInPhi
;
return
usedInPhi
;
}
}
public
boolean
isAssignInPhi
()
{
InsnNode
assignInsn
=
getAssignInsn
();
return
assignInsn
!=
null
&&
assignInsn
.
getType
()
==
InsnType
.
PHI
;
}
public
boolean
isUsedInPhi
()
{
public
boolean
isUsedInPhi
()
{
return
usedInPhi
!=
null
&&
!
usedInPhi
.
isEmpty
();
return
usedInPhi
!=
null
&&
!
usedInPhi
.
isEmpty
();
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
浏览文件 @
b66293a2
...
@@ -52,6 +52,13 @@ public class MoveInlineVisitor extends AbstractVisitor {
...
@@ -52,6 +52,13 @@ public class MoveInlineVisitor extends AbstractVisitor {
if
(
resultArg
.
sameRegAndSVar
(
moveArg
))
{
if
(
resultArg
.
sameRegAndSVar
(
moveArg
))
{
return
true
;
return
true
;
}
}
if
(
moveArg
.
isRegister
())
{
RegisterArg
moveReg
=
(
RegisterArg
)
moveArg
;
if
(
moveReg
.
getSVar
().
isAssignInPhi
())
{
// don't mix already merged variables
return
false
;
}
}
SSAVar
ssaVar
=
resultArg
.
getSVar
();
SSAVar
ssaVar
=
resultArg
.
getSVar
();
if
(
ssaVar
.
isUsedInPhi
())
{
if
(
ssaVar
.
isUsedInPhi
())
{
return
deleteMove
(
mth
,
move
);
return
deleteMove
(
mth
,
move
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeBoundCheckCastAssign.java
浏览文件 @
b66293a2
...
@@ -46,6 +46,10 @@ public final class TypeBoundCheckCastAssign implements ITypeBoundDynamic {
...
@@ -46,6 +46,10 @@ public final class TypeBoundCheckCastAssign implements ITypeBoundDynamic {
return
insn
.
getResult
();
return
insn
.
getResult
();
}
}
public
IndexInsnNode
getInsn
()
{
return
insn
;
}
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
"CHECK_CAST_ASSIGN{("
+
insn
.
getIndex
()
+
") "
+
insn
.
getArg
(
0
).
getType
()
+
"}"
;
return
"CHECK_CAST_ASSIGN{("
+
insn
.
getIndex
()
+
") "
+
insn
.
getArg
(
0
).
getType
()
+
"}"
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeBoundInvokeAssign.java
浏览文件 @
b66293a2
package
jadx.core.dex.visitors.typeinference
;
package
jadx.core.dex.visitors.typeinference
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnArg
;
...
@@ -48,12 +50,24 @@ public final class TypeBoundInvokeAssign implements ITypeBoundDynamic {
...
@@ -48,12 +50,24 @@ public final class TypeBoundInvokeAssign implements ITypeBoundDynamic {
mthDeclType
=
instanceType
;
mthDeclType
=
instanceType
;
}
}
ArgType
resultGeneric
=
root
.
getTypeUtils
().
replaceClassGenerics
(
instanceType
,
mthDeclType
,
genericReturnType
);
ArgType
resultGeneric
=
root
.
getTypeUtils
().
replaceClassGenerics
(
instanceType
,
mthDeclType
,
genericReturnType
);
if
(
resultGeneric
!=
null
&&
!
resultGeneric
.
isWildcard
())
{
ArgType
result
=
processResultType
(
resultGeneric
);
return
resultGeneric
;
if
(
result
!=
null
)
{
return
result
;
}
}
return
invokeNode
.
getCallMth
().
getReturnType
();
return
invokeNode
.
getCallMth
().
getReturnType
();
}
}
@Nullable
private
ArgType
processResultType
(
@Nullable
ArgType
resultGeneric
)
{
if
(
resultGeneric
==
null
)
{
return
null
;
}
if
(!
resultGeneric
.
isWildcard
())
{
return
resultGeneric
;
}
return
resultGeneric
.
getWildcardType
();
}
private
InsnArg
getInstanceArg
()
{
private
InsnArg
getInstanceArg
()
{
return
invokeNode
.
getArg
(
0
);
return
invokeNode
.
getArg
(
0
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInferenceVisitor.java
浏览文件 @
b66293a2
...
@@ -57,6 +57,7 @@ import jadx.core.dex.visitors.ssa.SSATransform;
...
@@ -57,6 +57,7 @@ import jadx.core.dex.visitors.ssa.SSATransform;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.ListUtils
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.JadxOverflowException
;
import
jadx.core.utils.exceptions.JadxOverflowException
;
...
@@ -83,6 +84,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
...
@@ -83,6 +84,7 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
this
.
resolvers
=
Arrays
.
asList
(
this
.
resolvers
=
Arrays
.
asList
(
this
::
initTypeBounds
,
this
::
initTypeBounds
,
this
::
runTypePropagation
,
this
::
runTypePropagation
,
this
::
tryRestoreTypeVarCasts
,
this
::
tryInsertCasts
,
this
::
tryInsertCasts
,
this
::
tryDeduceTypes
,
this
::
tryDeduceTypes
,
this
::
trySplitConstInsns
,
this
::
trySplitConstInsns
,
...
@@ -520,7 +522,60 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
...
@@ -520,7 +522,60 @@ public final class TypeInferenceVisitor extends AbstractVisitor {
return
false
;
return
false
;
}
}
@SuppressWarnings
(
"ForLoopReplaceableByWhile"
)
/**
* Fix check casts to type var extend type:
* <br>
* {@code <T extends Comparable> T var = (Comparable) obj; => T var = (T) obj; }
*/
private
boolean
tryRestoreTypeVarCasts
(
MethodNode
mth
)
{
int
changed
=
0
;
List
<
SSAVar
>
mthSVars
=
mth
.
getSVars
();
for
(
SSAVar
var
:
mthSVars
)
{
changed
+=
restoreTypeVarCasts
(
var
);
}
if
(
changed
==
0
)
{
return
false
;
}
if
(
Consts
.
DEBUG_TYPE_INFERENCE
)
{
mth
.
addDebugComment
(
"Restore "
+
changed
+
" type vars casts"
);
}
initTypeBounds
(
mth
);
return
runTypePropagation
(
mth
);
}
private
int
restoreTypeVarCasts
(
SSAVar
var
)
{
TypeInfo
typeInfo
=
var
.
getTypeInfo
();
Set
<
ITypeBound
>
bounds
=
typeInfo
.
getBounds
();
if
(!
ListUtils
.
anyMatch
(
bounds
,
t
->
t
.
getType
().
isGenericType
()))
{
return
0
;
}
List
<
ITypeBound
>
casts
=
ListUtils
.
filter
(
bounds
,
TypeBoundCheckCastAssign
.
class
::
isInstance
);
if
(
casts
.
isEmpty
())
{
return
0
;
}
ArgType
bestType
=
selectBestTypeFromBounds
(
bounds
).
orElse
(
ArgType
.
UNKNOWN
);
if
(!
bestType
.
isGenericType
())
{
return
0
;
}
List
<
ArgType
>
extendTypes
=
bestType
.
getExtendTypes
();
if
(
extendTypes
.
size
()
!=
1
)
{
return
0
;
}
int
fixed
=
0
;
ArgType
extendType
=
extendTypes
.
get
(
0
);
for
(
ITypeBound
bound
:
casts
)
{
TypeBoundCheckCastAssign
cast
=
(
TypeBoundCheckCastAssign
)
bound
;
ArgType
castType
=
cast
.
getType
();
TypeCompareEnum
result
=
typeUpdate
.
getTypeCompare
().
compareTypes
(
extendType
,
castType
);
if
(
result
.
isEqual
()
||
result
==
TypeCompareEnum
.
NARROW_BY_GENERIC
)
{
cast
.
getInsn
().
updateIndex
(
bestType
);
fixed
++;
}
}
return
fixed
;
}
@SuppressWarnings
({
"ForLoopReplaceableByWhile"
,
"ForLoopReplaceableByForEach"
})
private
boolean
tryInsertCasts
(
MethodNode
mth
)
{
private
boolean
tryInsertCasts
(
MethodNode
mth
)
{
int
added
=
0
;
int
added
=
0
;
List
<
SSAVar
>
mthSVars
=
mth
.
getSVars
();
List
<
SSAVar
>
mthSVars
=
mth
.
getSVars
();
...
...
jadx-core/src/main/java/jadx/core/utils/ListUtils.java
浏览文件 @
b66293a2
...
@@ -112,7 +112,7 @@ public class ListUtils {
...
@@ -112,7 +112,7 @@ public class ListUtils {
return
list
;
return
list
;
}
}
public
static
<
T
>
List
<
T
>
filter
(
List
<
T
>
list
,
Predicate
<
T
>
filter
)
{
public
static
<
T
>
List
<
T
>
filter
(
Collection
<
T
>
list
,
Predicate
<
T
>
filter
)
{
if
(
list
==
null
||
list
.
isEmpty
())
{
if
(
list
==
null
||
list
.
isEmpty
())
{
return
Collections
.
emptyList
();
return
Collections
.
emptyList
();
}
}
...
@@ -148,7 +148,7 @@ public class ListUtils {
...
@@ -148,7 +148,7 @@ public class ListUtils {
return
found
;
return
found
;
}
}
public
static
<
T
>
boolean
allMatch
(
List
<
T
>
list
,
Predicate
<
T
>
test
)
{
public
static
<
T
>
boolean
allMatch
(
Collection
<
T
>
list
,
Predicate
<
T
>
test
)
{
if
(
list
==
null
||
list
.
isEmpty
())
{
if
(
list
==
null
||
list
.
isEmpty
())
{
return
false
;
return
false
;
}
}
...
@@ -160,7 +160,7 @@ public class ListUtils {
...
@@ -160,7 +160,7 @@ public class ListUtils {
return
true
;
return
true
;
}
}
public
static
<
T
>
boolean
anyMatch
(
List
<
T
>
list
,
Predicate
<
T
>
test
)
{
public
static
<
T
>
boolean
anyMatch
(
Collection
<
T
>
list
,
Predicate
<
T
>
test
)
{
if
(
list
==
null
||
list
.
isEmpty
())
{
if
(
list
==
null
||
list
.
isEmpty
())
{
return
false
;
return
false
;
}
}
...
...
jadx-core/src/test/java/jadx/tests/integration/types/TestTypeResolver20.java
0 → 100644
浏览文件 @
b66293a2
package
jadx.tests.integration.types
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.List
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.SmaliTest
;
import
jadx.tests.api.extensions.profiles.TestProfile
;
import
jadx.tests.api.extensions.profiles.TestWithProfiles
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
/**
* Issue 1238
*/
public
class
TestTypeResolver20
extends
SmaliTest
{
public
static
class
TestCls
{
public
interface
Sequence
<
T
>
{
Iterator
<
T
>
iterator
();
}
public
static
<
T
extends
Comparable
<?
super
T
>>
T
max
(
Sequence
<?
extends
T
>
seq
)
{
Iterator
<?
extends
T
>
it
=
seq
.
iterator
();
if
(!
it
.
hasNext
())
{
return
null
;
}
T
t
=
it
.
next
();
while
(
it
.
hasNext
())
{
T
next
=
it
.
next
();
if
(
t
.
compareTo
(
next
)
<
0
)
{
t
=
next
;
}
}
return
t
;
}
private
static
class
ArraySeq
<
T
>
implements
Sequence
<
T
>
{
private
final
List
<
T
>
list
;
@SafeVarargs
public
ArraySeq
(
T
...
arr
)
{
this
.
list
=
Arrays
.
asList
(
arr
);
}
@Override
public
Iterator
<
T
>
iterator
()
{
return
list
.
iterator
();
}
}
public
void
check
()
{
assertThat
(
max
(
new
ArraySeq
<>(
2
,
5
,
3
,
4
))).
isEqualTo
(
5
);
}
}
@TestWithProfiles
({
TestProfile
.
DX_J8
,
TestProfile
.
JAVA8
})
public
void
test
()
{
noDebugInfo
();
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
doesNotContain
(
"next = next;"
)
.
containsOne
(
"T next = it.next();"
);
}
@Test
public
void
testSmali
()
{
assertThat
(
getClassNodeFromSmaliFiles
())
.
code
()
.
containsOne
(
"T next = it.next();"
)
.
containsOne
(
"T next2 = it.next();"
);
}
}
jadx-core/src/test/smali/types/TestTypeResolver20/Sequence.smali
0 → 100644
浏览文件 @
b66293a2
.class public interface abstract Lkotlin/sequences/Sequence;
.super Ljava/lang/Object;
.source "SourceFile"
.annotation system Ldalvik/annotation/Signature;
value = {
"<T:",
"Ljava/lang/Object;",
">",
"Ljava/lang/Object;"
}
.end annotation
.method public abstract iterator()Ljava/util/Iterator;
.annotation system Ldalvik/annotation/Signature;
value = {
"()",
"Ljava/util/Iterator<",
"TT;>;"
}
.end annotation
.end method
jadx-core/src/test/smali/types/TestTypeResolver20/TestTypeResolver20.smali
0 → 100644
浏览文件 @
b66293a2
.class public Ltypes/TestTypeResolver20;
.super Ljava/lang/Object;
.source "SourceFile"
.method public static final max(Lkotlin/sequences/Sequence;)Ljava/lang/Comparable;
.registers 4
.annotation system Ldalvik/annotation/Signature;
value = {
"<T::",
"Ljava/lang/Comparable<",
"-TT;>;>(",
"Lkotlin/sequences/Sequence<",
"+TT;>;)TT;"
}
.end annotation
.line 1147
invoke-interface {p0}, Lkotlin/sequences/Sequence;->iterator()Ljava/util/Iterator;
move-result-object p0
.line 1148
invoke-interface {p0}, Ljava/util/Iterator;->hasNext()Z
move-result v0
if-nez v0, :cond_11
const/4 p0, 0x0
return-object p0
.line 1149
:cond_11
invoke-interface {p0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v0
check-cast v0, Ljava/lang/Comparable;
.line 1150
:cond_17
:goto_17
invoke-interface {p0}, Ljava/util/Iterator;->hasNext()Z
move-result v1
if-eqz v1, :cond_2b
.line 1151
invoke-interface {p0}, Ljava/util/Iterator;->next()Ljava/lang/Object;
move-result-object v1
check-cast v1, Ljava/lang/Comparable;
.line 1152
invoke-interface {v0, v1}, Ljava/lang/Comparable;->compareTo(Ljava/lang/Object;)I
move-result v2
if-gez v2, :cond_17
move-object v0, v1
goto :goto_17
:cond_2b
return-object v0
.end method
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录