Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Quincy379
jadx
提交
7b6825d8
J
jadx
项目概览
Quincy379
/
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,发现更多精彩内容 >>
提交
7b6825d8
编写于
5月 31, 2018
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core: move same instructions from predecessors for loops
上级
a27cb9c3
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
171 addition
and
32 deletion
+171
-32
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
...core/src/main/java/jadx/core/dex/attributes/AttrNode.java
+4
-0
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+16
-3
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java
...va/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java
+149
-27
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockSplitter.java
...ava/jadx/core/dex/visitors/blocksmaker/BlockSplitter.java
+2
-2
未找到文件。
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
浏览文件 @
7b6825d8
...
...
@@ -96,4 +96,8 @@ public abstract class AttrNode implements IAttributeNode {
public
String
getAttributesString
()
{
return
storage
.
toString
();
}
public
boolean
isAttrStorageEmpty
()
{
return
storage
.
isEmpty
();
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
浏览文件 @
7b6825d8
...
...
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Objects
;
import
com.android.dx.io.instructions.DecodedInstruction
;
import
com.rits.cloning.Cloner
;
...
...
@@ -251,12 +252,14 @@ public class InsnNode extends LineAttrNode {
if
(
this
==
other
)
{
return
true
;
}
if
(
insnType
!=
other
.
insnType
||
arguments
.
size
()
!=
other
.
arguments
.
size
())
{
if
(
insnType
!=
other
.
insnType
)
{
return
false
;
}
// check wrapped instructions
int
size
=
arguments
.
size
();
if
(
size
!=
other
.
arguments
.
size
())
{
return
false
;
}
// check wrapped instructions
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
InsnArg
arg
=
arguments
.
get
(
i
);
InsnArg
otherArg
=
other
.
arguments
.
get
(
i
);
...
...
@@ -273,6 +276,16 @@ public class InsnNode extends LineAttrNode {
}
return
true
;
}
/**
* 'Hard' equals, compare all arguments
*/
public
boolean
isDeepEquals
(
InsnNode
other
)
{
if
(
this
==
other
)
{
return
true
;
}
return
isSame
(
other
)
&&
Objects
.
equals
(
arguments
,
other
.
arguments
);
}
protected
<
T
extends
InsnNode
>
T
copyCommonParams
(
T
copy
)
{
copy
.
setResult
(
result
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockProcessor.java
浏览文件 @
7b6825d8
...
...
@@ -45,6 +45,10 @@ public class BlockProcessor extends AbstractVisitor {
private
static
void
processBlocksTree
(
MethodNode
mth
)
{
computeDominators
(
mth
);
if
(
independentBlockTreeMod
(
mth
))
{
clearBlocksState
(
mth
);
computeDominators
(
mth
);
}
markReturnBlocks
(
mth
);
int
i
=
0
;
...
...
@@ -64,6 +68,109 @@ public class BlockProcessor extends AbstractVisitor {
processNestedLoops
(
mth
);
}
private
static
boolean
removeEmptyBlock
(
MethodNode
mth
,
BlockNode
block
)
{
if
(
block
.
getInstructions
().
isEmpty
()
&&
!
block
.
isSynthetic
()
&&
block
.
isAttrStorageEmpty
()
&&
block
.
getSuccessors
().
size
()
<=
1
)
{
LOG
.
debug
(
"Removing empty block: {}"
,
block
);
if
(
block
.
getSuccessors
().
size
()
==
1
)
{
BlockNode
successor
=
block
.
getSuccessors
().
get
(
0
);
block
.
getPredecessors
().
forEach
(
pred
->
{
pred
.
getSuccessors
().
remove
(
block
);
BlockSplitter
.
connect
(
pred
,
successor
);
BlockSplitter
.
replaceTarget
(
pred
,
block
,
successor
);
pred
.
updateCleanSuccessors
();
});
BlockSplitter
.
removeConnection
(
block
,
successor
);
}
else
{
block
.
getPredecessors
().
forEach
(
pred
->
{
pred
.
getSuccessors
().
remove
(
block
);
pred
.
updateCleanSuccessors
();
});
}
block
.
add
(
AFlag
.
REMOVE
);
block
.
getSuccessors
().
clear
();
block
.
getPredecessors
().
clear
();
return
true
;
}
return
false
;
}
private
static
boolean
deduplicateBlockInsns
(
BlockNode
block
)
{
if
(
block
.
contains
(
AFlag
.
LOOP_START
)
||
block
.
contains
(
AFlag
.
LOOP_END
))
{
// search for same instruction at end of all predecessors blocks
List
<
BlockNode
>
predecessors
=
block
.
getPredecessors
();
int
predsCount
=
predecessors
.
size
();
if
(
predsCount
>
1
)
{
InsnNode
lastInsn
=
BlockUtils
.
getLastInsn
(
block
);
if
(
lastInsn
!=
null
&&
lastInsn
.
getType
()
==
InsnType
.
IF
)
{
return
false
;
}
int
sameInsnCount
=
getSameLastInsnCount
(
predecessors
);
if
(
sameInsnCount
>
0
)
{
List
<
InsnNode
>
insns
=
getLastInsns
(
predecessors
.
get
(
0
),
sameInsnCount
);
insertAtStart
(
block
,
insns
);
predecessors
.
forEach
(
pred
->
getLastInsns
(
pred
,
sameInsnCount
).
clear
());
LOG
.
debug
(
"Move duplicate insns, count: {} to block {}"
,
sameInsnCount
,
block
);
return
true
;
}
}
}
return
false
;
}
private
static
List
<
InsnNode
>
getLastInsns
(
BlockNode
blockNode
,
int
sameInsnCount
)
{
List
<
InsnNode
>
instructions
=
blockNode
.
getInstructions
();
int
size
=
instructions
.
size
();
return
instructions
.
subList
(
size
-
sameInsnCount
,
size
);
}
private
static
void
insertAtStart
(
BlockNode
block
,
List
<
InsnNode
>
insns
)
{
List
<
InsnNode
>
blockInsns
=
block
.
getInstructions
();
List
<
InsnNode
>
newInsnList
=
new
ArrayList
<>(
insns
.
size
()
+
blockInsns
.
size
());
newInsnList
.
addAll
(
insns
);
newInsnList
.
addAll
(
blockInsns
);
blockInsns
.
clear
();
blockInsns
.
addAll
(
newInsnList
);
}
private
static
int
getSameLastInsnCount
(
List
<
BlockNode
>
predecessors
)
{
int
sameInsnCount
=
0
;
while
(
true
)
{
InsnNode
insn
=
null
;
for
(
BlockNode
pred
:
predecessors
)
{
InsnNode
curInsn
=
getInsnsFromEnd
(
pred
,
sameInsnCount
);
if
(
curInsn
==
null
)
{
return
sameInsnCount
;
}
if
(
insn
==
null
)
{
insn
=
curInsn
;
}
else
{
if
(!
isSame
(
insn
,
curInsn
))
{
return
sameInsnCount
;
}
}
}
sameInsnCount
++;
}
}
private
static
boolean
isSame
(
InsnNode
insn
,
InsnNode
curInsn
)
{
return
/*insn.getType() == InsnType.MOVE &&*/
insn
.
isDeepEquals
(
curInsn
)
&&
insn
.
canReorder
();
}
private
static
InsnNode
getInsnsFromEnd
(
BlockNode
block
,
int
number
)
{
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
int
insnCount
=
instructions
.
size
();
if
(
insnCount
<=
number
)
{
return
null
;
}
return
instructions
.
get
(
insnCount
-
number
-
1
);
}
private
static
void
computeDominators
(
MethodNode
mth
)
{
List
<
BlockNode
>
basicBlocks
=
mth
.
getBasicBlocks
();
int
nBlocks
=
basicBlocks
.
size
();
...
...
@@ -104,9 +211,7 @@ public class BlockProcessor extends AbstractVisitor {
markLoops
(
mth
);
// clear self dominance
for
(
BlockNode
block
:
basicBlocks
)
{
block
.
getDoms
().
clear
(
block
.
getId
());
}
basicBlocks
.
forEach
(
block
->
block
.
getDoms
().
clear
(
block
.
getId
()));
// calculate immediate dominators
for
(
BlockNode
block
:
basicBlocks
)
{
...
...
@@ -148,9 +253,7 @@ public class BlockProcessor extends AbstractVisitor {
if
(
block
.
getDomFrontier
()
!=
null
)
{
return
;
}
for
(
BlockNode
c
:
block
.
getDominatesOn
())
{
computeBlockDF
(
mth
,
c
);
}
block
.
getDominatesOn
().
forEach
(
c
->
computeBlockDF
(
mth
,
c
));
List
<
BlockNode
>
blocks
=
mth
.
getBasicBlocks
();
BitSet
domFrontier
=
null
;
for
(
BlockNode
s
:
block
.
getSuccessors
())
{
...
...
@@ -180,39 +283,37 @@ public class BlockProcessor extends AbstractVisitor {
private
static
void
markReturnBlocks
(
MethodNode
mth
)
{
mth
.
getExitBlocks
().
clear
();
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
mth
.
getBasicBlocks
().
forEach
(
block
->
{
if
(
BlockUtils
.
checkLastInsnType
(
block
,
InsnType
.
RETURN
))
{
block
.
add
(
AFlag
.
RETURN
);
mth
.
getExitBlocks
().
add
(
block
);
}
}
}
);
}
private
static
void
markLoops
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
BlockNode
succ
:
block
.
getSuccessors
())
{
// Every successor that dominates its predecessor is a header of a loop,
// block -> succ is a back edge.
if
(
block
.
getDoms
().
get
(
succ
.
getId
()))
{
succ
.
add
(
AFlag
.
LOOP_START
);
mth
.
getBasicBlocks
().
forEach
(
block
->
{
// Every successor that dominates its predecessor is a header of a loop,
// block -> succ is a back edge.
block
.
getSuccessors
().
forEach
(
successor
->
{
if
(
block
.
getDoms
().
get
(
succ
essor
.
getId
()))
{
succ
essor
.
add
(
AFlag
.
LOOP_START
);
block
.
add
(
AFlag
.
LOOP_END
);
LoopInfo
loop
=
new
LoopInfo
(
succ
,
block
);
succ
.
addAttr
(
AType
.
LOOP
,
loop
);
LoopInfo
loop
=
new
LoopInfo
(
succ
essor
,
block
);
succ
essor
.
addAttr
(
AType
.
LOOP
,
loop
);
block
.
addAttr
(
AType
.
LOOP
,
loop
);
}
}
}
}
);
}
);
}
private
static
void
registerLoops
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
mth
.
getBasicBlocks
().
forEach
(
block
->
{
if
(
block
.
contains
(
AFlag
.
LOOP_START
))
{
for
(
LoopInfo
loop
:
block
.
getAll
(
AType
.
LOOP
))
{
mth
.
registerLoop
(
loop
);
}
block
.
getAll
(
AType
.
LOOP
).
forEach
(
mth:
:
registerLoop
);
}
}
}
);
}
private
static
void
processNestedLoops
(
MethodNode
mth
)
{
...
...
@@ -242,10 +343,14 @@ public class BlockProcessor extends AbstractVisitor {
}
private
static
boolean
modifyBlocksTree
(
MethodNode
mth
)
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
List
<
BlockNode
>
basicBlocks
=
mth
.
getBasicBlocks
();
for
(
BlockNode
block
:
basicBlocks
)
{
if
(
block
.
getPredecessors
().
isEmpty
()
&&
block
!=
mth
.
getEnterBlock
())
{
throw
new
JadxRuntimeException
(
"Unreachable block: "
+
block
);
}
}
for
(
BlockNode
block
:
basicBlocks
)
{
if
(
checkLoops
(
mth
,
block
))
{
return
true
;
}
...
...
@@ -253,6 +358,25 @@ public class BlockProcessor extends AbstractVisitor {
return
splitReturn
(
mth
);
}
private
static
boolean
independentBlockTreeMod
(
MethodNode
mth
)
{
List
<
BlockNode
>
basicBlocks
=
mth
.
getBasicBlocks
();
boolean
changed
=
false
;
for
(
BlockNode
basicBlock
:
basicBlocks
)
{
if
(
deduplicateBlockInsns
(
basicBlock
))
{
changed
=
true
;
}
}
for
(
BlockNode
basicBlock
:
basicBlocks
)
{
if
(
removeEmptyBlock
(
mth
,
basicBlock
))
{
changed
=
true
;
}
}
if
(
BlockSplitter
.
removeEmptyDetachedBlocks
(
mth
))
{
changed
=
true
;
}
return
changed
;
}
private
static
boolean
checkLoops
(
MethodNode
mth
,
BlockNode
block
)
{
// check loops
List
<
LoopInfo
>
loops
=
block
.
getAll
(
AType
.
LOOP
);
...
...
@@ -303,9 +427,7 @@ public class BlockProcessor extends AbstractVisitor {
change
=
true
;
}
}
if
(
change
)
{
return
true
;
}
return
change
;
}
}
return
false
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockSplitter.java
浏览文件 @
7b6825d8
...
...
@@ -253,8 +253,8 @@ public class BlockSplitter extends AbstractVisitor {
}
}
static
void
removeEmptyDetachedBlocks
(
MethodNode
mth
)
{
mth
.
getBasicBlocks
().
removeIf
(
block
->
static
boolean
removeEmptyDetachedBlocks
(
MethodNode
mth
)
{
return
mth
.
getBasicBlocks
().
removeIf
(
block
->
block
.
getInstructions
().
isEmpty
()
&&
block
.
getPredecessors
().
isEmpty
()
&&
block
.
getSuccessors
().
isEmpty
()
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录