Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
colcode
jadx
提交
e22474e0
J
jadx
项目概览
colcode
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
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,体验更适合开发者的 AI 搜索 >>
提交
e22474e0
编写于
5月 09, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: inline move instructions to help process constructors (#927)
上级
45b73046
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
197 addition
and
2 deletion
+197
-2
jadx-core/src/main/java/jadx/core/Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+1
-0
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+9
-1
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+11
-0
jadx-core/src/main/java/jadx/core/dex/visitors/ConstructorVisitor.java
.../main/java/jadx/core/dex/visitors/ConstructorVisitor.java
+1
-1
jadx-core/src/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
...c/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
+103
-0
jadx-core/src/main/java/jadx/core/dex/visitors/regions/variables/ProcessVariables.java
...core/dex/visitors/regions/variables/ProcessVariables.java
+20
-0
jadx-core/src/test/java/jadx/tests/integration/invoke/TestConstructorWithMoves.java
...dx/tests/integration/invoke/TestConstructorWithMoves.java
+33
-0
jadx-core/src/test/smali/invoke/TestConstructorWithMoves.smali
...core/src/test/smali/invoke/TestConstructorWithMoves.smali
+19
-0
未找到文件。
jadx-core/src/main/java/jadx/core/Jadx.java
浏览文件 @
e22474e0
...
...
@@ -58,6 +58,7 @@ public class Jadx {
passes
.
add
(
new
BlockFinish
());
passes
.
add
(
new
SSATransform
());
passes
.
add
(
new
MoveInlineVisitor
());
passes
.
add
(
new
ConstructorVisitor
());
passes
.
add
(
new
InitCodeVariables
());
passes
.
add
(
new
MarkFinallyVisitor
());
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
浏览文件 @
e22474e0
...
...
@@ -130,12 +130,20 @@ public class RegisterArg extends InsnArg implements Named {
return
duplicate
(
getRegNum
(),
sVar
);
}
public
RegisterArg
duplicate
(
ArgType
initType
)
{
return
duplicate
(
getRegNum
(),
initType
,
sVar
);
}
public
RegisterArg
duplicate
(
@Nullable
SSAVar
ssaVar
)
{
return
duplicate
(
getRegNum
(),
ssaVar
);
}
public
RegisterArg
duplicate
(
int
regNum
,
@Nullable
SSAVar
sVar
)
{
RegisterArg
dup
=
new
RegisterArg
(
regNum
,
getInitType
());
return
duplicate
(
regNum
,
getInitType
(),
sVar
);
}
public
RegisterArg
duplicate
(
int
regNum
,
ArgType
initType
,
@Nullable
SSAVar
sVar
)
{
RegisterArg
dup
=
new
RegisterArg
(
regNum
,
initType
);
if
(
sVar
!=
null
)
{
// only 'set' here, 'assign' or 'use' will binds later
dup
.
setSVar
(
sVar
);
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
浏览文件 @
e22474e0
...
...
@@ -217,6 +217,17 @@ public class InsnNode extends LineAttrNode {
}
}
public
boolean
canRemoveResult
()
{
switch
(
getType
())
{
case
INVOKE:
case
CONSTRUCTOR:
return
true
;
default
:
return
false
;
}
}
public
boolean
canReorder
()
{
if
(
contains
(
AFlag
.
DONT_GENERATE
))
{
if
(
getType
()
==
InsnType
.
MONITOR_EXIT
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstructorVisitor.java
浏览文件 @
e22474e0
...
...
@@ -24,7 +24,7 @@ import jadx.core.utils.InsnRemover;
@JadxVisitor
(
name
=
"ConstructorVisitor"
,
desc
=
"Replace invoke with constructor call"
,
runAfter
=
SSATransform
.
class
,
runAfter
=
{
SSATransform
.
class
,
MoveInlineVisitor
.
class
}
,
runBefore
=
TypeInferenceVisitor
.
class
)
public
class
ConstructorVisitor
extends
AbstractVisitor
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/MoveInlineVisitor.java
0 → 100644
浏览文件 @
e22474e0
package
jadx.core.dex.visitors
;
import
java.util.ArrayList
;
import
java.util.List
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.RegDebugInfoAttr
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.InsnArg
;
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.dex.visitors.shrink.CodeShrinkVisitor
;
import
jadx.core.dex.visitors.ssa.SSATransform
;
import
jadx.core.utils.InsnRemover
;
@JadxVisitor
(
name
=
"MoveInlineVisitor"
,
desc
=
"Inline redundant move instructions"
,
runAfter
=
SSATransform
.
class
,
runBefore
=
CodeShrinkVisitor
.
class
)
public
class
MoveInlineVisitor
extends
AbstractVisitor
{
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
{
return
;
}
moveInline
(
mth
);
}
private
static
void
moveInline
(
MethodNode
mth
)
{
InsnRemover
remover
=
new
InsnRemover
(
mth
);
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
List
<
InsnNode
>
insns
=
block
.
getInstructions
();
int
size
=
insns
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
InsnNode
insn
=
insns
.
get
(
i
);
if
(
insn
.
getType
()
==
InsnType
.
MOVE
&&
processMove
(
mth
,
block
,
insn
,
i
))
{
remover
.
addAndUnbind
(
insn
);
}
}
remover
.
perform
();
}
}
private
static
boolean
processMove
(
MethodNode
mth
,
BlockNode
block
,
InsnNode
move
,
int
i
)
{
RegisterArg
resultArg
=
move
.
getResult
();
InsnArg
moveArg
=
move
.
getArg
(
0
);
if
(
resultArg
.
sameRegAndSVar
(
moveArg
))
{
return
true
;
}
SSAVar
ssaVar
=
resultArg
.
getSVar
();
if
(
ssaVar
.
isUsedInPhi
())
{
return
false
;
}
RegDebugInfoAttr
debugInfo
=
resultArg
.
get
(
AType
.
REG_DEBUG_INFO
);
for
(
RegisterArg
useArg
:
ssaVar
.
getUseList
())
{
InsnNode
useInsn
=
useArg
.
getParentInsn
();
if
(
useInsn
==
null
||
!
fromThisBlock
(
block
,
useInsn
,
i
))
{
return
false
;
}
RegDebugInfoAttr
debugInfoAttr
=
useArg
.
get
(
AType
.
REG_DEBUG_INFO
);
if
(
debugInfoAttr
!=
null
)
{
debugInfo
=
debugInfoAttr
;
}
}
// all checks passed, execute inline
for
(
RegisterArg
useArg
:
new
ArrayList
<>(
ssaVar
.
getUseList
()))
{
InsnNode
useInsn
=
useArg
.
getParentInsn
();
InsnArg
replaceArg
;
if
(
moveArg
.
isRegister
())
{
replaceArg
=
((
RegisterArg
)
moveArg
).
duplicate
(
useArg
.
getInitType
());
}
else
{
replaceArg
=
moveArg
.
duplicate
();
}
replaceArg
.
copyAttributesFrom
(
useArg
);
if
(
debugInfo
!=
null
)
{
replaceArg
.
addAttr
(
debugInfo
);
}
if
(
useInsn
==
null
||
!
useInsn
.
replaceArg
(
useArg
,
replaceArg
))
{
mth
.
addWarnComment
(
"Failed to replace arg in insn: "
+
useInsn
);
}
}
return
true
;
}
private
static
boolean
fromThisBlock
(
BlockNode
block
,
InsnNode
insn
,
int
curPos
)
{
List
<
InsnNode
>
list
=
block
.
getInstructions
();
int
size
=
list
.
size
();
for
(
int
j
=
curPos
;
j
<
size
;
j
++)
{
if
(
list
.
get
(
j
)
==
insn
)
{
return
true
;
}
}
return
false
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/variables/ProcessVariables.java
浏览文件 @
e22474e0
...
...
@@ -26,6 +26,7 @@ import jadx.core.dex.nodes.InsnNode;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.dex.visitors.regions.AbstractRegionVisitor
;
import
jadx.core.dex.visitors.regions.DepthRegionTraversal
;
import
jadx.core.dex.visitors.typeinference.TypeCompare
;
import
jadx.core.dex.visitors.typeinference.TypeCompareEnum
;
...
...
@@ -41,6 +42,7 @@ public class ProcessVariables extends AbstractVisitor {
if
(
mth
.
isNoCode
()
||
mth
.
getSVars
().
isEmpty
())
{
return
;
}
removeUnusedResults
(
mth
);
List
<
CodeVar
>
codeVars
=
collectCodeVars
(
mth
);
if
(
codeVars
.
isEmpty
())
{
...
...
@@ -64,6 +66,24 @@ public class ProcessVariables extends AbstractVisitor {
}
}
private
static
void
removeUnusedResults
(
MethodNode
mth
)
{
DepthRegionTraversal
.
traverse
(
mth
,
new
AbstractRegionVisitor
()
{
@Override
public
void
processBlock
(
MethodNode
mth
,
IBlock
container
)
{
for
(
InsnNode
insn
:
container
.
getInstructions
())
{
RegisterArg
resultArg
=
insn
.
getResult
();
if
(
resultArg
!=
null
)
{
SSAVar
ssaVar
=
resultArg
.
getSVar
();
if
(
ssaVar
.
getUseList
().
isEmpty
()
&&
insn
.
canRemoveResult
())
{
insn
.
setResult
(
null
);
mth
.
removeSVar
(
ssaVar
);
}
}
}
}
});
}
private
void
checkCodeVars
(
MethodNode
mth
,
List
<
CodeVar
>
codeVars
)
{
int
unknownTypesCount
=
0
;
for
(
CodeVar
codeVar
:
codeVars
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/invoke/TestConstructorWithMoves.java
0 → 100644
浏览文件 @
e22474e0
package
jadx.tests.integration.invoke
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestConstructorWithMoves
extends
SmaliTest
{
// @formatter:off
/*
public boolean test() {
java.lang.Boolean r5 = new java.lang.Boolean
r8 = r5
r5 = r8
r6 = r8
java.lang.String r7 = "test"
r6.<init>(r7)
java.lang.Boolean r5 = (java.lang.Boolean) r5
boolean r5 = r5.booleanValue()
r3 = r5
return r3
}
*/
// @formatter:on
@Test
public
void
test
()
{
assertThat
(
getClassNodeFromSmali
())
.
code
()
.
containsOne
(
"return new Boolean(\"test\").booleanValue();"
);
}
}
jadx-core/src/test/smali/invoke/TestConstructorWithMoves.smali
0 → 100644
浏览文件 @
e22474e0
.class public Linvoke/TestConstructorWithMoves;
.super Ljava/lang/Object;
.method static public test()Z
.registers 11
new-instance v5, Ljava/lang/Boolean;
move-object v8, v5
move-object v5, v8
move-object v6, v8
const-string v7, "test"
invoke-direct {v6, v7}, Ljava/lang/Boolean;-><init>(Ljava/lang/String;)V
check-cast v5, Ljava/lang/Boolean;
invoke-virtual {v5}, Ljava/lang/Boolean;->booleanValue()Z
move-result v5
move v3, v5
return v3
.end method
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录