Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
f9f840fb
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,体验更适合开发者的 AI 搜索 >>
提交
f9f840fb
编写于
7月 15, 2019
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
refactor: remove redundant FieldArg and change arith one arg insn
上级
8e8a2faa
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
152 addition
and
220 deletion
+152
-220
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+12
-16
jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java
...e/src/main/java/jadx/core/dex/instructions/ArithNode.java
+10
-4
jadx-core/src/main/java/jadx/core/dex/instructions/args/FieldArg.java
...c/main/java/jadx/core/dex/instructions/args/FieldArg.java
+0
-93
jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java
...rc/main/java/jadx/core/dex/instructions/args/InsnArg.java
+0
-4
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+9
-0
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
...core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
+91
-64
jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
...c/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
+3
-1
jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
...src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
+24
-35
jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java
...src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java
+1
-1
jadx-core/src/test/java/jadx/tests/integration/arith/TestArith3.java
...rc/test/java/jadx/tests/integration/arith/TestArith3.java
+2
-2
未找到文件。
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
浏览文件 @
f9f840fb
...
...
@@ -36,7 +36,6 @@ import jadx.core.dex.instructions.NewArrayNode;
import
jadx.core.dex.instructions.SwitchNode
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.CodeVar
;
import
jadx.core.dex.instructions.args.FieldArg
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
...
...
@@ -105,13 +104,6 @@ public class InsnGen {
makeInsn
(((
InsnWrapArg
)
arg
).
getWrapInsn
(),
code
,
flag
);
}
else
if
(
arg
.
isNamed
())
{
code
.
add
(((
Named
)
arg
).
getName
());
}
else
if
(
arg
.
isField
())
{
FieldArg
f
=
(
FieldArg
)
arg
;
if
(
f
.
isStatic
())
{
staticField
(
code
,
f
.
getField
());
}
else
{
instanceField
(
code
,
f
.
getField
(),
f
.
getInstanceArg
());
}
}
else
{
throw
new
CodegenException
(
"Unknown arg type "
+
arg
);
}
...
...
@@ -174,6 +166,7 @@ public class InsnGen {
public
static
void
makeStaticFieldAccess
(
CodeWriter
code
,
FieldInfo
field
,
ClassGen
clsGen
)
{
ClassInfo
declClass
=
field
.
getDeclClass
();
// TODO
boolean
fieldFromThisClass
=
clsGen
.
getClassNode
().
getClassInfo
().
equals
(
declClass
);
if
(!
fieldFromThisClass
)
{
// Android specific resources class handler
...
...
@@ -231,10 +224,10 @@ public class InsnGen {
code
.
add
(
"// "
);
}
}
if
(
insn
.
getResult
()
!=
null
)
{
SSAVar
var
=
insn
.
getResult
().
getSVar
();
if
((
var
==
null
||
var
.
getUseCount
()
!=
0
||
insn
.
getType
()
!=
InsnType
.
CONSTRUCTOR
)
&&
!
insn
.
contains
(
AFlag
.
ARITH_ONEARG
)
)
{
RegisterArg
resArg
=
insn
.
getResult
();
if
(
resArg
!=
null
)
{
SSAVar
var
=
resArg
.
getSVar
();
if
(
var
==
null
||
var
.
getUseCount
()
!=
0
||
insn
.
getType
()
!=
InsnType
.
CONSTRUCTOR
)
{
assignVar
(
code
,
insn
);
code
.
add
(
" = "
);
}
...
...
@@ -981,19 +974,22 @@ public class InsnGen {
private
void
makeArithOneArg
(
ArithNode
insn
,
CodeWriter
code
)
throws
CodegenException
{
ArithOp
op
=
insn
.
getOp
();
InsnArg
resArg
=
insn
.
getArg
(
0
);
InsnArg
arg
=
insn
.
getArg
(
1
);
// "++" or "--"
if
(
arg
.
isLiteral
()
&&
(
op
==
ArithOp
.
ADD
||
op
==
ArithOp
.
SUB
))
{
LiteralArg
lit
=
(
LiteralArg
)
arg
;
if
(
lit
.
isInteger
()
&&
lit
.
getLiteral
()
==
1
)
{
a
ssignVar
(
code
,
insn
);
if
(
lit
.
getLiteral
()
==
1
&&
lit
.
isInteger
()
)
{
a
ddArg
(
code
,
resArg
,
false
);
String
opSymbol
=
op
.
getSymbol
();
code
.
add
(
opSymbol
).
add
(
opSymbol
);
return
;
}
}
// +=, -= ...
assignVar
(
code
,
insn
);
// +=, -=, ...
addArg
(
code
,
resArg
,
false
);
code
.
add
(
' '
).
add
(
op
.
getSymbol
()).
add
(
"= "
);
addArg
(
code
,
arg
,
false
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/ArithNode.java
浏览文件 @
f9f840fb
...
...
@@ -51,10 +51,16 @@ public class ArithNode extends InsnNode {
addArg
(
b
);
}
// TODO: remove result for one arg insn, this will simplify processing and allow to remove FieldArg
public
ArithNode
(
ArithOp
op
,
RegisterArg
res
,
InsnArg
a
)
{
this
(
op
,
res
,
res
,
a
);
add
(
AFlag
.
ARITH_ONEARG
);
/**
* Create one argument arithmetic instructions (a+=2).
* Result is not set (null).
*
* @param res argument to change
*/
public
static
ArithNode
oneArgOp
(
ArithOp
op
,
InsnArg
res
,
InsnArg
a
)
{
ArithNode
insn
=
new
ArithNode
(
op
,
null
,
res
,
a
);
insn
.
add
(
AFlag
.
ARITH_ONEARG
);
return
insn
;
}
public
ArithOp
getOp
()
{
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/FieldArg.java
已删除
100644 → 0
浏览文件 @
8e8a2faa
package
jadx.core.dex.instructions.args
;
import
java.util.Objects
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
// TODO: don't extend RegisterArg (now used as a result of instruction)
public
final
class
FieldArg
extends
RegisterArg
{
private
final
FieldInfo
field
;
// instArg equal 'null' for static fields
@Nullable
private
final
InsnArg
instArg
;
public
FieldArg
(
FieldInfo
field
,
@Nullable
InsnArg
reg
)
{
super
(-
1
,
field
.
getType
());
this
.
instArg
=
reg
;
this
.
field
=
field
;
}
public
FieldInfo
getField
()
{
return
field
;
}
public
InsnArg
getInstanceArg
()
{
return
instArg
;
}
public
boolean
isStatic
()
{
return
instArg
==
null
;
}
@Override
public
boolean
isField
()
{
return
true
;
}
@Override
public
boolean
isRegister
()
{
return
false
;
}
@Override
public
ArgType
getType
()
{
return
this
.
field
.
getType
();
}
@Override
public
ArgType
getInitType
()
{
return
this
.
field
.
getType
();
}
@Override
public
void
setType
(
ArgType
newType
)
{
throw
new
JadxRuntimeException
(
"Can't set type for FieldArg"
);
}
@Override
public
RegisterArg
duplicate
()
{
return
copyCommonParams
(
new
FieldArg
(
field
,
instArg
));
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
{
return
true
;
}
if
(!(
obj
instanceof
FieldArg
)
||
!
super
.
equals
(
obj
))
{
return
false
;
}
FieldArg
fieldArg
=
(
FieldArg
)
obj
;
if
(!
field
.
equals
(
fieldArg
.
field
))
{
return
false
;
}
return
Objects
.
equals
(
instArg
,
fieldArg
.
instArg
);
}
@Override
public
int
hashCode
()
{
int
result
=
super
.
hashCode
();
result
=
31
*
result
+
field
.
hashCode
();
result
=
31
*
result
+
(
instArg
!=
null
?
instArg
.
hashCode
()
:
0
);
return
result
;
}
@Override
public
String
toString
()
{
return
"("
+
field
+
')'
;
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java
浏览文件 @
f9f840fb
...
...
@@ -84,10 +84,6 @@ public abstract class InsnArg extends Typed {
return
false
;
}
public
boolean
isField
()
{
return
false
;
}
@Nullable
public
InsnNode
getParentInsn
()
{
return
parentInsn
;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
浏览文件 @
f9f840fb
...
...
@@ -206,6 +206,15 @@ public class InsnNode extends LineAttrNode {
}
return
true
;
}
for
(
InsnArg
arg
:
getArguments
())
{
if
(
arg
.
isInsnWrap
())
{
InsnNode
wrapInsn
=
((
InsnWrapArg
)
arg
).
getWrapInsn
();
if
(!
wrapInsn
.
canReorder
())
{
return
false
;
}
}
}
switch
(
getType
())
{
case
CONST:
case
CONST_STR:
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
浏览文件 @
f9f840fb
...
...
@@ -41,6 +41,7 @@ import jadx.core.dex.nodes.MethodNode;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
jadx.core.dex.trycatch.ExcHandlerAttr
;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.visitors.regions.variables.ProcessVariables
;
import
jadx.core.dex.visitors.shrink.CodeShrinkVisitor
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.InsnRemover
;
...
...
@@ -56,17 +57,22 @@ import static jadx.core.utils.BlockUtils.replaceInsn;
@JadxVisitor
(
name
=
"ModVisitor"
,
desc
=
"Modify method instructions"
,
runBefore
=
CodeShrinkVisitor
.
class
runBefore
=
{
CodeShrinkVisitor
.
class
,
ProcessVariables
.
class
}
)
public
class
ModVisitor
extends
AbstractVisitor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ModVisitor
.
class
);
private
static
final
long
DOUBLE_TO_BITS
=
Double
.
doubleToLongBits
(
1
);
private
static
final
long
FLOAT_TO_BITS
=
Float
.
floatToIntBits
(
1
);
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
{
return
;
}
InsnRemover
remover
=
new
InsnRemover
(
mth
);
replaceStep
(
mth
,
remover
);
removeStep
(
mth
,
remover
);
...
...
@@ -76,9 +82,10 @@ public class ModVisitor extends AbstractVisitor {
ClassNode
parentClass
=
mth
.
getParentClass
();
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
remover
.
setBlock
(
block
);
int
size
=
block
.
getInstructions
().
size
();
List
<
InsnNode
>
insnsList
=
block
.
getInstructions
();
int
size
=
insnsList
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
InsnNode
insn
=
block
.
getInstructions
()
.
get
(
i
);
InsnNode
insn
=
insnsList
.
get
(
i
);
switch
(
insn
.
getType
())
{
case
CONSTRUCTOR:
processAnonymousConstructor
(
mth
,
((
ConstructorInsn
)
insn
));
...
...
@@ -86,33 +93,12 @@ public class ModVisitor extends AbstractVisitor {
case
CONST:
case
CONST_STR:
case
CONST_CLASS:
{
FieldNode
f
;
if
(
insn
.
getType
()
==
InsnType
.
CONST_STR
)
{
String
s
=
((
ConstStringNode
)
insn
).
getString
();
f
=
parentClass
.
getConstField
(
s
);
}
else
if
(
insn
.
getType
()
==
InsnType
.
CONST_CLASS
)
{
ArgType
t
=
((
ConstClassNode
)
insn
).
getClsType
();
f
=
parentClass
.
getConstField
(
t
);
}
else
{
f
=
parentClass
.
getConstFieldByLiteralArg
((
LiteralArg
)
insn
.
getArg
(
0
));
}
if
(
f
!=
null
)
{
InsnNode
inode
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
inode
.
setResult
(
insn
.
getResult
());
replaceInsn
(
block
,
i
,
inode
);
}
case
CONST_CLASS:
replaceConst
(
parentClass
,
block
,
i
,
insn
);
break
;
}
case
SWITCH:
SwitchNode
sn
=
(
SwitchNode
)
insn
;
for
(
int
k
=
0
;
k
<
sn
.
getCasesCount
();
k
++)
{
FieldNode
f
=
parentClass
.
getConstField
(
sn
.
getKeys
()[
k
]);
if
(
f
!=
null
)
{
sn
.
getKeys
()[
k
]
=
f
;
}
}
replaceConstKeys
(
parentClass
,
(
SwitchNode
)
insn
);
break
;
case
NEW_ARRAY:
...
...
@@ -134,48 +120,15 @@ public class ModVisitor extends AbstractVisitor {
break
;
case
ARITH:
ArithNode
arithNode
=
(
ArithNode
)
insn
;
if
(
arithNode
.
getArgsCount
()
==
2
)
{
InsnArg
litArg
=
arithNode
.
getArg
(
1
);
if
(
litArg
.
isLiteral
())
{
FieldNode
f
=
parentClass
.
getConstFieldByLiteralArg
((
LiteralArg
)
litArg
);
if
(
f
!=
null
)
{
InsnNode
fGet
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
insn
.
replaceArg
(
litArg
,
InsnArg
.
wrapArg
(
fGet
));
}
}
}
processArith
(
parentClass
,
(
ArithNode
)
insn
);
break
;
case
CHECK_CAST:
InsnArg
castArg
=
insn
.
getArg
(
0
);
ArgType
castType
=
(
ArgType
)
((
IndexInsnNode
)
insn
).
getIndex
();
if
(!
ArgType
.
isCastNeeded
(
mth
.
dex
(),
castArg
.
getType
(),
castType
)
||
isCastDuplicate
((
IndexInsnNode
)
insn
))
{
InsnNode
insnNode
=
new
InsnNode
(
InsnType
.
MOVE
,
1
);
insnNode
.
setResult
(
insn
.
getResult
());
insnNode
.
addArg
(
castArg
);
replaceInsn
(
block
,
i
,
insnNode
);
}
removeRedundantCast
(
mth
,
block
,
i
,
(
IndexInsnNode
)
insn
);
break
;
case
CAST:
// replace boolean to (byte/char/short/long/double/float) cast with ternary
if
(
insn
.
getArg
(
0
).
getType
()
==
ArgType
.
BOOLEAN
)
{
ArgType
type
=
insn
.
getResult
().
getType
();
if
(
type
.
isPrimitive
())
{
IfNode
ifNode
=
new
IfNode
(
IfOp
.
EQ
,
-
1
,
insn
.
getArg
(
0
),
LiteralArg
.
TRUE
);
IfCondition
condition
=
IfCondition
.
fromIfNode
(
ifNode
);
InsnArg
zero
=
new
LiteralArg
(
0
,
type
);
InsnArg
one
=
new
LiteralArg
(
type
==
ArgType
.
DOUBLE
?
Double
.
doubleToLongBits
(
1
)
:
type
==
ArgType
.
FLOAT
?
Float
.
floatToIntBits
(
1
)
:
1
,
type
);
TernaryInsn
ternary
=
new
TernaryInsn
(
condition
,
insn
.
getResult
(),
one
,
zero
);
replaceInsn
(
block
,
i
,
ternary
);
}
}
fixPrimitiveCast
(
block
,
i
,
insn
);
break
;
default
:
...
...
@@ -186,6 +139,68 @@ public class ModVisitor extends AbstractVisitor {
}
}
private
static
void
replaceConstKeys
(
ClassNode
parentClass
,
SwitchNode
insn
)
{
for
(
int
k
=
0
;
k
<
insn
.
getCasesCount
();
k
++)
{
FieldNode
f
=
parentClass
.
getConstField
(
insn
.
getKeys
()[
k
]);
if
(
f
!=
null
)
{
insn
.
getKeys
()[
k
]
=
f
;
}
}
}
private
static
void
fixPrimitiveCast
(
BlockNode
block
,
int
i
,
InsnNode
insn
)
{
// replace boolean to (byte/char/short/long/double/float) cast with ternary
if
(
insn
.
getArg
(
0
).
getType
()
==
ArgType
.
BOOLEAN
)
{
ArgType
type
=
insn
.
getResult
().
getType
();
if
(
type
.
isPrimitive
())
{
IfNode
ifNode
=
new
IfNode
(
IfOp
.
EQ
,
-
1
,
insn
.
getArg
(
0
),
LiteralArg
.
TRUE
);
IfCondition
condition
=
IfCondition
.
fromIfNode
(
ifNode
);
InsnArg
zero
=
new
LiteralArg
(
0
,
type
);
long
litVal
=
1
;
if
(
type
==
ArgType
.
DOUBLE
)
{
litVal
=
DOUBLE_TO_BITS
;
}
else
if
(
type
==
ArgType
.
FLOAT
)
{
litVal
=
FLOAT_TO_BITS
;
}
InsnArg
one
=
new
LiteralArg
(
litVal
,
type
);
TernaryInsn
ternary
=
new
TernaryInsn
(
condition
,
insn
.
getResult
(),
one
,
zero
);
replaceInsn
(
block
,
i
,
ternary
);
}
}
}
private
static
void
replaceConst
(
ClassNode
parentClass
,
BlockNode
block
,
int
i
,
InsnNode
insn
)
{
FieldNode
f
;
if
(
insn
.
getType
()
==
InsnType
.
CONST_STR
)
{
String
s
=
((
ConstStringNode
)
insn
).
getString
();
f
=
parentClass
.
getConstField
(
s
);
}
else
if
(
insn
.
getType
()
==
InsnType
.
CONST_CLASS
)
{
ArgType
t
=
((
ConstClassNode
)
insn
).
getClsType
();
f
=
parentClass
.
getConstField
(
t
);
}
else
{
f
=
parentClass
.
getConstFieldByLiteralArg
((
LiteralArg
)
insn
.
getArg
(
0
));
}
if
(
f
!=
null
)
{
InsnNode
inode
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
inode
.
setResult
(
insn
.
getResult
());
replaceInsn
(
block
,
i
,
inode
);
}
}
private
static
void
processArith
(
ClassNode
parentClass
,
ArithNode
arithNode
)
{
if
(
arithNode
.
getArgsCount
()
!=
2
)
{
throw
new
JadxRuntimeException
(
"Invalid args count in insn: "
+
arithNode
);
}
InsnArg
litArg
=
arithNode
.
getArg
(
1
);
if
(
litArg
.
isLiteral
())
{
FieldNode
f
=
parentClass
.
getConstFieldByLiteralArg
((
LiteralArg
)
litArg
);
if
(
f
!=
null
)
{
InsnNode
fGet
=
new
IndexInsnNode
(
InsnType
.
SGET
,
f
.
getFieldInfo
(),
0
);
arithNode
.
replaceArg
(
litArg
,
InsnArg
.
wrapArg
(
fGet
));
}
}
}
private
static
boolean
checkArrSizes
(
MethodNode
mth
,
NewArrayNode
newArrInsn
,
FillArrayNode
fillArrInsn
)
{
int
dataSize
=
fillArrInsn
.
getSize
();
InsnArg
arrSizeArg
=
newArrInsn
.
getArg
(
0
);
...
...
@@ -197,6 +212,18 @@ public class ModVisitor extends AbstractVisitor {
return
false
;
}
private
static
void
removeRedundantCast
(
MethodNode
mth
,
BlockNode
block
,
int
i
,
IndexInsnNode
insn
)
{
InsnArg
castArg
=
insn
.
getArg
(
0
);
ArgType
castType
=
(
ArgType
)
insn
.
getIndex
();
if
(!
ArgType
.
isCastNeeded
(
mth
.
dex
(),
castArg
.
getType
(),
castType
)
||
isCastDuplicate
(
insn
))
{
InsnNode
insnNode
=
new
InsnNode
(
InsnType
.
MOVE
,
1
);
insnNode
.
setResult
(
insn
.
getResult
());
insnNode
.
addArg
(
castArg
);
replaceInsn
(
block
,
i
,
insnNode
);
}
}
private
static
boolean
isCastDuplicate
(
IndexInsnNode
castInsn
)
{
InsnArg
arg
=
castInsn
.
getArg
(
0
);
if
(
arg
.
isRegister
())
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java
浏览文件 @
f9f840fb
...
...
@@ -160,7 +160,8 @@ public class PrepareForCodeGen extends AbstractVisitor {
List
<
InsnNode
>
list
=
block
.
getInstructions
();
for
(
InsnNode
insn
:
list
)
{
if
(
insn
.
getType
()
==
InsnType
.
ARITH
&&
!
insn
.
contains
(
AFlag
.
DECLARE_VAR
))
{
// TODO: move this modify before ProcessVariable
&&
!
insn
.
contains
(
AFlag
.
ARITH_ONEARG
)
&&
!
insn
.
contains
(
AFlag
.
DECLARE_VAR
))
{
RegisterArg
res
=
insn
.
getResult
();
InsnArg
arg
=
insn
.
getArg
(
0
);
boolean
replace
=
false
;
...
...
@@ -171,6 +172,7 @@ public class PrepareForCodeGen extends AbstractVisitor {
replace
=
res
.
sameCodeVar
(
regArg
);
}
if
(
replace
)
{
insn
.
setResult
(
null
);
insn
.
add
(
AFlag
.
ARITH_ONEARG
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java
浏览文件 @
f9f840fb
...
...
@@ -4,7 +4,6 @@ import java.util.ArrayList;
import
java.util.Collections
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -24,7 +23,6 @@ import jadx.core.dex.instructions.InsnType;
import
jadx.core.dex.instructions.InvokeNode
;
import
jadx.core.dex.instructions.InvokeType
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.FieldArg
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnWrapArg
;
import
jadx.core.dex.instructions.args.LiteralArg
;
...
...
@@ -37,6 +35,7 @@ import jadx.core.dex.nodes.InsnNode;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
jadx.core.dex.visitors.shrink.CodeShrinkVisitor
;
import
jadx.core.utils.BlockUtils
;
import
jadx.core.utils.InsnList
;
import
jadx.core.utils.InsnRemover
;
...
...
@@ -51,12 +50,19 @@ public class SimplifyVisitor extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
boolean
changed
=
false
;
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
simplifyBlock
(
mth
,
block
);
if
(
simplifyBlock
(
mth
,
block
))
{
changed
=
true
;
}
}
if
(
changed
)
{
CodeShrinkVisitor
.
shrinkMethod
(
mth
);
}
}
private
static
void
simplifyBlock
(
MethodNode
mth
,
BlockNode
block
)
{
private
static
boolean
simplifyBlock
(
MethodNode
mth
,
BlockNode
block
)
{
boolean
changed
=
false
;
List
<
InsnNode
>
list
=
block
.
getInstructions
();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++)
{
InsnNode
insn
=
list
.
get
(
i
);
...
...
@@ -75,10 +81,12 @@ public class SimplifyVisitor extends AbstractVisitor {
if
(
list
.
size
()
<
insnCount
)
{
// some insns removed => restart block processing
simplifyBlock
(
mth
,
block
);
return
;
return
true
;
}
changed
=
true
;
}
}
return
changed
;
}
private
static
InsnNode
simplifyInsn
(
MethodNode
mth
,
BlockNode
block
,
InsnNode
insn
)
{
...
...
@@ -109,7 +117,7 @@ public class SimplifyVisitor extends AbstractVisitor {
case
IPUT:
case
SPUT:
return
convertFieldArith
(
mth
,
block
,
insn
);
return
convertFieldArith
(
mth
,
insn
);
case
CHECK_CAST:
return
processCast
(
mth
,
insn
);
...
...
@@ -404,9 +412,9 @@ public class SimplifyVisitor extends AbstractVisitor {
/**
* Convert field arith operation to arith instruction
* (IPUT
= ARITH (IGET, lit) -> ARITH (fieldArg
<op>= lit))
* (IPUT
(ARITH (IGET, lit)) -> ARITH ((IGET))
<op>= lit))
*/
private
static
ArithNode
convertFieldArith
(
MethodNode
mth
,
BlockNode
block
,
InsnNode
insn
)
{
private
static
ArithNode
convertFieldArith
(
MethodNode
mth
,
InsnNode
insn
)
{
InsnArg
arg
=
insn
.
getArg
(
0
);
if
(!
arg
.
isInsnWrap
())
{
return
null
;
...
...
@@ -428,49 +436,30 @@ public class SimplifyVisitor extends AbstractVisitor {
return
null
;
}
try
{
InsnArg
reg
=
null
;
if
(
getType
==
InsnType
.
IGET
)
{
reg
=
get
.
getArg
(
0
);
if
(
getType
==
InsnType
.
IGET
&&
insn
.
getType
()
==
InsnType
.
IPUT
)
{
InsnArg
reg
=
get
.
getArg
(
0
);
InsnArg
putReg
=
insn
.
getArg
(
1
);
if
(!
reg
.
equals
(
putReg
))
{
return
null
;
}
}
reg
=
inlineFieldGet
(
reg
,
block
,
get
,
insn
);
FieldArg
fArg
=
new
FieldArg
(
field
,
reg
);
InsnArg
fArg
=
InsnArg
.
wrapArg
(
get
);
if
(
insn
.
getType
()
==
InsnType
.
IPUT
)
{
InsnRemover
.
unbindArgUsage
(
mth
,
insn
.
getArg
(
1
));
}
if
(
wrapType
==
InsnType
.
ARITH
)
{
ArithNode
ar
=
(
ArithNode
)
wrap
;
return
new
ArithNode
(
ar
.
getOp
(),
fArg
,
ar
.
getArg
(
1
));
return
ArithNode
.
oneArgOp
(
ar
.
getOp
(),
fArg
,
ar
.
getArg
(
1
));
}
int
argsCount
=
wrap
.
getArgsCount
();
InsnNode
concat
=
new
InsnNode
(
InsnType
.
STR_CONCAT
,
argsCount
-
1
);
for
(
int
i
=
1
;
i
<
argsCount
;
i
++)
{
concat
.
addArg
(
wrap
.
getArg
(
i
));
}
return
new
ArithNode
(
ArithOp
.
ADD
,
fArg
,
InsnArg
.
wrapArg
(
concat
));
return
ArithNode
.
oneArgOp
(
ArithOp
.
ADD
,
fArg
,
InsnArg
.
wrapArg
(
concat
));
}
catch
(
Exception
e
)
{
LOG
.
debug
(
"Can't convert field arith insn: {}, mth: {}"
,
insn
,
mth
,
e
);
}
return
null
;
}
private
static
InsnArg
inlineFieldGet
(
@Nullable
InsnArg
arg
,
BlockNode
block
,
InsnNode
get
,
InsnNode
insn
)
{
if
(
arg
==
null
||
!
arg
.
isRegister
())
{
return
arg
;
}
RegisterArg
reg
=
(
RegisterArg
)
arg
;
InsnNode
assignInsn
=
reg
.
getAssignInsn
();
SSAVar
ssaVar
=
reg
.
getSVar
();
if
(
ssaVar
.
getUseCount
()
==
2
&&
!
ssaVar
.
isUsedInPhi
()
&&
assignInsn
!=
null
)
{
List
<
RegisterArg
>
useList
=
ssaVar
.
getUseList
();
if
(
useList
.
get
(
0
).
getParentInsn
()
==
get
&&
useList
.
get
(
1
).
getParentInsn
()
==
insn
)
{
InsnType
assignInsnType
=
assignInsn
.
getType
();
if
(
assignInsnType
==
InsnType
.
IGET
||
assignInsnType
==
InsnType
.
SGET
)
{
InsnList
.
remove
(
block
,
assignInsn
);
return
InsnArg
.
wrapArg
(
assignInsn
);
}
}
}
return
arg
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/shrink/ArgsInfo.java
浏览文件 @
f9f840fb
...
...
@@ -118,7 +118,7 @@ final class ArgsInfo {
return
false
;
}
RegisterArg
result
=
insn
.
getResult
();
if
(
result
==
null
||
result
.
isField
()
)
{
if
(
result
==
null
)
{
return
false
;
}
return
args
.
get
(
result
.
getRegNum
());
...
...
jadx-core/src/test/java/jadx/tests/integration/arith/TestArith3.java
浏览文件 @
f9f840fb
...
...
@@ -18,9 +18,9 @@ public class TestArith3 extends IntegrationTest {
public
void
test
(
byte
[]
buffer
)
{
int
n
=
((
buffer
[
3
]
&
255
)
+
4
)
+
((
buffer
[
2
]
&
15
)
<<
8
);
while
(
n
+
4
<
buffer
.
length
)
{
int
c
=
buffer
[
n
]
&
255
;
int
p
=
(
buffer
[
n
+
2
]
&
255
)
+
((
buffer
[
n
+
1
]
&
31
)
<<
8
);
int
len
=
(
buffer
[
n
+
4
]
&
255
)
+
((
buffer
[
n
+
3
]
&
15
)
<<
8
);
int
c
=
buffer
[
n
]
&
255
;
switch
(
c
)
{
case
27
:
this
.
vp
=
p
;
...
...
@@ -37,7 +37,7 @@ public class TestArith3 extends IntegrationTest {
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"while (n + 4 < buffer.length) {"
));
assertThat
(
code
,
containsOne
(
"n += len + 5;"
));
assertThat
(
code
,
containsOne
(
indent
()
+
"n += len + 5;"
));
assertThat
(
code
,
not
(
containsString
(
"; n += len + 5) {"
)));
assertThat
(
code
,
not
(
containsString
(
"default:"
)));
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录