Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
colcode
jadx
提交
e3606d1b
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,发现更多精彩内容 >>
提交
e3606d1b
编写于
1月 03, 2014
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
reformat code (force braces)
上级
ab593e3c
变更
65
隐藏空白更改
内联
并排
Showing
65 changed file
with
687 addition
and
419 deletion
+687
-419
jadx-core/src/main/java/jadx/api/JavaPackage.java
jadx-core/src/main/java/jadx/api/JavaPackage.java
+7
-4
jadx-core/src/main/java/jadx/core/Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+13
-6
jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
+2
-1
jadx-core/src/main/java/jadx/core/clsp/NClass.java
jadx-core/src/main/java/jadx/core/clsp/NClass.java
+7
-4
jadx-core/src/main/java/jadx/core/codegen/AnnotationGen.java
jadx-core/src/main/java/jadx/core/codegen/AnnotationGen.java
+32
-25
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+34
-28
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
+7
-4
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+20
-15
jadx-core/src/main/java/jadx/core/codegen/TypeGen.java
jadx-core/src/main/java/jadx/core/codegen/TypeGen.java
+7
-5
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
...core/src/main/java/jadx/core/dex/attributes/AttrNode.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeType.java
...src/main/java/jadx/core/dex/attributes/AttributeType.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/attributes/AttributesList.java
...rc/main/java/jadx/core/dex/attributes/AttributesList.java
+32
-20
jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java
...src/main/java/jadx/core/dex/attributes/BlockRegState.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/attributes/DeclareVariableAttr.java
...in/java/jadx/core/dex/attributes/DeclareVariableAttr.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/attributes/EnumClassAttr.java
...src/main/java/jadx/core/dex/attributes/EnumClassAttr.java
+3
-2
jadx-core/src/main/java/jadx/core/dex/attributes/JumpAttribute.java
...src/main/java/jadx/core/dex/attributes/JumpAttribute.java
+9
-3
jadx-core/src/main/java/jadx/core/dex/attributes/LoopAttr.java
...core/src/main/java/jadx/core/dex/attributes/LoopAttr.java
+4
-2
jadx-core/src/main/java/jadx/core/dex/info/AccessInfo.java
jadx-core/src/main/java/jadx/core/dex/info/AccessInfo.java
+36
-33
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
+7
-5
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
+15
-6
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
+18
-6
jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java
...src/main/java/jadx/core/dex/instructions/InsnDecoder.java
+16
-8
jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java
.../src/main/java/jadx/core/dex/instructions/InvokeNode.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
.../src/main/java/jadx/core/dex/instructions/SwitchNode.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/instructions/args/PrimitiveType.java
...n/java/jadx/core/dex/instructions/args/PrimitiveType.java
+6
-4
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+19
-8
jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java
...c/main/java/jadx/core/dex/instructions/args/TypedVar.java
+17
-6
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
+22
-8
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
+6
-2
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+27
-12
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+45
-21
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
+4
-2
jadx-core/src/main/java/jadx/core/dex/nodes/parser/AnnotationsParser.java
...in/java/jadx/core/dex/nodes/parser/AnnotationsParser.java
+0
-2
jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
...main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
+12
-9
jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java
...core/src/main/java/jadx/core/dex/regions/IfCondition.java
+4
-2
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
+4
-2
jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
...-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
+14
-10
jadx-core/src/main/java/jadx/core/dex/regions/Region.java
jadx-core/src/main/java/jadx/core/dex/regions/Region.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
...ore/src/main/java/jadx/core/dex/regions/SwitchRegion.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java
...rc/main/java/jadx/core/dex/trycatch/ExceptionHandler.java
+15
-5
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
...main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
+13
-10
jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraverser.java
.../src/main/java/jadx/core/dex/visitors/DepthTraverser.java
+4
-2
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
...src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
+20
-13
jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
...main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
+2
-2
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java
...ain/java/jadx/core/dex/visitors/regions/CheckRegions.java
+8
-5
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CleanRegions.java
...ain/java/jadx/core/dex/visitors/regions/CleanRegions.java
+4
-4
jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraverser.java
.../jadx/core/dex/visitors/regions/DepthRegionTraverser.java
+2
-1
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
...java/jadx/core/dex/visitors/regions/ProcessVariables.java
+8
-5
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
...va/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
+2
-2
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionStack.java
...main/java/jadx/core/dex/visitors/regions/RegionStack.java
+12
-7
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/FinishTypeResolver.java
...dx/core/dex/visitors/typeresolver/FinishTypeResolver.java
+16
-8
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/TypeResolver.java
...ava/jadx/core/dex/visitors/typeresolver/TypeResolver.java
+8
-5
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/PostTypeResolver.java
...re/dex/visitors/typeresolver/finish/PostTypeResolver.java
+12
-6
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/SelectTypeVisitor.java
...e/dex/visitors/typeresolver/finish/SelectTypeVisitor.java
+2
-1
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
+29
-22
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
+3
-2
jadx-core/src/main/java/jadx/core/utils/InsnUtils.java
jadx-core/src/main/java/jadx/core/utils/InsnUtils.java
+5
-4
jadx-core/src/main/java/jadx/core/utils/InstructionRemover.java
...ore/src/main/java/jadx/core/utils/InstructionRemover.java
+4
-2
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
+29
-19
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
+2
-2
jadx-core/src/main/java/jadx/core/utils/Utils.java
jadx-core/src/main/java/jadx/core/utils/Utils.java
+16
-12
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
+2
-2
jadx-core/src/test/java/jadx/tests/internal/TestStringBuilderElimination.java
...ava/jadx/tests/internal/TestStringBuilderElimination.java
+2
-2
jadx-core/src/test/java/jadx/tests/internal/TestSwitchLabels.java
...e/src/test/java/jadx/tests/internal/TestSwitchLabels.java
+1
-2
jadx-core/src/test/java/jadx/tests/internal/inline/TestInline3.java
...src/test/java/jadx/tests/internal/inline/TestInline3.java
+1
-1
未找到文件。
jadx-core/src/main/java/jadx/api/JavaPackage.java
浏览文件 @
e3606d1b
...
...
@@ -26,11 +26,14 @@ public final class JavaPackage implements Comparable<JavaPackage> {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
JavaPackage
that
=
(
JavaPackage
)
o
;
if
(!
name
.
equals
(
that
.
name
))
return
false
;
return
true
;
return
name
.
equals
(
that
.
name
);
}
@Override
...
...
jadx-core/src/main/java/jadx/core/Jadx.java
浏览文件 @
e3606d1b
...
...
@@ -37,10 +37,12 @@ public class Jadx {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Jadx
.
class
);
static
{
if
(
Consts
.
DEBUG
)
if
(
Consts
.
DEBUG
)
{
LOG
.
info
(
"debug enabled"
);
if
(
Jadx
.
class
.
desiredAssertionStatus
())
}
if
(
Jadx
.
class
.
desiredAssertionStatus
())
{
LOG
.
info
(
"assertions enabled"
);
}
}
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
IJadxArgs
args
,
File
outDir
)
{
...
...
@@ -52,8 +54,9 @@ public class Jadx {
passes
.
add
(
new
TypeResolver
());
if
(
args
.
isRawCFGOutput
())
if
(
args
.
isRawCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
,
true
));
}
passes
.
add
(
new
ConstInlinerVisitor
());
passes
.
add
(
new
FinishTypeResolver
());
...
...
@@ -61,8 +64,9 @@ public class Jadx {
passes
.
add
(
new
ModVisitor
());
passes
.
add
(
new
EnumVisitor
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
));
}
passes
.
add
(
new
RegionMakerVisitor
());
passes
.
add
(
new
PostRegionVisitor
());
...
...
@@ -71,8 +75,10 @@ public class Jadx {
passes
.
add
(
new
SimplifyVisitor
());
passes
.
add
(
new
ProcessVariables
());
passes
.
add
(
new
CheckRegions
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
{
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
true
));
}
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
ClassModifier
());
...
...
@@ -88,8 +94,9 @@ public class Jadx {
while
(
resources
.
hasMoreElements
())
{
Manifest
manifest
=
new
Manifest
(
resources
.
nextElement
().
openStream
());
String
ver
=
manifest
.
getMainAttributes
().
getValue
(
"jadx-version"
);
if
(
ver
!=
null
)
if
(
ver
!=
null
)
{
return
ver
;
}
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Can't get manifest file"
,
e
);
...
...
jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
浏览文件 @
e3606d1b
...
...
@@ -82,8 +82,9 @@ public class ClspGraph {
return
name
;
}
else
{
String
r
=
searchCommonParent
(
anc
,
p
);
if
(
r
!=
null
)
if
(
r
!=
null
)
{
return
r
;
}
}
}
return
null
;
...
...
jadx-core/src/main/java/jadx/core/clsp/NClass.java
浏览文件 @
e3606d1b
...
...
@@ -41,11 +41,14 @@ public class NClass {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
NClass
nClass
=
(
NClass
)
o
;
if
(!
name
.
equals
(
nClass
.
name
))
return
false
;
return
true
;
return
name
.
equals
(
nClass
.
name
);
}
@Override
...
...
jadx-core/src/main/java/jadx/core/codegen/AnnotationGen.java
浏览文件 @
e3606d1b
...
...
@@ -43,9 +43,9 @@ public class AnnotationGen {
public
void
addForParameter
(
CodeWriter
code
,
MethodParameters
paramsAnnotations
,
int
n
)
{
AnnotationsList
aList
=
paramsAnnotations
.
getParamList
().
get
(
n
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
;
}
for
(
Annotation
a
:
aList
.
getAll
())
{
code
.
add
(
formatAnnotation
(
a
));
code
.
add
(
' '
);
...
...
@@ -54,9 +54,9 @@ public class AnnotationGen {
private
void
add
(
IAttributeNode
node
,
CodeWriter
code
)
{
AnnotationsList
aList
=
(
AnnotationsList
)
node
.
getAttributes
().
get
(
AttributeType
.
ANNOTATION_LIST
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
;
}
for
(
Annotation
a
:
aList
.
getAll
())
{
String
aCls
=
a
.
getAnnotationClass
();
if
(
aCls
.
startsWith
(
Consts
.
DALVIK_ANNOTATION_PKG
))
{
...
...
@@ -86,8 +86,9 @@ public class AnnotationGen {
code
.
add
(
e
.
getKey
());
code
.
add
(
" = "
);
code
.
add
(
encValueToString
(
e
.
getValue
()));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
", "
);
}
}
}
code
.
add
(
')'
);
...
...
@@ -104,8 +105,9 @@ public class AnnotationGen {
for
(
Iterator
<
ArgType
>
it
=
((
List
<
ArgType
>)
exs
).
iterator
();
it
.
hasNext
();
)
{
ArgType
ex
=
it
.
next
();
code
.
add
(
TypeGen
.
translate
(
classGen
,
ex
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
", "
);
}
}
}
}
...
...
@@ -122,31 +124,39 @@ public class AnnotationGen {
// TODO: refactor this boilerplate code
@SuppressWarnings
(
"unchecked"
)
public
String
encValueToString
(
Object
val
)
{
if
(
val
==
null
)
if
(
val
==
null
)
{
return
"null"
;
if
(
val
instanceof
String
)
}
if
(
val
instanceof
String
)
{
return
StringUtils
.
unescapeString
((
String
)
val
);
if
(
val
instanceof
Integer
)
}
if
(
val
instanceof
Integer
)
{
return
TypeGen
.
formatInteger
((
Integer
)
val
);
if
(
val
instanceof
Character
)
}
if
(
val
instanceof
Character
)
{
return
StringUtils
.
unescapeChar
((
Character
)
val
);
if
(
val
instanceof
Boolean
)
}
if
(
val
instanceof
Boolean
)
{
return
Boolean
.
TRUE
.
equals
(
val
)
?
"true"
:
"false"
;
if
(
val
instanceof
Float
)
}
if
(
val
instanceof
Float
)
{
return
TypeGen
.
formatFloat
((
Float
)
val
);
if
(
val
instanceof
Double
)
}
if
(
val
instanceof
Double
)
{
return
TypeGen
.
formatDouble
((
Double
)
val
);
if
(
val
instanceof
Long
)
}
if
(
val
instanceof
Long
)
{
return
TypeGen
.
formatLong
((
Long
)
val
);
if
(
val
instanceof
Short
)
}
if
(
val
instanceof
Short
)
{
return
TypeGen
.
formatShort
((
Short
)
val
);
if
(
val
instanceof
Byte
)
}
if
(
val
instanceof
Byte
)
{
return
TypeGen
.
formatByte
((
Byte
)
val
);
if
(
val
instanceof
ArgType
)
}
if
(
val
instanceof
ArgType
)
{
return
TypeGen
.
translate
(
classGen
,
(
ArgType
)
val
)
+
".class"
;
}
if
(
val
instanceof
FieldInfo
)
{
// must be a static field
FieldInfo
field
=
(
FieldInfo
)
val
;
...
...
@@ -158,7 +168,6 @@ public class AnnotationGen {
return
classGen
.
useClass
(
field
.
getDeclClass
())
+
'.'
+
field
.
getName
();
}
}
if
(
val
instanceof
List
)
{
StringBuilder
str
=
new
StringBuilder
();
str
.
append
(
'{'
);
...
...
@@ -166,19 +175,17 @@ public class AnnotationGen {
for
(
Iterator
<
Object
>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
Object
obj
=
it
.
next
();
str
.
append
(
encValueToString
(
obj
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
str
.
append
(
", "
);
}
}
str
.
append
(
'}'
);
return
str
.
toString
();
}
if
(
val
instanceof
Annotation
)
{
return
formatAnnotation
((
Annotation
)
val
).
toString
();
}
// TODO: also can be method values
throw
new
JadxRuntimeException
(
"Can't decode value: "
+
val
+
" ("
+
val
.
getClass
()
+
")"
);
}
}
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
浏览文件 @
e3606d1b
...
...
@@ -90,12 +90,12 @@ public class ClassGen {
}
public
void
addClassCode
(
CodeWriter
code
)
throws
CodegenException
{
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
return
;
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
INCONSISTENT_CODE
))
}
if
(
cls
.
getAttributes
().
contains
(
AttributeFlag
.
INCONSISTENT_CODE
))
{
code
.
startLine
(
"// jadx: inconsistent code"
);
}
makeClassDeclaration
(
code
);
makeClassBody
(
code
);
code
.
newLine
();
...
...
@@ -113,8 +113,9 @@ public class ClassGen {
insertSourceFileInfo
(
clsCode
,
cls
);
clsCode
.
startLine
(
af
.
makeString
());
if
(
af
.
isInterface
())
{
if
(
af
.
isAnnotation
())
if
(
af
.
isAnnotation
())
{
clsCode
.
add
(
'@'
);
}
clsCode
.
add
(
"interface "
);
}
else
if
(
af
.
isEnum
())
{
clsCode
.
add
(
"enum "
);
...
...
@@ -134,28 +135,30 @@ public class ClassGen {
}
if
(
cls
.
getInterfaces
().
size
()
>
0
&&
!
af
.
isAnnotation
())
{
if
(
cls
.
getAccessFlags
().
isInterface
())
if
(
cls
.
getAccessFlags
().
isInterface
())
{
clsCode
.
add
(
"extends "
);
else
}
else
{
clsCode
.
add
(
"implements "
);
}
for
(
Iterator
<
ClassInfo
>
it
=
cls
.
getInterfaces
().
iterator
();
it
.
hasNext
();
)
{
ClassInfo
interf
=
it
.
next
();
clsCode
.
add
(
useClass
(
interf
));
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
clsCode
.
add
(
", "
);
}
}
if
(!
cls
.
getInterfaces
().
isEmpty
())
if
(!
cls
.
getInterfaces
().
isEmpty
())
{
clsCode
.
add
(
' '
);
}
}
clsCode
.
attachAnnotation
(
cls
);
}
public
boolean
makeGenericMap
(
CodeWriter
code
,
Map
<
ArgType
,
List
<
ArgType
>>
gmap
)
{
if
(
gmap
==
null
||
gmap
.
isEmpty
())
if
(
gmap
==
null
||
gmap
.
isEmpty
())
{
return
false
;
}
code
.
add
(
'<'
);
int
i
=
0
;
for
(
Entry
<
ArgType
,
List
<
ArgType
>>
e
:
gmap
.
entrySet
())
{
...
...
@@ -186,14 +189,15 @@ public class ClassGen {
CodeWriter
mthsCode
=
makeMethods
(
clsCode
,
cls
.
getMethods
());
CodeWriter
fieldsCode
=
makeFields
(
clsCode
,
cls
,
cls
.
getFields
());
clsCode
.
add
(
fieldsCode
);
if
(
fieldsCode
.
notEmpty
()
&&
mthsCode
.
notEmpty
())
if
(
fieldsCode
.
notEmpty
()
&&
mthsCode
.
notEmpty
())
{
clsCode
.
newLine
();
}
// insert inner classes code
if
(
cls
.
getInnerClasses
().
size
()
!=
0
)
{
clsCode
.
add
(
makeInnerClasses
(
cls
,
clsCode
.
getIndent
()));
if
(
mthsCode
.
notEmpty
())
if
(
mthsCode
.
notEmpty
())
{
clsCode
.
newLine
();
}
}
clsCode
.
add
(
mthsCode
);
clsCode
.
startLine
(
'}'
);
...
...
@@ -202,12 +206,11 @@ public class ClassGen {
private
CodeWriter
makeInnerClasses
(
ClassNode
cls
,
int
indent
)
throws
CodegenException
{
CodeWriter
innerClsCode
=
new
CodeWriter
(
indent
+
1
);
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
{
if
(
inCls
.
isAnonymous
())
continue
;
ClassGen
inClGen
=
new
ClassGen
(
inCls
,
parentGen
==
null
?
this
:
parentGen
,
fallback
);
inClGen
.
addClassCode
(
innerClsCode
);
imports
.
addAll
(
inClGen
.
getImports
());
if
(!
inCls
.
isAnonymous
())
{
ClassGen
inClGen
=
new
ClassGen
(
inCls
,
parentGen
==
null
?
this
:
parentGen
,
fallback
);
inClGen
.
addClassCode
(
innerClsCode
);
imports
.
addAll
(
inClGen
.
getImports
());
}
}
return
innerClsCode
;
}
...
...
@@ -276,26 +279,28 @@ public class ClassGen {
igen
=
new
InsnGen
(
mthGen
,
enumFields
.
getStaticMethod
(),
false
);
}
code
.
add
(
igen
.
arg
(
arg
));
if
(
aIt
.
hasNext
())
if
(
aIt
.
hasNext
())
{
code
.
add
(
", "
);
}
}
code
.
add
(
')'
);
}
if
(
f
.
getCls
()
!=
null
)
{
new
ClassGen
(
f
.
getCls
(),
this
,
fallback
).
makeClassBody
(
code
);
}
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
code
.
add
(
','
);
}
}
if
(
enumFields
.
getFields
().
isEmpty
())
if
(
enumFields
.
getFields
().
isEmpty
())
{
code
.
startLine
();
}
code
.
add
(
';'
);
code
.
newLine
();
}
for
(
FieldNode
f
:
fields
)
{
if
(
f
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
if
(
f
.
getAttributes
().
contains
(
AttributeFlag
.
DONT_GENERATE
))
{
continue
;
}
annotationGen
.
addForField
(
code
,
f
);
...
...
@@ -338,10 +343,11 @@ public class ClassGen {
sb
.
append
(
", "
);
}
ArgType
gt
=
generics
[
i
];
if
(
gt
.
isTypeKnown
())
if
(
gt
.
isTypeKnown
())
{
sb
.
append
(
TypeGen
.
translate
(
this
,
gt
));
else
}
else
{
sb
.
append
(
'?'
);
}
}
sb
.
append
(
'>'
);
return
sb
.
toString
();
...
...
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
浏览文件 @
e3606d1b
...
...
@@ -59,8 +59,9 @@ public class CodeWriter {
public
CodeWriter
startLine
(
int
ind
,
String
str
)
{
addLine
();
buf
.
append
(
indentStr
);
for
(
int
i
=
0
;
i
<
ind
;
i
++)
for
(
int
i
=
0
;
i
<
ind
;
i
++)
{
buf
.
append
(
INDENT
);
}
buf
.
append
(
str
);
return
this
;
}
...
...
@@ -209,10 +210,11 @@ public class CodeWriter {
if
(
name
.
length
()
>
MAX_FILENAME_LENGTH
)
{
int
dotIndex
=
name
.
indexOf
(
'.'
);
int
cutAt
=
MAX_FILENAME_LENGTH
-
name
.
length
()
+
dotIndex
-
1
;
if
(
cutAt
<=
0
)
if
(
cutAt
<=
0
)
{
name
=
name
.
substring
(
0
,
MAX_FILENAME_LENGTH
-
1
);
else
}
else
{
name
=
name
.
substring
(
0
,
cutAt
)
+
name
.
substring
(
dotIndex
);
}
file
=
new
File
(
file
.
getParentFile
(),
name
);
}
...
...
@@ -226,8 +228,9 @@ public class CodeWriter {
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Save file error"
,
e
);
}
finally
{
if
(
out
!=
null
)
if
(
out
!=
null
)
{
out
.
close
();
}
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
浏览文件 @
e3606d1b
...
...
@@ -127,9 +127,9 @@ public class MethodGen {
RegisterArg
arg
=
it
.
next
();
// add argument annotation
if
(
paramsAnnotation
!=
null
)
if
(
paramsAnnotation
!=
null
)
{
annotationGen
.
addForParameter
(
argsCode
,
paramsAnnotation
,
i
);
}
if
(!
it
.
hasNext
()
&&
mth
.
getAccessFlags
().
isVarArgs
())
{
// change last array argument to varargs
ArgType
type
=
arg
.
getType
();
...
...
@@ -148,8 +148,9 @@ public class MethodGen {
argsCode
.
add
(
makeArgName
(
arg
));
i
++;
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
argsCode
.
add
(
", "
);
}
}
return
argsCode
;
}
...
...
@@ -163,24 +164,27 @@ public class MethodGen {
String
name
=
arg
.
getTypedVar
().
getName
();
String
base
=
"r"
+
arg
.
getRegNum
();
if
(
fallback
)
{
if
(
name
!=
null
)
if
(
name
!=
null
)
{
return
base
+
"_"
+
name
;
else
}
else
{
return
base
;
}
}
else
{
if
(
name
!=
null
)
{
if
(
name
.
equals
(
"this"
))
if
(
name
.
equals
(
"this"
))
{
return
name
;
else
if
(
Consts
.
DEBUG
)
}
else
if
(
Consts
.
DEBUG
)
{
return
name
+
"_"
+
base
;
else
}
else
{
return
name
;
}
}
else
{
ArgType
type
=
arg
.
getType
();
if
(
type
.
isPrimitive
())
if
(
type
.
isPrimitive
())
{
return
base
+
type
.
getPrimitiveType
().
getShortName
().
toLowerCase
();
else
}
else
{
return
base
+
"_"
+
Utils
.
escape
(
TypeGen
.
translate
(
classGen
,
arg
.
getType
()));
}
}
}
}
...
...
@@ -193,9 +197,9 @@ public class MethodGen {
*/
public
String
assignArg
(
RegisterArg
arg
)
{
String
name
=
makeArgName
(
arg
);
if
(
varNames
.
add
(
name
)
||
fallback
)
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
getTypedVar
().
setName
(
name
);
return
name
;
...
...
@@ -203,9 +207,9 @@ public class MethodGen {
public
String
assignNamedArg
(
NamedArg
arg
)
{
String
name
=
arg
.
getName
();
if
(
varNames
.
add
(
name
)
||
fallback
)
if
(
varNames
.
add
(
name
)
||
fallback
)
{
return
name
;
}
name
=
getUniqVarName
(
name
);
arg
.
setName
(
name
);
return
name
;
...
...
@@ -298,8 +302,9 @@ public class MethodGen {
try
{
if
(
insnGen
.
makeInsn
(
insn
,
code
))
{
CatchAttr
catchAttr
=
(
CatchAttr
)
attrs
.
get
(
AttributeType
.
CATCH_BLOCK
);
if
(
catchAttr
!=
null
)
if
(
catchAttr
!=
null
)
{
code
.
add
(
"\t //"
+
catchAttr
);
}
}
}
catch
(
CodegenException
e
)
{
code
.
startLine
(
"// error: "
+
insn
);
...
...
jadx-core/src/main/java/jadx/core/codegen/TypeGen.java
浏览文件 @
e3606d1b
...
...
@@ -10,9 +10,9 @@ public class TypeGen {
public
static
String
translate
(
ClassGen
clsGen
,
ArgType
type
)
{
final
PrimitiveType
stype
=
type
.
getPrimitiveType
();
if
(
stype
==
null
)
if
(
stype
==
null
)
{
return
type
.
toString
();
}
if
(
stype
==
PrimitiveType
.
OBJECT
)
{
return
clsGen
.
useClass
(
type
);
}
...
...
@@ -69,8 +69,9 @@ public class TypeGen {
case
OBJECT:
case
ARRAY:
if
(
lit
!=
0
)
if
(
lit
!=
0
)
{
throw
new
JadxRuntimeException
(
"Wrong object literal: "
+
type
+
" = "
+
lit
);
}
return
"null"
;
default
:
...
...
@@ -100,8 +101,9 @@ public class TypeGen {
public
static
String
formatLong
(
long
lit
)
{
String
l
=
Long
.
toString
(
lit
);
if
(
lit
==
Long
.
MIN_VALUE
||
Math
.
abs
(
lit
)
>=
Integer
.
MAX_VALUE
)
if
(
lit
==
Long
.
MIN_VALUE
||
Math
.
abs
(
lit
)
>=
Integer
.
MAX_VALUE
)
{
l
+=
"L"
;
}
return
wrapNegNum
(
lit
<
0
,
l
);
}
...
...
@@ -109,6 +111,6 @@ public class TypeGen {
// if (lz)
// return "(" + str + ")";
// else
return
str
;
return
str
;
}
}
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
浏览文件 @
e3606d1b
...
...
@@ -6,8 +6,9 @@ public abstract class AttrNode implements IAttributeNode {
@Override
public
AttributesList
getAttributes
()
{
if
(
attributesList
==
null
)
if
(
attributesList
==
null
)
{
attributesList
=
new
AttributesList
();
}
return
attributesList
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttributeType.java
浏览文件 @
e3606d1b
...
...
@@ -38,8 +38,9 @@ public enum AttributeType {
AttributeType
[]
vals
=
AttributeType
.
values
();
for
(
int
i
=
0
;
i
<
vals
.
length
;
i
++)
{
AttributeType
type
=
vals
[
i
];
if
(
type
.
notUniq
())
if
(
type
.
notUniq
())
{
last
=
i
;
}
}
NOT_UNIQ_COUNT
=
last
+
1
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttributesList.java
浏览文件 @
e3606d1b
...
...
@@ -52,10 +52,11 @@ public final class AttributesList {
// Attributes
public
void
add
(
IAttribute
attr
)
{
if
(
attr
.
getType
().
isUniq
())
if
(
attr
.
getType
().
isUniq
())
{
uniqAttr
.
put
(
attr
.
getType
(),
attr
);
else
}
else
{
addMultiAttribute
(
attr
);
}
}
private
void
addMultiAttribute
(
IAttribute
attr
)
{
...
...
@@ -70,15 +71,17 @@ public final class AttributesList {
public
void
addAll
(
AttributesList
otherList
)
{
flags
.
addAll
(
otherList
.
flags
);
uniqAttr
.
putAll
(
otherList
.
uniqAttr
);
for
(
IAttribute
attr
:
otherList
.
attributes
)
for
(
IAttribute
attr
:
otherList
.
attributes
)
{
addMultiAttribute
(
attr
);
}
}
public
boolean
contains
(
AttributeType
type
)
{
if
(
type
.
isUniq
())
if
(
type
.
isUniq
())
{
return
uniqAttr
.
containsKey
(
type
);
else
}
else
{
return
getMultiCountInternal
(
type
)
!=
0
;
}
}
public
IAttribute
get
(
AttributeType
type
)
{
...
...
@@ -86,9 +89,11 @@ public final class AttributesList {
return
uniqAttr
.
get
(
type
);
}
else
{
if
(
getMultiCountInternal
(
type
)
!=
0
)
{
for
(
IAttribute
attr
:
attributes
)
if
(
attr
.
getType
()
==
type
)
for
(
IAttribute
attr
:
attributes
)
{
if
(
attr
.
getType
()
==
type
)
{
return
attr
;
}
}
}
return
null
;
}
...
...
@@ -104,9 +109,9 @@ public final class AttributesList {
public
Annotation
getAnnotation
(
String
cls
)
{
AnnotationsList
aList
=
(
AnnotationsList
)
get
(
AttributeType
.
ANNOTATION_LIST
);
if
(
aList
==
null
||
aList
.
size
()
==
0
)
if
(
aList
==
null
||
aList
.
size
()
==
0
)
{
return
null
;
}
return
aList
.
get
(
cls
);
}
...
...
@@ -119,8 +124,9 @@ public final class AttributesList {
}
else
{
List
<
IAttribute
>
attrs
=
new
ArrayList
<
IAttribute
>(
count
);
for
(
IAttribute
attr
:
attributes
)
{
if
(
attr
.
getType
()
==
type
)
if
(
attr
.
getType
()
==
type
)
{
attrs
.
add
(
attr
);
}
}
return
attrs
;
}
...
...
@@ -132,8 +138,9 @@ public final class AttributesList {
}
else
{
for
(
Iterator
<
IAttribute
>
it
=
attributes
.
iterator
();
it
.
hasNext
();
)
{
IAttribute
attr
=
it
.
next
();
if
(
attr
.
getType
()
==
type
)
if
(
attr
.
getType
()
==
type
)
{
it
.
remove
();
}
}
attrCount
[
type
.
ordinal
()]
=
0
;
}
...
...
@@ -143,11 +150,13 @@ public final class AttributesList {
AttributeType
type
=
attr
.
getType
();
if
(
type
.
isUniq
())
{
IAttribute
a
=
uniqAttr
.
get
(
type
);
if
(
a
==
attr
)
if
(
a
==
attr
)
{
uniqAttr
.
remove
(
type
);
}
}
else
{
if
(
getMultiCountInternal
(
type
)
==
0
)
if
(
getMultiCountInternal
(
type
)
==
0
)
{
return
;
}
for
(
Iterator
<
IAttribute
>
it
=
attributes
.
iterator
();
it
.
hasNext
();
)
{
IAttribute
a
=
it
.
next
();
...
...
@@ -168,25 +177,28 @@ public final class AttributesList {
public
List
<
String
>
getAttributeStrings
()
{
int
size
=
flags
.
size
()
+
uniqAttr
.
size
()
+
attributes
.
size
();
if
(
size
==
0
)
if
(
size
==
0
)
{
return
Collections
.
emptyList
();
}
List
<
String
>
list
=
new
ArrayList
<
String
>(
size
);
for
(
AttributeFlag
a
:
flags
)
for
(
AttributeFlag
a
:
flags
)
{
list
.
add
(
a
.
toString
());
for
(
IAttribute
a
:
uniqAttr
.
values
())
}
for
(
IAttribute
a
:
uniqAttr
.
values
())
{
list
.
add
(
a
.
toString
());
for
(
IAttribute
a
:
attributes
)
}
for
(
IAttribute
a
:
attributes
)
{
list
.
add
(
a
.
toString
());
}
return
list
;
}
@Override
public
String
toString
()
{
List
<
String
>
list
=
getAttributeStrings
();
if
(
list
.
isEmpty
())
if
(
list
.
isEmpty
())
{
return
""
;
}
return
"A:{"
+
Utils
.
listToString
(
list
)
+
"}"
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/BlockRegState.java
浏览文件 @
e3606d1b
...
...
@@ -45,8 +45,9 @@ public final class BlockRegState {
StringBuilder
str
=
new
StringBuilder
();
for
(
RegisterArg
reg
:
regs
)
{
if
(
reg
.
getTypedVar
()
!=
null
)
{
if
(
str
.
length
()
!=
0
)
if
(
str
.
length
()
!=
0
)
{
str
.
append
(
", "
);
}
str
.
append
(
reg
.
toString
());
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/DeclareVariableAttr.java
浏览文件 @
e3606d1b
...
...
@@ -24,8 +24,9 @@ public class DeclareVariableAttr implements IAttribute {
public
void
addVar
(
RegisterArg
arg
)
{
int
i
;
if
((
i
=
vars
.
indexOf
(
arg
))
!=
-
1
)
{
if
(
vars
.
get
(
i
).
getType
().
equals
(
arg
.
getType
()))
if
(
vars
.
get
(
i
).
getType
().
equals
(
arg
.
getType
()))
{
return
;
}
}
vars
.
add
(
arg
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/EnumClassAttr.java
浏览文件 @
e3606d1b
...
...
@@ -18,10 +18,11 @@ public class EnumClassAttr implements IAttribute {
public
EnumField
(
String
name
,
int
argsCount
)
{
this
.
name
=
name
;
if
(
argsCount
!=
0
)
if
(
argsCount
!=
0
)
{
this
.
args
=
new
ArrayList
<
InsnArg
>(
argsCount
);
else
}
else
{
this
.
args
=
Collections
.
emptyList
();
}
}
public
String
getName
()
{
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/JumpAttribute.java
浏览文件 @
e3606d1b
...
...
@@ -41,9 +41,15 @@ public class JumpAttribute implements IAttribute {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
JumpAttribute
other
=
(
JumpAttribute
)
obj
;
return
dest
==
other
.
dest
&&
src
==
other
.
src
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/LoopAttr.java
浏览文件 @
e3606d1b
...
...
@@ -45,9 +45,11 @@ public class LoopAttr implements IAttribute {
Set
<
BlockNode
>
inloop
=
getLoopBlocks
();
for
(
BlockNode
block
:
inloop
)
{
// exit: successor node not from this loop, (don't change to getCleanSuccessors)
for
(
BlockNode
s
:
block
.
getSuccessors
())
if
(!
inloop
.
contains
(
s
)
&&
!
s
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
for
(
BlockNode
s
:
block
.
getSuccessors
())
{
if
(!
inloop
.
contains
(
s
)
&&
!
s
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
nodes
.
add
(
block
);
}
}
}
return
nodes
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/info/AccessInfo.java
浏览文件 @
e3606d1b
...
...
@@ -24,10 +24,11 @@ public class AccessInfo {
}
public
AccessInfo
remove
(
int
flag
)
{
if
(
containsFlag
(
flag
))
if
(
containsFlag
(
flag
))
{
return
new
AccessInfo
(
accFlags
-
flag
,
type
);
else
}
else
{
return
this
;
}
}
public
AccessInfo
getVisibility
()
{
...
...
@@ -111,71 +112,73 @@ public class AccessInfo {
public
String
makeString
()
{
StringBuilder
code
=
new
StringBuilder
();
if
(
isPublic
())
if
(
isPublic
())
{
code
.
append
(
"public "
);
if
(
isPrivate
())
}
if
(
isPrivate
())
{
code
.
append
(
"private "
);
if
(
isProtected
())
}
if
(
isProtected
())
{
code
.
append
(
"protected "
);
if
(
isStatic
())
}
if
(
isStatic
())
{
code
.
append
(
"static "
);
if
(
isFinal
())
}
if
(
isFinal
())
{
code
.
append
(
"final "
);
if
(
isAbstract
())
}
if
(
isAbstract
())
{
code
.
append
(
"abstract "
);
if
(
isNative
())
}
if
(
isNative
())
{
code
.
append
(
"native "
);
}
switch
(
type
)
{
case
METHOD:
if
(
isSynchronized
())
if
(
isSynchronized
())
{
code
.
append
(
"synchronized "
);
if
(
isBridge
())
}
if
(
isBridge
())
{
code
.
append
(
"/* bridge */ "
);
}
if
(
Consts
.
DEBUG
)
{
if
(
isVarArgs
())
if
(
isVarArgs
())
{
code
.
append
(
"/* varargs */ "
);
}
}
break
;
case
FIELD:
if
(
isVolatile
())
if
(
isVolatile
())
{
code
.
append
(
"volatile "
);
if
(
isTransient
())
}
if
(
isTransient
())
{
code
.
append
(
"transient "
);
}
break
;
case
CLASS:
if
((
accFlags
&
AccessFlags
.
ACC_STRICT
)
!=
0
)
if
((
accFlags
&
AccessFlags
.
ACC_STRICT
)
!=
0
)
{
code
.
append
(
"strict "
);
}
if
(
Consts
.
DEBUG
)
{
if
((
accFlags
&
AccessFlags
.
ACC_SUPER
)
!=
0
)
if
((
accFlags
&
AccessFlags
.
ACC_SUPER
)
!=
0
)
{
code
.
append
(
"/* super */ "
);
if
((
accFlags
&
AccessFlags
.
ACC_ENUM
)
!=
0
)
}
if
((
accFlags
&
AccessFlags
.
ACC_ENUM
)
!=
0
)
{
code
.
append
(
"/* enum */ "
);
}
}
break
;
}
if
(
isSynthetic
())
if
(
isSynthetic
())
{
code
.
append
(
"/* synthetic */ "
);
}
return
code
.
toString
();
}
public
String
rawString
()
{
switch
(
type
){
switch
(
type
)
{
case
CLASS:
return
AccessFlags
.
classString
(
accFlags
);
case
FIELD:
...
...
jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java
浏览文件 @
e3606d1b
...
...
@@ -14,13 +14,13 @@ public final class ClassInfo {
private
static
final
Map
<
ArgType
,
ClassInfo
>
CLASSINFO_CACHE
=
new
WeakHashMap
<
ArgType
,
ClassInfo
>();
public
static
ClassInfo
fromDex
(
DexNode
dex
,
int
clsIndex
)
{
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
if
(
clsIndex
==
DexNode
.
NO_INDEX
)
{
return
null
;
}
ArgType
type
=
dex
.
getType
(
clsIndex
);
if
(
type
.
isArray
())
if
(
type
.
isArray
())
{
type
=
ArgType
.
OBJECT
;
}
return
fromType
(
type
);
}
...
...
@@ -153,7 +153,9 @@ public final class ClassInfo {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
instanceof
ClassInfo
)
{
ClassInfo
other
=
(
ClassInfo
)
obj
;
return
this
.
getFullName
().
equals
(
other
.
getFullName
());
...
...
jadx-core/src/main/java/jadx/core/dex/info/FieldInfo.java
浏览文件 @
e3606d1b
...
...
@@ -41,13 +41,22 @@ public class FieldInfo {
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
return
true
;
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
return
false
;
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
FieldInfo
fieldInfo
=
(
FieldInfo
)
o
;
if
(!
name
.
equals
(
fieldInfo
.
name
))
return
false
;
if
(!
type
.
equals
(
fieldInfo
.
type
))
return
false
;
if
(!
declClass
.
equals
(
fieldInfo
.
declClass
))
return
false
;
if
(!
name
.
equals
(
fieldInfo
.
name
))
{
return
false
;
}
if
(!
type
.
equals
(
fieldInfo
.
type
))
{
return
false
;
}
if
(!
declClass
.
equals
(
fieldInfo
.
declClass
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/info/MethodInfo.java
浏览文件 @
e3606d1b
...
...
@@ -98,13 +98,25 @@ public final class MethodInfo {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
MethodInfo
other
=
(
MethodInfo
)
obj
;
if
(!
shortId
.
equals
(
other
.
shortId
))
return
false
;
if
(!
retType
.
equals
(
other
.
retType
))
return
false
;
if
(!
declClass
.
equals
(
other
.
declClass
))
return
false
;
if
(!
shortId
.
equals
(
other
.
shortId
))
{
return
false
;
}
if
(!
retType
.
equals
(
other
.
retType
))
{
return
false
;
}
if
(!
declClass
.
equals
(
other
.
declClass
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/InsnDecoder.java
浏览文件 @
e3606d1b
...
...
@@ -578,14 +578,16 @@ public class InsnDecoder {
targets
=
ps
.
getTargets
();
keys
=
new
Object
[
targets
.
length
];
int
k
=
ps
.
getFirstKey
();
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
keys
[
i
]
=
k
++;
}
}
else
{
SparseSwitchPayloadDecodedInstruction
ss
=
(
SparseSwitchPayloadDecodedInstruction
)
payload
;
targets
=
ss
.
getTargets
();
keys
=
new
Object
[
targets
.
length
];
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
for
(
int
i
=
0
;
i
<
keys
.
length
;
i
++)
{
keys
[
i
]
=
ss
.
getKeys
()[
i
];
}
}
// convert from relative to absolute offsets
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
...
...
@@ -612,8 +614,9 @@ public class InsnDecoder {
r
++;
}
}
else
{
for
(
int
i
=
0
;
i
<
insn
.
getRegisterCount
();
i
++)
for
(
int
i
=
0
;
i
<
insn
.
getRegisterCount
();
i
++)
{
regs
[
i
]
=
InsnArg
.
reg
(
insn
,
i
,
elType
);
}
}
return
insn
(
InsnType
.
FILLED_NEW_ARRAY
,
resReg
==
-
1
?
null
:
InsnArg
.
reg
(
resReg
,
arrType
),
...
...
@@ -689,8 +692,9 @@ public class InsnDecoder {
InsnNode
node
=
new
InsnNode
(
type
,
args
==
null
?
0
:
args
.
length
);
node
.
setResult
(
res
);
if
(
args
!=
null
)
{
for
(
InsnArg
arg
:
args
)
for
(
InsnArg
arg
:
args
)
{
node
.
addArg
(
arg
);
}
}
return
node
;
}
...
...
@@ -711,19 +715,23 @@ public class InsnDecoder {
public
static
int
getPrevInsnOffset
(
Object
[]
insnArr
,
int
offset
)
{
int
i
=
offset
-
1
;
while
(
i
>=
0
&&
insnArr
[
i
]
==
null
)
while
(
i
>=
0
&&
insnArr
[
i
]
==
null
)
{
i
--;
if
(
i
<
0
)
}
if
(
i
<
0
)
{
return
-
1
;
}
return
i
;
}
public
static
int
getNextInsnOffset
(
Object
[]
insnArr
,
int
offset
)
{
int
i
=
offset
+
1
;
while
(
i
<
insnArr
.
length
&&
insnArr
[
i
]
==
null
)
while
(
i
<
insnArr
.
length
&&
insnArr
[
i
]
==
null
)
{
i
++;
if
(
i
>=
insnArr
.
length
)
}
if
(
i
>=
insnArr
.
length
)
{
return
-
1
;
}
return
i
;
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/InvokeNode.java
浏览文件 @
e3606d1b
...
...
@@ -19,8 +19,9 @@ public class InvokeNode extends InsnNode {
this
.
mth
=
mth
;
this
.
type
=
type
;
if
(
resReg
>=
0
)
if
(
resReg
>=
0
)
{
setResult
(
InsnArg
.
reg
(
resReg
,
mth
.
getReturnType
()));
}
int
k
=
isRange
?
insn
.
getA
()
:
0
;
if
(
type
!=
InvokeType
.
STATIC
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
浏览文件 @
e3606d1b
...
...
@@ -42,8 +42,9 @@ public class SwitchNode extends InsnNode {
targ
.
append
(
'['
);
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
targ
.
append
(
InsnUtils
.
formatOffset
(
targets
[
i
]));
if
(
i
<
targets
.
length
-
1
)
if
(
i
<
targets
.
length
-
1
)
{
targ
.
append
(
", "
);
}
}
targ
.
append
(
']'
);
return
super
.
toString
()
+
" k:"
+
Arrays
.
toString
(
keys
)
+
" t:"
+
targ
;
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/PrimitiveType.java
浏览文件 @
e3606d1b
...
...
@@ -30,17 +30,19 @@ public enum PrimitiveType {
}
public
static
PrimitiveType
getWidest
(
PrimitiveType
a
,
PrimitiveType
b
)
{
if
(
a
.
ordinal
()
>
b
.
ordinal
())
if
(
a
.
ordinal
()
>
b
.
ordinal
())
{
return
a
;
else
}
else
{
return
b
;
}
}
public
static
PrimitiveType
getSmaller
(
PrimitiveType
a
,
PrimitiveType
b
)
{
if
(
a
.
ordinal
()
<
b
.
ordinal
())
if
(
a
.
ordinal
()
<
b
.
ordinal
())
{
return
a
;
else
}
else
{
return
b
;
}
}
@Override
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
浏览文件 @
e3606d1b
...
...
@@ -40,12 +40,13 @@ public class RegisterArg extends InsnArg {
public
InsnNode
getAssignInsn
()
{
for
(
InsnArg
arg
:
getTypedVar
().
getUseList
())
{
InsnNode
assignInsn
=
arg
.
getParentInsn
();
if
(
assignInsn
==
null
)
if
(
assignInsn
==
null
)
{
// assign as function argument
return
null
;
else
if
(
assignInsn
.
getResult
()
!=
null
&&
assignInsn
.
getResult
().
getRegNum
()
==
regNum
)
}
else
if
(
assignInsn
.
getResult
()
!=
null
&&
assignInsn
.
getResult
().
getRegNum
()
==
regNum
)
{
return
assignInsn
;
}
}
return
null
;
}
...
...
@@ -109,12 +110,22 @@ public class RegisterArg extends InsnArg {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
RegisterArg
other
=
(
RegisterArg
)
obj
;
if
(
regNum
!=
other
.
regNum
)
return
false
;
if
(!
typedVar
.
equals
(
other
.
typedVar
))
return
false
;
if
(
regNum
!=
other
.
regNum
)
{
return
false
;
}
if
(!
typedVar
.
equals
(
other
.
typedVar
))
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/args/TypedVar.java
浏览文件 @
e3606d1b
...
...
@@ -70,13 +70,23 @@ public class TypedVar {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(!(
obj
instanceof
TypedVar
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(!(
obj
instanceof
TypedVar
))
{
return
false
;
}
TypedVar
other
=
(
TypedVar
)
obj
;
if
(!
type
.
equals
(
other
.
type
))
return
false
;
if
(!
type
.
equals
(
other
.
type
))
{
return
false
;
}
if
(
name
==
null
)
{
if
(
other
.
name
!=
null
)
return
false
;
if
(
other
.
name
!=
null
)
{
return
false
;
}
}
else
if
(!
name
.
equals
(
other
.
name
))
{
return
false
;
}
...
...
@@ -86,8 +96,9 @@ public class TypedVar {
@Override
public
String
toString
()
{
StringBuilder
sb
=
new
StringBuilder
();
if
(
name
!=
null
)
if
(
name
!=
null
)
{
sb
.
append
(
'\''
).
append
(
name
).
append
(
"' "
);
}
sb
.
append
(
type
);
return
sb
.
toString
();
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
浏览文件 @
e3606d1b
...
...
@@ -72,15 +72,17 @@ public class BlockNode extends AttrNode implements IBlock {
LoopAttr
loop
=
(
LoopAttr
)
block
.
getAttributes
().
get
(
AttributeType
.
LOOP
);
if
(
loop
==
null
)
{
for
(
BlockNode
b
:
sucList
)
{
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
nodes
.
add
(
b
);
}
}
}
else
{
for
(
BlockNode
b
:
sucList
)
{
if
(!
b
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
// don't follow back edge
if
(
loop
.
getStart
()
==
b
&&
loop
.
getEnd
()
==
block
)
if
(
loop
.
getStart
()
==
b
&&
loop
.
getEnd
()
==
block
)
{
continue
;
}
nodes
.
add
(
b
);
}
}
...
...
@@ -153,13 +155,25 @@ public class BlockNode extends AttrNode implements IBlock {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
hashCode
()
!=
obj
.
hashCode
())
return
false
;
if
(!(
obj
instanceof
BlockNode
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
hashCode
()
!=
obj
.
hashCode
())
{
return
false
;
}
if
(!(
obj
instanceof
BlockNode
))
{
return
false
;
}
BlockNode
other
=
(
BlockNode
)
obj
;
if
(
id
!=
other
.
id
)
return
false
;
if
(
startOffset
!=
other
.
startOffset
)
return
false
;
if
(
id
!=
other
.
id
)
{
return
false
;
}
if
(
startOffset
!=
other
.
startOffset
)
{
return
false
;
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/FieldNode.java
浏览文件 @
e3606d1b
...
...
@@ -48,8 +48,12 @@ public class FieldNode extends LineAttrNode {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
FieldNode
other
=
(
FieldNode
)
obj
;
return
fieldInfo
.
equals
(
other
.
fieldInfo
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
浏览文件 @
e3606d1b
...
...
@@ -32,15 +32,17 @@ public class InsnNode extends LineAttrNode {
this
.
insnType
=
type
;
this
.
offset
=
-
1
;
if
(
argsCount
==
0
)
if
(
argsCount
==
0
)
{
this
.
arguments
=
Collections
.
emptyList
();
else
}
else
{
this
.
arguments
=
new
ArrayList
<
InsnArg
>(
argsCount
);
}
}
public
void
setResult
(
RegisterArg
res
)
{
if
(
res
!=
null
)
if
(
res
!=
null
)
{
res
.
setParentInsn
(
this
);
}
this
.
result
=
res
;
}
...
...
@@ -71,8 +73,9 @@ public class InsnNode extends LineAttrNode {
public
boolean
containsArg
(
RegisterArg
arg
)
{
for
(
InsnArg
a
:
arguments
)
{
if
(
a
==
arg
||
(
a
.
isRegister
()
&&
((
RegisterArg
)
a
).
getRegNum
()
==
arg
.
getRegNum
()))
if
(
a
==
arg
||
(
a
.
isRegister
()
&&
((
RegisterArg
)
a
).
getRegNum
()
==
arg
.
getRegNum
()))
{
return
true
;
}
}
return
false
;
}
...
...
@@ -92,8 +95,9 @@ public class InsnNode extends LineAttrNode {
setArg
(
i
,
to
);
return
true
;
}
else
if
(
arg
.
isInsnWrap
())
{
if
(((
InsnWrapArg
)
arg
).
getWrapInsn
().
replaceArg
(
from
,
to
))
if
(((
InsnWrapArg
)
arg
).
getWrapInsn
().
replaceArg
(
from
,
to
))
{
return
true
;
}
}
}
return
false
;
...
...
@@ -176,14 +180,25 @@ public class InsnNode extends LineAttrNode {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
hashCode
()
!=
obj
.
hashCode
())
return
false
;
if
(!(
obj
instanceof
InsnNode
))
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
hashCode
()
!=
obj
.
hashCode
())
{
return
false
;
}
if
(!(
obj
instanceof
InsnNode
))
{
return
false
;
}
InsnNode
other
=
(
InsnNode
)
obj
;
if
(
insnType
!=
other
.
insnType
)
return
false
;
if
(
arguments
.
size
()
!=
other
.
arguments
.
size
())
return
false
;
if
(
insnType
!=
other
.
insnType
)
{
return
false
;
}
if
(
arguments
.
size
()
!=
other
.
arguments
.
size
())
{
return
false
;
}
// TODO !!! finish equals
return
true
;
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
浏览文件 @
e3606d1b
...
...
@@ -90,8 +90,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
InsnNode
[]
insnByOffset
=
decoder
.
run
();
instructions
=
new
ArrayList
<
InsnNode
>();
for
(
InsnNode
insn
:
insnByOffset
)
{
if
(
insn
!=
null
)
if
(
insn
!=
null
)
{
instructions
.
add
(
insn
);
}
}
((
ArrayList
<
InsnNode
>)
instructions
).
trimToSize
();
...
...
@@ -127,18 +128,23 @@ public class MethodNode extends LineAttrNode implements ILoadable {
if
(
noCode
)
{
return
;
}
if
(
instructions
!=
null
)
instructions
.
clear
();
if
(
instructions
!=
null
)
{
instructions
.
clear
();
}
blocks
=
null
;
exitBlocks
=
null
;
if
(
exceptionHandlers
!=
null
)
exceptionHandlers
.
clear
();
if
(
exceptionHandlers
!=
null
)
{
exceptionHandlers
.
clear
();
}
noCode
=
true
;
}
@SuppressWarnings
(
"unchecked"
)
private
boolean
parseSignature
()
{
Annotation
a
=
getAttributes
().
getAnnotation
(
Consts
.
DALVIK_SIGNATURE
);
if
(
a
==
null
)
if
(
a
==
null
)
{
return
false
;
}
String
sign
=
Utils
.
mergeSignature
((
List
<
String
>)
a
.
getDefaultValue
());
...
...
@@ -162,8 +168,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
List
<
ArgType
>
argsTypes
=
ArgType
.
parseSignatureList
(
argsTypesStr
);
if
(
argsTypes
==
null
)
if
(
argsTypes
==
null
)
{
return
false
;
}
List
<
ArgType
>
mthArgs
=
mthInfo
.
getArgumentsTypes
();
if
(
argsTypes
.
size
()
!=
mthArgs
.
size
())
{
...
...
@@ -197,8 +204,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
pos
=
1
;
}
else
{
pos
=
regsCount
;
for
(
ArgType
arg
:
args
)
for
(
ArgType
arg
:
args
)
{
pos
-=
arg
.
getRegCount
();
}
}
if
(
accFlags
.
isStatic
())
{
thisArg
=
null
;
...
...
@@ -289,11 +297,15 @@ public class MethodNode extends LineAttrNode implements ILoadable {
// resolve nested try blocks:
// inner block contains all handlers from outer block => remove these handlers from inner block
// each handler must be only in one try/catch block
for
(
TryCatchBlock
ct1
:
catches
)
for
(
TryCatchBlock
ct2
:
catches
)
if
(
ct1
!=
ct2
&&
ct2
.
getHandlers
().
containsAll
(
ct1
.
getHandlers
()))
for
(
ExceptionHandler
h
:
ct1
.
getHandlers
())
for
(
TryCatchBlock
ct1
:
catches
)
{
for
(
TryCatchBlock
ct2
:
catches
)
{
if
(
ct1
!=
ct2
&&
ct2
.
getHandlers
().
containsAll
(
ct1
.
getHandlers
()))
{
for
(
ExceptionHandler
h
:
ct1
.
getHandlers
())
{
ct2
.
removeHandler
(
this
,
h
);
}
}
}
}
}
// attach EXC_HANDLER attributes to instructions
...
...
@@ -319,8 +331,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
block
.
addInsn
(
insnByOffset
[
offset
]);
offset
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
}
if
(
insnByOffset
[
end
]
!=
null
)
if
(
insnByOffset
[
end
]
!=
null
)
{
insnByOffset
[
end
].
getAttributes
().
add
(
AttributeFlag
.
TRY_LEAVE
);
}
}
}
...
...
@@ -335,15 +348,17 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
// default case
int
next
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
if
(
next
!=
-
1
)
if
(
next
!=
-
1
)
{
addJump
(
insnByOffset
,
offset
,
next
);
}
break
;
}
case
IF:
int
next
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
if
(
next
!=
-
1
)
if
(
next
!=
-
1
)
{
addJump
(
insnByOffset
,
offset
,
next
);
}
addJump
(
insnByOffset
,
offset
,
((
IfNode
)
insn
).
getTarget
());
break
;
...
...
@@ -363,10 +378,11 @@ public class MethodNode extends LineAttrNode implements ILoadable {
public
String
getName
()
{
String
name
=
mthInfo
.
getName
();
if
(
name
.
equals
(
parentClass
.
getShortName
()))
if
(
name
.
equals
(
parentClass
.
getShortName
()))
{
return
name
+
"_"
;
else
}
else
{
return
name
;
}
}
public
ClassNode
getParentClass
()
{
...
...
@@ -397,8 +413,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
blocks
=
Collections
.
unmodifiableList
(
blocks
);
exitBlocks
=
Collections
.
unmodifiableList
(
exitBlocks
);
for
(
BlockNode
block
:
blocks
)
for
(
BlockNode
block
:
blocks
)
{
block
.
lock
();
}
}
public
List
<
BlockNode
>
getBasicBlocks
()
{
...
...
@@ -430,8 +447,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
public
LoopAttr
getLoopForBlock
(
BlockNode
block
)
{
for
(
LoopAttr
loop
:
loops
)
{
if
(
loop
.
getLoopBlocks
().
contains
(
block
))
if
(
loop
.
getLoopBlocks
().
contains
(
block
))
{
return
loop
;
}
}
return
null
;
}
...
...
@@ -445,8 +463,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
exceptionHandlers
=
new
ArrayList
<
ExceptionHandler
>(
2
);
}
else
{
for
(
ExceptionHandler
h
:
exceptionHandlers
)
{
if
(
h
==
handler
||
h
.
getHandleOffset
()
==
handler
.
getHandleOffset
())
if
(
h
==
handler
||
h
.
getHandleOffset
()
==
handler
.
getHandleOffset
())
{
return
h
;
}
}
}
exceptionHandlers
.
add
(
handler
);
...
...
@@ -471,8 +490,9 @@ public class MethodNode extends LineAttrNode implements ILoadable {
for
(
MethodNode
method
:
methods
)
{
if
(
this
!=
method
&&
method
.
getName
().
equals
(
name
)
&&
method
.
mthInfo
.
getArgumentsTypes
().
size
()
==
argsCount
)
&&
method
.
mthInfo
.
getArgumentsTypes
().
size
()
==
argsCount
)
{
return
true
;
}
}
return
false
;
}
...
...
@@ -508,8 +528,12 @@ public class MethodNode extends LineAttrNode implements ILoadable {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
||
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
MethodNode
other
=
(
MethodNode
)
obj
;
return
mthInfo
.
equals
(
other
.
mthInfo
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
浏览文件 @
e3606d1b
...
...
@@ -59,8 +59,9 @@ public class RootNode {
// move inner classes
List
<
ClassNode
>
inner
=
new
ArrayList
<
ClassNode
>();
for
(
ClassNode
cls
:
classes
)
{
if
(
cls
.
getClassInfo
().
isInner
())
if
(
cls
.
getClassInfo
().
isInner
())
{
inner
.
add
(
cls
);
}
}
for
(
ClassNode
cls
:
inner
)
{
ClassNode
parent
=
resolveClass
(
cls
.
getClassInfo
().
getParentClass
());
...
...
@@ -81,8 +82,9 @@ public class RootNode {
if
(
includeInner
)
{
classes
.
add
(
cls
);
}
else
{
if
(!
cls
.
getClassInfo
().
isInner
())
if
(!
cls
.
getClassInfo
().
isInner
())
{
classes
.
add
(
cls
);
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/AnnotationsParser.java
浏览文件 @
e3606d1b
...
...
@@ -61,8 +61,6 @@ public class AnnotationsParser {
private
AnnotationsList
readAnnotationSet
(
int
offset
)
throws
DecodeException
{
Section
section
=
dex
.
openSection
(
offset
);
int
size
=
section
.
readInt
();
if
(
size
>
100
)
section
.
toString
();
List
<
Annotation
>
list
=
new
ArrayList
<
Annotation
>(
size
);
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
Section
anSection
=
dex
.
openSection
(
section
.
readInt
());
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/parser/DebugInfoParser.java
浏览文件 @
e3606d1b
...
...
@@ -162,18 +162,19 @@ public class DebugInfoParser {
int
newAddr
=
addr
+
addrInc
;
for
(
int
i
=
addr
+
1
;
i
<=
newAddr
;
i
++)
{
InsnNode
insn
=
insnByOffset
[
i
];
if
(
insn
==
null
)
if
(
insn
==
null
)
{
continue
;
}
insn
.
setSourceLine
(
line
);
for
(
InsnArg
arg
:
insn
.
getArguments
())
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(
arg
.
isRegister
())
{
activeRegisters
[((
RegisterArg
)
arg
).
getRegNum
()]
=
arg
;
}
}
RegisterArg
res
=
insn
.
getResult
();
if
(
res
!=
null
)
if
(
res
!=
null
)
{
activeRegisters
[
res
.
getRegNum
()]
=
res
;
}
}
return
newAddr
;
}
...
...
@@ -195,18 +196,20 @@ public class DebugInfoParser {
for
(
int
i
=
start
;
i
<=
end
;
i
++)
{
InsnNode
insn
=
insnByOffset
[
i
];
if
(
insn
!=
null
)
if
(
insn
!=
null
)
{
fillLocals
(
insn
,
var
);
}
}
merge
(
activeRegisters
[
var
.
getRegNum
()],
var
);
}
private
static
void
fillLocals
(
InsnNode
insn
,
LocalVar
var
)
{
if
(
insn
.
getResult
()
!=
null
)
if
(
insn
.
getResult
()
!=
null
)
{
merge
(
insn
.
getResult
(),
var
);
for
(
InsnArg
arg
:
insn
.
getArguments
())
}
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
merge
(
arg
,
var
);
}
}
private
static
void
merge
(
InsnArg
arg
,
LocalVar
var
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java
浏览文件 @
e3606d1b
...
...
@@ -53,11 +53,13 @@ public final class IfCondition {
}
public
InsnArg
getB
()
{
if
(
insn
.
isZeroCmp
())
if
(
insn
.
isZeroCmp
())
{
return
InsnArg
.
lit
(
0
,
getA
().
getType
());
else
}
else
{
return
insn
.
getArg
(
1
);
}
}
public
Compare
invert
()
{
insn
.
invertCondition
();
return
this
;
...
...
jadx-core/src/main/java/jadx/core/dex/regions/IfRegion.java
浏览文件 @
e3606d1b
...
...
@@ -51,10 +51,12 @@ public final class IfRegion extends AbstractRegion {
public
List
<
IContainer
>
getSubBlocks
()
{
ArrayList
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
all
.
add
(
header
);
if
(
thenRegion
!=
null
)
if
(
thenRegion
!=
null
)
{
all
.
add
(
thenRegion
);
if
(
elseRegion
!=
null
)
}
if
(
elseRegion
!=
null
)
{
all
.
add
(
elseRegion
);
}
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/regions/LoopRegion.java
浏览文件 @
e3606d1b
...
...
@@ -68,9 +68,9 @@ public final class LoopRegion extends AbstractRegion {
*/
public
boolean
checkPreCondition
()
{
List
<
InsnNode
>
insns
=
preCondition
.
getInstructions
();
if
(
insns
.
isEmpty
())
if
(
insns
.
isEmpty
())
{
return
true
;
}
IfNode
ifInsn
=
getIfInsn
();
int
size
=
insns
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
...
...
@@ -79,21 +79,23 @@ public final class LoopRegion extends AbstractRegion {
return
false
;
}
else
{
RegisterArg
res
=
insn
.
getResult
();
if
(
res
.
getTypedVar
().
getUseList
().
size
()
>
2
)
if
(
res
.
getTypedVar
().
getUseList
().
size
()
>
2
)
{
return
false
;
}
boolean
found
=
false
;
// search result arg in other insns
for
(
int
j
=
i
+
1
;
j
<
size
;
j
++)
{
if
(
insns
.
get
(
i
).
containsArg
(
res
))
if
(
insns
.
get
(
i
).
containsArg
(
res
))
{
found
=
true
;
}
}
// or in if insn
if
(!
found
&&
ifInsn
.
containsArg
(
res
))
if
(!
found
&&
ifInsn
.
containsArg
(
res
))
{
found
=
true
;
if
(!
found
)
}
if
(!
found
)
{
return
false
;
}
}
}
return
true
;
...
...
@@ -117,10 +119,12 @@ public final class LoopRegion extends AbstractRegion {
@Override
public
List
<
IContainer
>
getSubBlocks
()
{
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
3
);
if
(
preCondition
!=
null
)
if
(
preCondition
!=
null
)
{
all
.
add
(
preCondition
);
if
(
conditionBlock
!=
null
)
}
if
(
conditionBlock
!=
null
)
{
all
.
add
(
conditionBlock
);
}
all
.
add
(
body
);
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/regions/Region.java
浏览文件 @
e3606d1b
...
...
@@ -28,8 +28,9 @@ public final class Region extends AbstractRegion {
sb
.
append
(
blocks
.
size
());
if
(
blocks
.
size
()
!=
0
)
{
for
(
IContainer
cont
:
blocks
)
{
if
(
cont
instanceof
BlockNode
)
if
(
cont
instanceof
BlockNode
)
{
sb
.
append
(((
BlockNode
)
cont
).
getId
());
}
}
}
return
sb
.
toString
();
...
...
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
浏览文件 @
e3606d1b
...
...
@@ -53,8 +53,9 @@ public final class SwitchRegion extends AbstractRegion {
List
<
IContainer
>
all
=
new
ArrayList
<
IContainer
>(
cases
.
size
()
+
2
);
all
.
add
(
header
);
all
.
addAll
(
cases
);
if
(
defCase
!=
null
)
if
(
defCase
!=
null
)
{
all
.
add
(
defCase
);
}
return
Collections
.
unmodifiableList
(
all
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/trycatch/ExceptionHandler.java
浏览文件 @
e3606d1b
...
...
@@ -86,13 +86,23 @@ public class ExceptionHandler {
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
this
==
obj
)
return
true
;
if
(
obj
==
null
)
return
false
;
if
(
getClass
()
!=
obj
.
getClass
())
return
false
;
if
(
this
==
obj
)
{
return
true
;
}
if
(
obj
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
obj
.
getClass
())
{
return
false
;
}
ExceptionHandler
other
=
(
ExceptionHandler
)
obj
;
if
(
catchType
==
null
)
{
if
(
other
.
catchType
!=
null
)
return
false
;
}
else
if
(!
catchType
.
equals
(
other
.
catchType
))
return
false
;
if
(
other
.
catchType
!=
null
)
{
return
false
;
}
}
else
if
(!
catchType
.
equals
(
other
.
catchType
))
{
return
false
;
}
return
handleOffset
==
other
.
handleOffset
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlinerVisitor.java
浏览文件 @
e3606d1b
...
...
@@ -22,14 +22,15 @@ public class ConstInlinerVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
Iterator
<
InsnNode
>
it
=
block
.
getInstructions
().
iterator
();
it
.
hasNext
();
)
{
InsnNode
insn
=
it
.
next
();
if
(
checkInsn
(
mth
,
block
,
insn
))
if
(
checkInsn
(
mth
,
block
,
insn
))
{
it
.
remove
();
}
}
}
}
...
...
@@ -57,9 +58,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
int
replace
=
0
;
for
(
InsnArg
arg
:
use
)
{
InsnNode
useInsn
=
arg
.
getParentInsn
();
if
(
useInsn
==
null
)
if
(
useInsn
==
null
)
{
continue
;
}
BlockNode
useBlock
=
BlockUtils
.
getBlockByInsn
(
mth
,
useInsn
);
if
(
useBlock
==
block
||
useBlock
.
isDominator
(
block
))
{
if
(
arg
!=
insn
.
getResult
()
&&
!
registerReassignOnPath
(
block
,
useBlock
,
insn
))
{
...
...
@@ -77,9 +78,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
}
private
static
boolean
registerReassignOnPath
(
BlockNode
block
,
BlockNode
useBlock
,
InsnNode
assignInsn
)
{
if
(
block
==
useBlock
)
if
(
block
==
useBlock
)
{
return
false
;
}
Set
<
BlockNode
>
blocks
=
BlockUtils
.
getAllPathsBlocks
(
block
,
useBlock
);
// TODO store list of assign insn for each register
int
regNum
=
assignInsn
.
getResult
().
getRegNum
();
...
...
@@ -87,8 +88,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
for
(
InsnNode
insn
:
b
.
getInstructions
())
{
if
(
insn
.
getResult
()
!=
null
&&
insn
!=
assignInsn
&&
insn
.
getResult
().
getRegNum
()
==
regNum
)
&&
insn
.
getResult
().
getRegNum
()
==
regNum
)
{
return
true
;
}
}
}
return
false
;
...
...
@@ -156,10 +158,11 @@ public class ConstInlinerVisitor extends AbstractVisitor {
InsnArg
arg
=
insn
.
getArg
(
i
);
if
(!
arg
.
getType
().
isTypeKnown
())
{
ArgType
type
;
if
(
k
>=
0
)
if
(
k
>=
0
)
{
type
=
types
.
get
(
k
);
else
}
else
{
type
=
mth
.
getParentClass
().
getClassInfo
().
getType
();
}
arg
.
merge
(
type
);
}
k
++;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DepthTraverser.java
浏览文件 @
e3606d1b
...
...
@@ -9,10 +9,12 @@ public class DepthTraverser {
public
static
void
visit
(
IDexTreeVisitor
visitor
,
ClassNode
cls
)
{
try
{
if
(
visitor
.
visit
(
cls
))
{
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
for
(
ClassNode
inCls
:
cls
.
getInnerClasses
())
{
visit
(
visitor
,
inCls
);
for
(
MethodNode
mth
:
cls
.
getMethods
())
}
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
visit
(
visitor
,
mth
);
}
}
}
catch
(
Throwable
e
)
{
ErrorsCounter
.
classError
(
cls
,
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
浏览文件 @
e3606d1b
...
...
@@ -36,9 +36,9 @@ public class DotGraphVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
CodeWriter
dot
=
new
CodeWriter
();
CodeWriter
conn
=
new
CodeWriter
();
...
...
@@ -47,18 +47,22 @@ public class DotGraphVisitor extends AbstractVisitor {
+
"\" {"
);
if
(
useRegions
)
{
if
(
mth
.
getRegion
()
==
null
)
if
(
mth
.
getRegion
()
==
null
)
{
return
;
}
processRegion
(
mth
,
mth
.
getRegion
(),
dot
,
conn
);
if
(
mth
.
getExceptionHandlers
()
!=
null
)
{
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
if
(
h
.
getHandlerRegion
()
!=
null
)
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
if
(
h
.
getHandlerRegion
()
!=
null
)
{
processRegion
(
mth
,
h
.
getHandlerRegion
(),
dot
,
conn
);
}
}
}
}
else
{
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
processBlock
(
mth
,
block
,
dot
,
conn
);
}
}
String
attrs
=
attributesString
(
mth
);
...
...
@@ -109,8 +113,9 @@ public class DotGraphVisitor extends AbstractVisitor {
String
attrs
=
attributesString
(
block
);
if
(
PRINT_REGISTERS_STATES
)
{
if
(
block
.
getStartState
()
!=
null
)
{
if
(
attrs
.
length
()
!=
0
)
if
(
attrs
.
length
()
!=
0
)
{
attrs
+=
"|"
;
}
attrs
+=
escape
(
"RS: "
+
block
.
getStartState
())
+
NL
;
attrs
+=
escape
(
"RE: "
+
block
.
getEndState
())
+
NL
;
}
...
...
@@ -125,16 +130,17 @@ public class DotGraphVisitor extends AbstractVisitor {
+
(
insns
.
length
()
==
0
?
""
:
"|"
+
insns
)
+
"}\"];"
);
for
(
BlockNode
next
:
block
.
getSuccessors
())
for
(
BlockNode
next
:
block
.
getSuccessors
())
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
";"
);
for
(
BlockNode
next
:
block
.
getDominatesOn
())
}
for
(
BlockNode
next
:
block
.
getDominatesOn
())
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
"[style=dotted];"
);
}
// add all dominators connections
if
(
false
)
{
for
(
BlockNode
next
:
BlockUtils
.
bitsetToBlocks
(
mth
,
block
.
getDoms
()))
for
(
BlockNode
next
:
BlockUtils
.
bitsetToBlocks
(
mth
,
block
.
getDoms
()))
{
conn
.
startLine
(
makeName
(
block
)
+
" -> "
+
makeName
(
next
)
+
"[style=dotted, color=green];"
);
}
}
}
...
...
@@ -168,8 +174,9 @@ public class DotGraphVisitor extends AbstractVisitor {
CodeWriter
code
=
new
CodeWriter
(
0
);
MethodGen
.
makeFallbackInsns
(
code
,
mth
,
block
.
getInstructions
(),
false
);
String
str
=
escape
(
code
.
newLine
().
toString
());
if
(
str
.
startsWith
(
NL
))
if
(
str
.
startsWith
(
NL
))
{
str
=
str
.
substring
(
NL
.
length
());
}
return
str
;
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/FallbackModeVisitor.java
浏览文件 @
e3606d1b
...
...
@@ -10,9 +10,9 @@ public class FallbackModeVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
for
(
InsnNode
insn
:
mth
.
getInstructions
())
{
// remove 'exception catch' for instruction which don't throw any exceptions
CatchAttr
catchAttr
=
(
CatchAttr
)
insn
.
getAttributes
().
get
(
AttributeType
.
CATCH_BLOCK
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java
浏览文件 @
e3606d1b
...
...
@@ -22,18 +22,20 @@ public class CheckRegions extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
{
return
;
}
// check if all blocks included in regions
final
Set
<
BlockNode
>
blocksInRegions
=
new
HashSet
<
BlockNode
>();
IRegionVisitor
collectBlocks
=
new
AbstractRegionVisitor
()
{
@Override
public
void
processBlock
(
MethodNode
mth
,
IBlock
container
)
{
if
(
container
instanceof
BlockNode
)
if
(
container
instanceof
BlockNode
)
{
blocksInRegions
.
add
((
BlockNode
)
container
);
else
}
else
{
LOG
.
warn
(
"Not block node : "
+
container
.
getClass
().
getSimpleName
());
}
}
};
DepthRegionTraverser
.
traverseAll
(
mth
,
collectBlocks
);
...
...
@@ -44,10 +46,11 @@ public class CheckRegions extends AbstractVisitor {
if
(!
block
.
getInstructions
().
isEmpty
()
&&
!
block
.
getAttributes
().
contains
(
AttributeFlag
.
SKIP
))
{
mth
.
getAttributes
().
add
(
AttributeFlag
.
INCONSISTENT_CODE
);
if
(
Consts
.
DEBUG
)
if
(
Consts
.
DEBUG
)
{
LOG
.
debug
(
" Missing block: {} in {}"
,
block
,
mth
);
else
}
else
{
break
;
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CleanRegions.java
浏览文件 @
e3606d1b
...
...
@@ -18,14 +18,15 @@ public class CleanRegions extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
if
(
mth
.
isNoCode
()
||
mth
.
getBasicBlocks
().
size
()
==
0
)
{
return
;
}
IRegionVisitor
removeEmptyBlocks
=
new
AbstractRegionVisitor
()
{
@Override
public
void
enterRegion
(
MethodNode
mth
,
IRegion
region
)
{
if
(!(
region
instanceof
Region
))
if
(!(
region
instanceof
Region
))
{
return
;
}
for
(
Iterator
<
IContainer
>
it
=
region
.
getSubBlocks
().
iterator
();
it
.
hasNext
();
)
{
IContainer
container
=
it
.
next
();
...
...
@@ -44,6 +45,5 @@ public class CleanRegions extends AbstractVisitor {
}
};
DepthRegionTraverser
.
traverseAll
(
mth
,
removeEmptyBlocks
);
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraverser.java
浏览文件 @
e3606d1b
...
...
@@ -25,8 +25,9 @@ public class DepthRegionTraverser {
traverse
(
mth
,
visitor
,
mth
.
getRegion
());
if
(
mth
.
getExceptionHandlers
()
!=
null
)
{
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
for
(
ExceptionHandler
h
:
mth
.
getExceptionHandlers
())
{
traverse
(
mth
,
visitor
,
h
.
getHandlerRegion
());
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessVariables.java
浏览文件 @
e3606d1b
...
...
@@ -141,12 +141,13 @@ public class ProcessVariables extends AbstractVisitor {
for
(
Iterator
<
IRegion
>
it
=
set
.
iterator
();
it
.
hasNext
();
)
{
IRegion
r
=
it
.
next
();
IRegion
parent
=
r
.
getParent
();
if
(
parent
!=
null
&&
set
.
contains
(
parent
))
if
(
parent
!=
null
&&
set
.
contains
(
parent
))
{
it
.
remove
();
}
}
if
(
set
.
isEmpty
())
if
(
set
.
isEmpty
())
{
continue
;
}
IRegion
region
=
set
.
iterator
().
next
();
IRegion
parent
=
region
;
boolean
declare
=
false
;
...
...
@@ -178,12 +179,14 @@ public class ProcessVariables extends AbstractVisitor {
private
boolean
canDeclareInRegion
(
Usage
u
,
IRegion
region
)
{
for
(
IRegion
r
:
u
.
getAssigns
())
{
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
{
return
false
;
}
}
for
(
IRegion
r
:
u
.
getUseRegions
())
{
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
if
(!
RegionUtils
.
isRegionContainsRegion
(
region
,
r
))
{
return
false
;
}
}
return
true
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMakerVisitor.java
浏览文件 @
e3606d1b
...
...
@@ -12,9 +12,9 @@ public class RegionMakerVisitor extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
RegionMaker
rm
=
new
RegionMaker
(
mth
);
RegionStack
state
=
new
RegionStack
(
mth
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionStack.java
浏览文件 @
e3606d1b
...
...
@@ -17,8 +17,9 @@ final class RegionStack {
private
static
final
boolean
DEBUG
=
false
;
static
{
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Debug enabled for {}"
,
RegionStack
.
class
);
}
}
private
static
final
class
State
{
...
...
@@ -47,27 +48,30 @@ final class RegionStack {
private
State
curState
;
public
RegionStack
(
MethodNode
mth
)
{
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"New RegionStack: {}"
,
mth
);
}
this
.
stack
=
new
ArrayDeque
<
State
>();
this
.
curState
=
new
State
();
}
public
void
push
(
IRegion
region
)
{
stack
.
push
(
curState
);
if
(
stack
.
size
()
>
1000
)
if
(
stack
.
size
()
>
1000
)
{
throw
new
StackOverflowError
(
"Deep code hierarchy"
);
}
curState
=
curState
.
copy
();
curState
.
region
=
region
;
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Stack push: {}: {}"
,
size
(),
curState
);
}
}
public
void
pop
()
{
curState
=
stack
.
pop
();
if
(
DEBUG
)
if
(
DEBUG
)
{
LOG
.
debug
(
"Stack pop: {}: {}"
,
size
(),
curState
);
}
}
/**
...
...
@@ -76,8 +80,9 @@ final class RegionStack {
* @param exit boundary node, null will be ignored
*/
public
void
addExit
(
BlockNode
exit
)
{
if
(
exit
!=
null
)
if
(
exit
!=
null
)
{
curState
.
exits
.
add
(
exit
);
}
}
public
boolean
containsExit
(
BlockNode
exit
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/FinishTypeResolver.java
浏览文件 @
e3606d1b
...
...
@@ -12,31 +12,39 @@ public class FinishTypeResolver extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
boolean
change
;
int
i
=
0
;
do
{
change
=
false
;
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
if
(
PostTypeResolver
.
visit
(
mth
,
insn
))
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
if
(
PostTypeResolver
.
visit
(
mth
,
insn
))
{
change
=
true
;
}
}
}
i
++;
if
(
i
>
1000
)
if
(
i
>
1000
)
{
break
;
}
}
while
(
change
);
// last chance to set correct value (just use first type from 'possible' list)
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
InsnNode
insn
:
block
.
getInstructions
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
SelectTypeVisitor
.
visit
(
insn
);
}
}
// check
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
for
(
InsnNode
insn
:
block
.
getInstructions
())
for
(
BlockNode
block
:
mth
.
getBasicBlocks
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
CheckTypeVisitor
.
visit
(
mth
,
insn
);
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/TypeResolver.java
浏览文件 @
e3606d1b
...
...
@@ -16,9 +16,9 @@ public class TypeResolver extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
if
(
mth
.
isNoCode
())
{
return
;
}
prepare
(
mth
);
visitBlocks
(
mth
);
...
...
@@ -60,11 +60,13 @@ public class TypeResolver extends AbstractVisitor {
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(
arg
.
isRegister
())
if
(
arg
.
isRegister
())
{
state
.
use
((
RegisterArg
)
arg
);
}
}
if
(
insn
.
getResult
()
!=
null
)
if
(
insn
.
getResult
()
!=
null
)
{
state
.
assignReg
(
insn
.
getResult
());
}
}
block
.
setEndState
(
new
BlockRegState
(
state
));
...
...
@@ -78,8 +80,9 @@ public class TypeResolver extends AbstractVisitor {
changed
=
false
;
for
(
BlockNode
block
:
preds
)
{
for
(
BlockNode
pred
:
block
.
getPredecessors
())
{
if
(
connectEdges
(
mth
,
pred
,
block
,
true
))
if
(
connectEdges
(
mth
,
pred
,
block
,
true
))
{
changed
=
true
;
}
}
}
}
while
(
changed
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/PostTypeResolver.java
浏览文件 @
e3606d1b
...
...
@@ -39,10 +39,12 @@ public class PostTypeResolver {
case
MOVE:
{
boolean
change
=
false
;
if
(
insn
.
getResult
().
merge
(
insn
.
getArg
(
0
)))
if
(
insn
.
getResult
().
merge
(
insn
.
getArg
(
0
)))
{
change
=
true
;
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getResult
()))
}
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getResult
()))
{
change
=
true
;
}
return
change
;
}
...
...
@@ -56,10 +58,12 @@ public class PostTypeResolver {
boolean
change
=
false
;
IfNode
ifnode
=
(
IfNode
)
insn
;
if
(!
ifnode
.
isZeroCmp
())
{
if
(
insn
.
getArg
(
1
).
merge
(
insn
.
getArg
(
0
)))
if
(
insn
.
getArg
(
1
).
merge
(
insn
.
getArg
(
0
)))
{
change
=
true
;
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getArg
(
1
)))
}
if
(
insn
.
getArg
(
0
).
merge
(
insn
.
getArg
(
1
)))
{
change
=
true
;
}
}
return
change
;
}
...
...
@@ -94,10 +98,12 @@ public class PostTypeResolver {
private
static
boolean
fixArrayTypes
(
InsnArg
array
,
InsnArg
elem
)
{
boolean
change
=
false
;
if
(!
elem
.
getType
().
isTypeKnown
()
&&
elem
.
merge
(
array
.
getType
().
getArrayElement
()))
if
(!
elem
.
getType
().
isTypeKnown
()
&&
elem
.
merge
(
array
.
getType
().
getArrayElement
()))
{
change
=
true
;
if
(!
array
.
getType
().
isTypeKnown
()
&&
array
.
merge
(
ArgType
.
array
(
elem
.
getType
())))
}
if
(!
array
.
getType
().
isTypeKnown
()
&&
array
.
merge
(
ArgType
.
array
(
elem
.
getType
())))
{
change
=
true
;
}
return
change
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/typeresolver/finish/SelectTypeVisitor.java
浏览文件 @
e3606d1b
...
...
@@ -13,8 +13,9 @@ public class SelectTypeVisitor {
}
for
(
InsnArg
arg
:
insn
.
getArguments
())
{
if
(!
arg
.
getType
().
isTypeKnown
())
if
(!
arg
.
getType
().
isTypeKnown
())
{
selectType
(
arg
);
}
}
}
...
...
jadx-core/src/main/java/jadx/core/utils/BlockUtils.java
浏览文件 @
e3606d1b
...
...
@@ -33,25 +33,27 @@ public class BlockUtils {
}
assert
list
.
size
()
==
2
:
"too many nodes for selectOther: "
+
node
+
" in "
+
list
;
BlockNode
first
=
list
.
get
(
0
);
if
(
first
!=
node
)
if
(
first
!=
node
)
{
return
first
;
else
}
else
{
return
list
.
get
(
1
);
}
}
private
static
List
<
BlockNode
>
cleanBlockList
(
List
<
BlockNode
>
list
)
{
List
<
BlockNode
>
ret
=
new
ArrayList
<
BlockNode
>(
list
.
size
());
for
(
BlockNode
block
:
list
)
{
if
(!
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(!
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
ret
.
add
(
block
);
}
}
return
ret
;
}
public
static
boolean
isBackEdge
(
BlockNode
from
,
BlockNode
to
)
{
if
(
from
.
getCleanSuccessors
().
contains
(
to
))
if
(
from
.
getCleanSuccessors
().
contains
(
to
))
{
return
false
;
// already checked
}
return
from
.
getSuccessors
().
contains
(
to
);
}
...
...
@@ -61,8 +63,9 @@ public class BlockUtils {
public
static
void
cleanBitSet
(
MethodNode
mth
,
BitSet
bs
)
{
for
(
int
i
=
bs
.
nextSetBit
(
0
);
i
>=
0
;
i
=
bs
.
nextSetBit
(
i
+
1
))
{
BlockNode
block
=
mth
.
getBasicBlocks
().
get
(
i
);
if
(
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(
block
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
bs
.
clear
(
i
);
}
}
}
...
...
@@ -81,17 +84,18 @@ public class BlockUtils {
*/
public
static
boolean
blockContains
(
BlockNode
block
,
InsnNode
insn
)
{
for
(
InsnNode
bi
:
block
.
getInstructions
())
{
if
(
bi
==
insn
)
if
(
bi
==
insn
)
{
return
true
;
}
}
return
false
;
}
public
static
boolean
lastInsnType
(
BlockNode
block
,
InsnType
type
)
{
List
<
InsnNode
>
insns
=
block
.
getInstructions
();
if
(
insns
.
isEmpty
())
if
(
insns
.
isEmpty
())
{
return
false
;
}
InsnNode
insn
=
insns
.
get
(
insns
.
size
()
-
1
);
return
insn
.
getType
()
==
type
;
}
...
...
@@ -99,8 +103,9 @@ public class BlockUtils {
public
static
BlockNode
getBlockByInsn
(
MethodNode
mth
,
InsnNode
insn
)
{
assert
insn
!=
null
;
for
(
BlockNode
bn
:
mth
.
getBasicBlocks
())
{
if
(
blockContains
(
bn
,
insn
))
if
(
blockContains
(
bn
,
insn
))
{
return
bn
;
}
}
return
null
;
}
...
...
@@ -136,8 +141,9 @@ public class BlockUtils {
public
static
Set
<
BlockNode
>
getAllPathsBlocks
(
BlockNode
start
,
BlockNode
end
)
{
Set
<
BlockNode
>
set
=
new
HashSet
<
BlockNode
>();
set
.
add
(
start
);
if
(
start
!=
end
)
if
(
start
!=
end
)
{
addPredcessors
(
set
,
end
,
start
);
}
return
set
;
}
...
...
@@ -152,29 +158,29 @@ public class BlockUtils {
private
static
boolean
traverseSuccessorsUntil
(
BlockNode
from
,
BlockNode
until
,
Set
<
BlockNode
>
checked
)
{
for
(
BlockNode
s
:
from
.
getCleanSuccessors
())
{
if
(
s
==
until
)
if
(
s
==
until
)
{
return
true
;
}
if
(!
checked
.
contains
(
s
))
{
checked
.
add
(
s
);
if
(
until
.
isDominator
(
s
))
if
(
until
.
isDominator
(
s
))
{
return
true
;
if
(
traverseSuccessorsUntil
(
s
,
until
,
checked
))
}
if
(
traverseSuccessorsUntil
(
s
,
until
,
checked
))
{
return
true
;
}
}
}
return
false
;
}
public
static
boolean
isPathExists
(
BlockNode
start
,
BlockNode
end
)
{
if
(
start
==
end
)
if
(
start
==
end
)
{
return
true
;
if
(
end
.
isDominator
(
start
))
}
if
(
end
.
isDominator
(
start
))
{
return
true
;
}
return
traverseSuccessorsUntil
(
start
,
end
,
new
HashSet
<
BlockNode
>());
}
...
...
@@ -203,8 +209,9 @@ public class BlockUtils {
return
node
;
}
else
{
BlockNode
out
=
traverseWhileDominates
(
block
,
node
);
if
(
out
!=
null
)
if
(
out
!=
null
)
{
return
out
;
}
}
}
return
null
;
...
...
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
浏览文件 @
e3606d1b
...
...
@@ -81,10 +81,11 @@ public class ErrorsCounter {
}
private
static
String
formatException
(
Throwable
e
)
{
if
(
e
==
null
||
e
.
getMessage
()
==
null
)
if
(
e
==
null
||
e
.
getMessage
()
==
null
)
{
return
""
;
else
}
else
{
return
"\n error: "
+
e
.
getMessage
();
}
}
public
static
String
formatErrorMsg
(
ClassNode
cls
,
String
msg
,
Throwable
e
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/InsnUtils.java
浏览文件 @
e3606d1b
...
...
@@ -40,12 +40,13 @@ public class InsnUtils {
}
public
static
String
indexToString
(
Object
index
)
{
if
(
index
==
null
)
if
(
index
==
null
)
{
return
""
;
if
(
index
instanceof
String
)
}
if
(
index
instanceof
String
)
{
return
"\""
+
index
+
"\""
;
else
}
else
{
return
" "
+
index
.
toString
();
}
}
}
jadx-core/src/main/java/jadx/core/utils/InstructionRemover.java
浏览文件 @
e3606d1b
...
...
@@ -32,8 +32,9 @@ public class InstructionRemover {
}
public
static
void
unbindInsnList
(
List
<
InsnNode
>
unbind
)
{
for
(
InsnNode
rem
:
unbind
)
for
(
InsnNode
rem
:
unbind
)
{
unbindInsn
(
rem
);
}
}
public
static
void
unbindInsn
(
InsnNode
insn
)
{
...
...
@@ -56,8 +57,9 @@ public class InstructionRemover {
// and here can be several instructions with same content
public
static
void
removeAll
(
List
<
InsnNode
>
insns
,
List
<
InsnNode
>
toRemove
)
{
if
(
insns
==
toRemove
)
{
for
(
InsnNode
rem
:
toRemove
)
for
(
InsnNode
rem
:
toRemove
)
{
unbindInsn
(
rem
);
}
return
;
}
...
...
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
浏览文件 @
e3606d1b
...
...
@@ -19,8 +19,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
List
<
IContainer
>
blocks
=
region
.
getSubBlocks
();
if
(
blocks
.
isEmpty
())
if
(
blocks
.
isEmpty
())
{
return
false
;
}
return
hasExitEdge
(
blocks
.
get
(
blocks
.
size
()
-
1
));
}
else
{
throw
new
JadxRuntimeException
(
"Unknown container type: "
+
container
.
getClass
());
...
...
@@ -33,8 +34,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
for
(
IContainer
block
:
region
.
getSubBlocks
())
{
if
(
notEmpty
(
block
))
if
(
notEmpty
(
block
))
{
return
true
;
}
}
return
false
;
}
else
{
...
...
@@ -61,8 +63,9 @@ public class RegionUtils {
}
else
if
(
container
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
container
;
for
(
IContainer
b
:
region
.
getSubBlocks
())
{
if
(
isRegionContainsBlock
(
b
,
block
))
if
(
isRegionContainsBlock
(
b
,
block
))
{
return
true
;
}
}
return
false
;
}
else
{
...
...
@@ -71,8 +74,9 @@ public class RegionUtils {
}
private
static
boolean
isRegionContainsExcHandlerRegion
(
IContainer
container
,
IRegion
region
)
{
if
(
container
==
region
)
if
(
container
==
region
)
{
return
true
;
}
if
(
container
instanceof
IRegion
)
{
IRegion
r
=
(
IRegion
)
container
;
...
...
@@ -84,16 +88,19 @@ public class RegionUtils {
if
(
cb
!=
null
&&
(
b
instanceof
IRegion
))
{
TryCatchBlock
tb
=
cb
.
getTryBlock
();
for
(
ExceptionHandler
eh
:
tb
.
getHandlers
())
{
if
(
isRegionContainsRegion
(
eh
.
getHandlerRegion
(),
region
))
if
(
isRegionContainsRegion
(
eh
.
getHandlerRegion
(),
region
))
{
return
true
;
}
}
if
(
tb
.
getFinalBlock
()
!=
null
)
{
if
(
isRegionContainsRegion
(
tb
.
getFinalBlock
(),
region
))
if
(
isRegionContainsRegion
(
tb
.
getFinalBlock
(),
region
))
{
return
true
;
}
}
}
if
(
isRegionContainsRegion
(
b
,
region
))
if
(
isRegionContainsRegion
(
b
,
region
))
{
return
true
;
}
}
}
return
false
;
...
...
@@ -105,16 +112,20 @@ public class RegionUtils {
* otherwise run recursive search because exception handlers can have several parents
*/
public
static
boolean
isRegionContainsRegion
(
IContainer
container
,
IRegion
region
)
{
if
(
container
==
region
)
return
true
;
if
(
region
==
null
)
return
false
;
if
(
container
==
region
)
{
return
true
;
}
if
(
region
==
null
)
{
return
false
;
}
IRegion
parent
=
region
.
getParent
();
while
(
container
!=
parent
)
{
if
(
parent
==
null
)
{
if
(
region
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
if
(
region
.
getAttributes
().
contains
(
AttributeType
.
EXC_HANDLER
))
{
return
isRegionContainsExcHandlerRegion
(
container
,
region
);
else
}
else
{
return
false
;
}
}
region
=
parent
;
parent
=
region
.
getParent
();
...
...
@@ -123,11 +134,9 @@ public class RegionUtils {
}
public
static
boolean
isDominaterBy
(
BlockNode
dom
,
IContainer
cont
)
{
assert
cont
!=
null
;
if
(
dom
==
cont
)
if
(
dom
==
cont
)
{
return
true
;
}
if
(
cont
instanceof
BlockNode
)
{
BlockNode
block
=
(
BlockNode
)
cont
;
return
block
.
isDominator
(
dom
);
...
...
@@ -145,16 +154,17 @@ public class RegionUtils {
}
public
static
boolean
hasPathThruBlock
(
BlockNode
block
,
IContainer
cont
)
{
if
(
block
==
cont
)
if
(
block
==
cont
)
{
return
true
;
}
if
(
cont
instanceof
BlockNode
)
{
return
BlockUtils
.
isPathExists
(
block
,
(
BlockNode
)
cont
);
}
else
if
(
cont
instanceof
IRegion
)
{
IRegion
region
=
(
IRegion
)
cont
;
for
(
IContainer
c
:
region
.
getSubBlocks
())
{
if
(!
hasPathThruBlock
(
block
,
c
))
if
(!
hasPathThruBlock
(
block
,
c
))
{
return
false
;
}
}
return
true
;
}
else
{
...
...
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
浏览文件 @
e3606d1b
...
...
@@ -14,9 +14,9 @@ public class StringUtils {
}
public
static
String
unescapeChar
(
char
ch
)
{
if
(
ch
==
'\''
)
if
(
ch
==
'\''
)
{
return
"'\\\''"
;
}
StringBuilder
res
=
new
StringBuilder
();
processChar
(
ch
,
res
);
return
'\''
+
res
.
toString
()
+
'\''
;
...
...
jadx-core/src/main/java/jadx/core/utils/Utils.java
浏览文件 @
e3606d1b
...
...
@@ -16,10 +16,11 @@ public class Utils {
public
static
String
cleanObjectName
(
String
obj
)
{
int
last
=
obj
.
length
()
-
1
;
if
(
obj
.
charAt
(
0
)
==
'L'
&&
obj
.
charAt
(
last
)
==
';'
)
if
(
obj
.
charAt
(
0
)
==
'L'
&&
obj
.
charAt
(
last
)
==
';'
)
{
return
obj
.
substring
(
1
,
last
).
replace
(
'/'
,
'.'
);
else
}
else
{
return
obj
;
}
}
public
static
String
makeQualifiedObjectName
(
String
obj
)
{
...
...
@@ -61,27 +62,29 @@ public class Utils {
}
public
static
String
listToString
(
Iterable
<?>
list
)
{
if
(
list
==
null
)
if
(
list
==
null
)
{
return
""
;
}
StringBuilder
str
=
new
StringBuilder
();
for
(
Iterator
<?>
it
=
list
.
iterator
();
it
.
hasNext
();
)
{
Object
o
=
it
.
next
();
str
.
append
(
o
);
if
(
it
.
hasNext
())
if
(
it
.
hasNext
())
{
str
.
append
(
", "
);
}
}
return
str
.
toString
();
}
public
static
String
arrayToString
(
Object
[]
array
)
{
if
(
array
==
null
)
if
(
array
==
null
)
{
return
""
;
}
StringBuilder
sb
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
array
.
length
;
i
++)
{
if
(
i
!=
0
)
if
(
i
!=
0
)
{
sb
.
append
(
", "
);
}
sb
.
append
(
array
[
i
]);
}
return
sb
.
toString
();
...
...
@@ -108,11 +111,11 @@ public class Utils {
int
pair
=
1
;
for
(
int
pos
=
1
;
pos
<
sign
.
length
();
pos
++)
{
char
c
=
sign
.
charAt
(
pos
);
if
(
c
==
'<'
)
if
(
c
==
'<'
)
{
pair
++;
else
if
(
c
==
'>'
)
}
else
if
(
c
==
'>'
)
{
pair
--;
}
if
(
pair
==
0
)
{
end
=
pos
;
break
;
...
...
@@ -127,8 +130,9 @@ public class Utils {
if
(!
dir
.
exists
())
{
// if directory already created in other thread mkdirs will return false,
// so check dir existence again
if
(!
dir
.
mkdirs
()
&&
!
dir
.
exists
())
if
(!
dir
.
mkdirs
()
&&
!
dir
.
exists
())
{
throw
new
JadxRuntimeException
(
"Can't create directory "
+
dir
);
}
}
}
}
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
浏览文件 @
e3606d1b
...
...
@@ -26,7 +26,6 @@ public class InputFile {
if
(!
file
.
exists
())
{
throw
new
IOException
(
"File not found: "
+
file
.
getAbsolutePath
());
}
String
fileName
=
file
.
getName
();
if
(
fileName
.
endsWith
(
".dex"
))
{
...
...
@@ -49,8 +48,9 @@ public class InputFile {
throw
new
DecodeException
(
"java class to dex conversion error:\n "
+
e
.
getMessage
(),
e
);
}
}
else
}
else
{
throw
new
DecodeException
(
"Unsupported input file: "
+
file
);
}
}
private
byte
[]
openDexFromApk
(
File
file
)
throws
IOException
{
...
...
jadx-core/src/test/java/jadx/tests/internal/TestStringBuilderElimination.java
浏览文件 @
e3606d1b
...
...
@@ -29,8 +29,8 @@ public class TestStringBuilderElimination extends InternalJadxTest {
String
code
=
cls
.
getCode
().
toString
();
System
.
out
.
println
(
code
);
assertThat
(
code
,
containsString
(
"MyException(String str, Exception e) {"
));
assertThat
(
code
,
containsString
(
"super(\"msg:\" + str, e);"
));
assertThat
(
code
,
containsString
(
"MyException(String str, Exception e) {"
));
assertThat
(
code
,
containsString
(
"super(\"msg:\" + str, e);"
));
assertThat
(
code
,
not
(
containsString
(
"new StringBuilder"
)));
assertThat
(
code
,
containsString
(
"System.out.println(\"k=\" + k);"
));
...
...
jadx-core/src/test/java/jadx/tests/internal/TestSwitchLabels.java
浏览文件 @
e3606d1b
...
...
@@ -6,9 +6,7 @@ import jadx.core.dex.nodes.ClassNode;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
hamcrest
.
CoreMatchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
mockito
.
AdditionalMatchers
.
or
;
public
class
TestSwitchLabels
extends
InternalJadxTest
{
public
static
class
TestCls
{
...
...
@@ -17,6 +15,7 @@ public class TestSwitchLabels extends InternalJadxTest {
public
static
class
Inner
{
private
static
final
int
CONST_CDE_PRIVATE
=
0xCDE
;
public
int
f1
(
int
arg0
)
{
switch
(
arg0
)
{
case
CONST_CDE_PRIVATE:
...
...
jadx-core/src/test/java/jadx/tests/internal/inline/TestInline3.java
浏览文件 @
e3606d1b
...
...
@@ -19,7 +19,7 @@ public class TestInline3 extends InternalJadxTest {
public
TestCls
(
int
a1
,
int
a2
,
int
a3
,
int
a4
,
int
a5
)
{
}
public
class
A
extends
TestCls
{
public
class
A
extends
TestCls
{
public
A
(
int
a
)
{
super
(
a
,
a
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录