Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
keyescgm
jadx
提交
13c17a00
J
jadx
项目概览
keyescgm
/
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,发现更多精彩内容 >>
提交
13c17a00
编写于
12月 12, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: force code inline after new array creation resugar (#1048)
上级
96dea75b
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
53 addition
and
28 deletion
+53
-28
jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
...ore/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
+26
-28
jadx-core/src/test/java/jadx/tests/integration/invoke/TestVarArg2.java
.../test/java/jadx/tests/integration/invoke/TestVarArg2.java
+27
-0
未找到文件。
jadx-core/src/main/java/jadx/core/dex/visitors/ReSugarCode.java
浏览文件 @
13c17a00
...
...
@@ -4,8 +4,6 @@ import java.util.List;
import
java.util.stream.Collectors
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
...
...
@@ -44,8 +42,6 @@ import jadx.core.utils.exceptions.JadxException;
)
public
class
ReSugarCode
extends
AbstractVisitor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ReSugarCode
.
class
);
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
JadxException
{
initClsEnumMap
(
cls
);
...
...
@@ -57,55 +53,57 @@ public class ReSugarCode extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
boolean
changed
=
false
;
InsnRemover
remover
=
new
InsnRemover
(
mth
);
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
int
size
=
instructions
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
process
(
mth
,
instructions
,
i
,
remover
);
changed
|=
process
(
mth
,
instructions
,
i
,
remover
);
}
remover
.
perform
();
}
if
(
changed
)
{
CodeShrinkVisitor
.
shrinkMethod
(
mth
);
}
}
private
static
void
process
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
InsnRemover
remover
)
{
private
static
boolean
process
(
MethodNode
mth
,
List
<
InsnNode
>
instructions
,
int
i
,
InsnRemover
remover
)
{
InsnNode
insn
=
instructions
.
get
(
i
);
if
(
insn
.
contains
(
AFlag
.
REMOVE
))
{
return
;
return
false
;
}
switch
(
insn
.
getType
())
{
case
NEW_ARRAY:
processNewArray
(
mth
,
(
NewArrayNode
)
insn
,
instructions
,
remover
);
break
;
return
processNewArray
(
mth
,
(
NewArrayNode
)
insn
,
instructions
,
remover
);
case
SWITCH:
processEnumSwitch
(
mth
,
(
SwitchInsn
)
insn
);
break
;
return
processEnumSwitch
(
mth
,
(
SwitchInsn
)
insn
);
default
:
break
;
return
false
;
}
}
/**
* Replace new-array and sequence of array-put to new filled-array instruction.
*/
private
static
void
processNewArray
(
MethodNode
mth
,
NewArrayNode
newArrayInsn
,
private
static
boolean
processNewArray
(
MethodNode
mth
,
NewArrayNode
newArrayInsn
,
List
<
InsnNode
>
instructions
,
InsnRemover
remover
)
{
InsnArg
arrLenArg
=
newArrayInsn
.
getArg
(
0
);
if
(!
arrLenArg
.
isLiteral
())
{
return
;
return
false
;
}
int
len
=
(
int
)
((
LiteralArg
)
arrLenArg
).
getLiteral
();
if
(
len
==
0
)
{
return
;
return
false
;
}
RegisterArg
arrArg
=
newArrayInsn
.
getResult
();
SSAVar
ssaVar
=
arrArg
.
getSVar
();
List
<
RegisterArg
>
useList
=
ssaVar
.
getUseList
();
if
(
useList
.
size
()
<
len
)
{
return
;
return
false
;
}
// check sequential array put with increasing index
int
putIndex
=
0
;
...
...
@@ -118,17 +116,15 @@ public class ReSugarCode extends AbstractVisitor {
}
}
if
(
putIndex
!=
len
)
{
return
;
return
false
;
}
List
<
InsnNode
>
arrPuts
=
useList
.
subList
(
0
,
len
).
stream
().
map
(
InsnArg:
:
getParentInsn
).
collect
(
Collectors
.
toList
());
// check that all puts in current block
for
(
InsnNode
arrPut
:
arrPuts
)
{
int
index
=
InsnList
.
getIndex
(
instructions
,
arrPut
);
if
(
index
==
-
1
)
{
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"TODO: APUT found in different block: {}, mth: {}"
,
arrPut
,
mth
);
}
return
;
mth
.
addDebugComment
(
"Can't convert new array creation: APUT found in different block: "
+
arrPut
);
return
false
;
}
}
...
...
@@ -146,6 +142,7 @@ public class ReSugarCode extends AbstractVisitor {
InsnNode
lastPut
=
Utils
.
last
(
arrPuts
);
int
replaceIndex
=
InsnList
.
getIndex
(
instructions
,
lastPut
);
instructions
.
set
(
replaceIndex
,
filledArr
);
return
true
;
}
private
static
boolean
checkPutInsn
(
MethodNode
mth
,
InsnNode
insn
,
RegisterArg
arrArg
,
int
putIndex
)
{
...
...
@@ -164,43 +161,44 @@ public class ReSugarCode extends AbstractVisitor {
return
false
;
}
private
static
void
processEnumSwitch
(
MethodNode
mth
,
SwitchInsn
insn
)
{
private
static
boolean
processEnumSwitch
(
MethodNode
mth
,
SwitchInsn
insn
)
{
InsnArg
arg
=
insn
.
getArg
(
0
);
if
(!
arg
.
isInsnWrap
())
{
return
;
return
false
;
}
InsnNode
wrapInsn
=
((
InsnWrapArg
)
arg
).
getWrapInsn
();
if
(
wrapInsn
.
getType
()
!=
InsnType
.
AGET
)
{
return
;
return
false
;
}
EnumMapInfo
enumMapInfo
=
checkEnumMapAccess
(
mth
.
root
(),
wrapInsn
);
if
(
enumMapInfo
==
null
)
{
return
;
return
false
;
}
FieldNode
enumMapField
=
enumMapInfo
.
getMapField
();
InsnArg
invArg
=
enumMapInfo
.
getArg
();
EnumMapAttr
.
KeyValueMap
valueMap
=
getEnumMap
(
mth
,
enumMapField
);
if
(
valueMap
==
null
)
{
return
;
return
false
;
}
int
caseCount
=
insn
.
getKeys
().
length
;
for
(
int
i
=
0
;
i
<
caseCount
;
i
++)
{
Object
key
=
insn
.
getKey
(
i
);
Object
newKey
=
valueMap
.
get
(
key
);
if
(
newKey
==
null
)
{
return
;
return
false
;
}
}
// replace confirmed
if
(!
insn
.
replaceArg
(
arg
,
invArg
))
{
return
;
return
false
;
}
for
(
int
i
=
0
;
i
<
caseCount
;
i
++)
{
insn
.
modifyKey
(
i
,
valueMap
.
get
(
insn
.
getKey
(
i
)));
}
enumMapField
.
add
(
AFlag
.
DONT_GENERATE
);
checkAndHideClass
(
enumMapField
.
getParentClass
());
return
true
;
}
private
static
void
initClsEnumMap
(
ClassNode
enumCls
)
{
...
...
jadx-core/src/test/java/jadx/tests/integration/invoke/TestVarArg2.java
0 → 100644
浏览文件 @
13c17a00
package
jadx.tests.integration.invoke
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestVarArg2
extends
IntegrationTest
{
@SuppressWarnings
(
"ConstantConditions"
)
public
static
class
TestCls
{
protected
static
boolean
b1
;
protected
static
final
boolean
IS_VALID
=
b1
&&
isValid
(
"test"
);
private
static
boolean
isValid
(
String
...
string
)
{
return
false
;
}
}
@Test
public
void
test
()
{
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
containsOne
(
"isValid(\"test\")"
);
// TODO: .containsOne("b1 && isValid(\"test\")");
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录