Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Quincy379
jadx
提交
cd7e5bf0
J
jadx
项目概览
Quincy379
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cd7e5bf0
编写于
1月 17, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into rename
上级
9dbffef1
5e7388f6
变更
24
显示空白变更内容
内联
并排
Showing
24 changed file
with
417 addition
and
78 deletion
+417
-78
.github/workflows/gradle-wrapper-validation.yml
.github/workflows/gradle-wrapper-validation.yml
+10
-0
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+2
-0
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+11
-0
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+1
-1
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+4
-4
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
...core/src/main/java/jadx/core/dex/attributes/AttrNode.java
+1
-0
jadx-core/src/main/java/jadx/core/dex/attributes/IAttributeNode.java
...rc/main/java/jadx/core/dex/attributes/IAttributeNode.java
+2
-0
jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
+1
-6
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
.../src/main/java/jadx/core/dex/instructions/SwitchNode.java
+7
-8
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+15
-1
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
...ore/src/main/java/jadx/core/dex/regions/SwitchRegion.java
+39
-12
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
...core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
+37
-0
jadx-core/src/main/java/jadx/core/export/TemplateFile.java
jadx-core/src/main/java/jadx/core/export/TemplateFile.java
+3
-11
jadx-core/src/main/java/jadx/core/utils/DebugUtils.java
jadx-core/src/main/java/jadx/core/utils/DebugUtils.java
+47
-20
jadx-core/src/main/java/jadx/core/utils/SmaliUtils.java
jadx-core/src/main/java/jadx/core/utils/SmaliUtils.java
+10
-10
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
+4
-0
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
+47
-2
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+7
-2
jadx-core/src/test/java/jadx/tests/integration/inner/TestRFieldRestore3.java
...java/jadx/tests/integration/inner/TestRFieldRestore3.java
+70
-0
jadx-core/src/test/java/jadx/tests/integration/inner/TestReplaceConstsInAnnotations.java
...sts/integration/inner/TestReplaceConstsInAnnotations.java
+37
-0
jadx-core/src/test/java/jadx/tests/integration/switches/TestSwitchFallThrough.java
...adx/tests/integration/switches/TestSwitchFallThrough.java
+54
-0
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+3
-0
jadx-gui/src/main/java/jadx/gui/ui/codearea/SearchBar.java
jadx-gui/src/main/java/jadx/gui/ui/codearea/SearchBar.java
+2
-1
jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java
jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java
+3
-0
未找到文件。
.github/workflows/gradle-wrapper-validation.yml
0 → 100644
浏览文件 @
cd7e5bf0
name
:
"
Validate
Gradle
Wrapper"
on
:
[
push
]
jobs
:
validation
:
name
:
"
Validation"
runs-on
:
ubuntu-latest
steps
:
-
uses
:
actions/checkout@v1
-
uses
:
gradle/wrapper-validation-action@v1
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
cd7e5bf0
...
@@ -7,6 +7,7 @@ import jadx.api.JadxArgs;
...
@@ -7,6 +7,7 @@ import jadx.api.JadxArgs;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.impl.NoOpCodeCache
;
import
jadx.api.impl.NoOpCodeCache
;
import
jadx.core.utils.exceptions.JadxArgsValidateException
;
import
jadx.core.utils.exceptions.JadxArgsValidateException
;
import
jadx.core.utils.files.FileUtils
;
public
class
JadxCLI
{
public
class
JadxCLI
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxCLI
.
class
);
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxCLI
.
class
);
...
@@ -22,6 +23,7 @@ public class JadxCLI {
...
@@ -22,6 +23,7 @@ public class JadxCLI {
LOG
.
error
(
"jadx error: {}"
,
e
.
getMessage
(),
e
);
LOG
.
error
(
"jadx error: {}"
,
e
.
getMessage
(),
e
);
result
=
1
;
result
=
1
;
}
finally
{
}
finally
{
FileUtils
.
deleteTempRootDir
();
System
.
exit
(
result
);
System
.
exit
(
result
);
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
浏览文件 @
cd7e5bf0
...
@@ -52,6 +52,8 @@ public class ClassGen {
...
@@ -52,6 +52,8 @@ public class ClassGen {
private
final
Set
<
ClassInfo
>
imports
=
new
HashSet
<>();
private
final
Set
<
ClassInfo
>
imports
=
new
HashSet
<>();
private
int
clsDeclLine
;
private
int
clsDeclLine
;
private
boolean
bodyGenStarted
;
public
ClassGen
(
ClassNode
cls
,
JadxArgs
jadxArgs
)
{
public
ClassGen
(
ClassNode
cls
,
JadxArgs
jadxArgs
)
{
this
(
cls
,
null
,
jadxArgs
.
isUseImports
(),
jadxArgs
.
isFallbackMode
(),
jadxArgs
.
isShowInconsistentCode
());
this
(
cls
,
null
,
jadxArgs
.
isUseImports
(),
jadxArgs
.
isFallbackMode
(),
jadxArgs
.
isShowInconsistentCode
());
}
}
...
@@ -222,6 +224,7 @@ public class ClassGen {
...
@@ -222,6 +224,7 @@ public class ClassGen {
public
void
addClassBody
(
CodeWriter
clsCode
)
throws
CodegenException
{
public
void
addClassBody
(
CodeWriter
clsCode
)
throws
CodegenException
{
clsCode
.
add
(
'{'
);
clsCode
.
add
(
'{'
);
setBodyGenStarted
(
true
);
clsDeclLine
=
clsCode
.
getLine
();
clsDeclLine
=
clsCode
.
getLine
();
clsCode
.
incIndent
();
clsCode
.
incIndent
();
addFields
(
clsCode
);
addFields
(
clsCode
);
...
@@ -656,4 +659,12 @@ public class ClassGen {
...
@@ -656,4 +659,12 @@ public class ClassGen {
public
boolean
isFallbackMode
()
{
public
boolean
isFallbackMode
()
{
return
fallback
;
return
fallback
;
}
}
public
boolean
isBodyGenStarted
()
{
return
bodyGenStarted
;
}
public
void
setBodyGenStarted
(
boolean
bodyGenStarted
)
{
this
.
bodyGenStarted
=
bodyGenStarted
;
}
}
}
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
浏览文件 @
cd7e5bf0
...
@@ -183,7 +183,7 @@ public class InsnGen {
...
@@ -183,7 +183,7 @@ public class InsnGen {
ClassInfo
declClass
=
field
.
getDeclClass
();
ClassInfo
declClass
=
field
.
getDeclClass
();
// TODO
// TODO
boolean
fieldFromThisClass
=
clsGen
.
getClassNode
().
getClassInfo
().
equals
(
declClass
);
boolean
fieldFromThisClass
=
clsGen
.
getClassNode
().
getClassInfo
().
equals
(
declClass
);
if
(!
fieldFromThisClass
)
{
if
(!
fieldFromThisClass
||
!
clsGen
.
isBodyGenStarted
()
)
{
// Android specific resources class handler
// Android specific resources class handler
if
(!
handleAppResField
(
code
,
clsGen
,
declClass
))
{
if
(!
handleAppResField
(
code
,
clsGen
,
declClass
))
{
clsGen
.
useClass
(
code
,
declClass
);
clsGen
.
useClass
(
code
,
declClass
);
...
...
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
浏览文件 @
cd7e5bf0
...
@@ -28,6 +28,7 @@ import jadx.core.dex.nodes.InsnNode;
...
@@ -28,6 +28,7 @@ import jadx.core.dex.nodes.InsnNode;
import
jadx.core.dex.nodes.parser.FieldInitAttr
;
import
jadx.core.dex.nodes.parser.FieldInitAttr
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.regions.Region
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.SwitchRegion
;
import
jadx.core.dex.regions.SwitchRegion.CaseInfo
;
import
jadx.core.dex.regions.SynchronizedRegion
;
import
jadx.core.dex.regions.SynchronizedRegion
;
import
jadx.core.dex.regions.TryCatchRegion
;
import
jadx.core.dex.regions.TryCatchRegion
;
import
jadx.core.dex.regions.conditions.IfCondition
;
import
jadx.core.dex.regions.conditions.IfCondition
;
...
@@ -270,10 +271,9 @@ public class RegionGen extends InsnGen {
...
@@ -270,10 +271,9 @@ public class RegionGen extends InsnGen {
code
.
add
(
") {"
);
code
.
add
(
") {"
);
code
.
incIndent
();
code
.
incIndent
();
int
size
=
sw
.
getKeys
().
size
();
for
(
CaseInfo
caseInfo
:
sw
.
getCases
())
{
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
List
<
Object
>
keys
=
caseInfo
.
getKeys
();
List
<
Object
>
keys
=
sw
.
getKeys
().
get
(
i
);
IContainer
c
=
caseInfo
.
getContainer
();
IContainer
c
=
sw
.
getCases
().
get
(
i
);
for
(
Object
k
:
keys
)
{
for
(
Object
k
:
keys
)
{
code
.
startLine
(
"case "
);
code
.
startLine
(
"case "
);
if
(
k
instanceof
FieldNode
)
{
if
(
k
instanceof
FieldNode
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttrNode.java
浏览文件 @
cd7e5bf0
...
@@ -118,6 +118,7 @@ public abstract class AttrNode implements IAttributeNode {
...
@@ -118,6 +118,7 @@ public abstract class AttrNode implements IAttributeNode {
return
storage
.
toString
();
return
storage
.
toString
();
}
}
@Override
public
boolean
isAttrStorageEmpty
()
{
public
boolean
isAttrStorageEmpty
()
{
return
storage
.
isEmpty
();
return
storage
.
isEmpty
();
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/IAttributeNode.java
浏览文件 @
cd7e5bf0
...
@@ -35,4 +35,6 @@ public interface IAttributeNode {
...
@@ -35,4 +35,6 @@ public interface IAttributeNode {
List
<
String
>
getAttributesStringsList
();
List
<
String
>
getAttributesStringsList
();
String
getAttributesString
();
String
getAttributesString
();
boolean
isAttrStorageEmpty
();
}
}
jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
浏览文件 @
cd7e5bf0
...
@@ -110,12 +110,7 @@ public class ConstStorage {
...
@@ -110,12 +110,7 @@ public class ConstStorage {
}
}
private
ValueStorage
getClsValues
(
ClassNode
cls
)
{
private
ValueStorage
getClsValues
(
ClassNode
cls
)
{
ValueStorage
classValues
=
classes
.
get
(
cls
);
return
classes
.
computeIfAbsent
(
cls
,
c
->
new
ValueStorage
());
if
(
classValues
==
null
)
{
classValues
=
new
ValueStorage
();
classes
.
put
(
cls
,
classValues
);
}
return
classValues
;
}
}
@Nullable
@Nullable
...
...
jadx-core/src/main/java/jadx/core/dex/instructions/SwitchNode.java
浏览文件 @
cd7e5bf0
...
@@ -3,6 +3,7 @@ package jadx.core.dex.instructions;
...
@@ -3,6 +3,7 @@ package jadx.core.dex.instructions;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.List
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.instructions.args.InsnArg
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.InsnNode
;
...
@@ -110,15 +111,13 @@ public class SwitchNode extends TargetInsnNode {
...
@@ -110,15 +111,13 @@ public class SwitchNode extends TargetInsnNode {
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
StringBuilder
targ
=
new
StringBuilder
();
StringBuilder
sb
=
new
StringBuilder
();
targ
.
append
(
'['
);
sb
.
append
(
super
.
toString
()
);
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
for
(
int
i
=
0
;
i
<
targets
.
length
;
i
++)
{
targ
.
append
(
InsnUtils
.
formatOffset
(
targets
[
i
]));
sb
.
append
(
" case "
).
append
(
keys
[
i
])
if
(
i
<
targets
.
length
-
1
)
{
.
append
(
": goto "
).
append
(
InsnUtils
.
formatOffset
(
targets
[
i
]));
targ
.
append
(
", "
);
sb
.
append
(
CodeWriter
.
NL
);
}
}
}
return
sb
.
toString
();
targ
.
append
(
']'
);
return
super
.
toString
()
+
" k:"
+
Arrays
.
toString
(
keys
)
+
" t:"
+
targ
;
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
浏览文件 @
cd7e5bf0
package
jadx.core.dex.nodes
;
package
jadx.core.dex.nodes
;
import
java.io.StringWriter
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -555,11 +556,24 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
...
@@ -555,11 +556,24 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
public
String
getSmali
()
{
public
String
getSmali
()
{
if
(
smali
==
null
)
{
if
(
smali
==
null
)
{
smali
=
SmaliUtils
.
getSmaliCode
(
dex
,
clsDefOffset
);
StringWriter
stringWriter
=
new
StringWriter
(
4096
);
getSmali
(
this
,
stringWriter
);
stringWriter
.
append
(
System
.
lineSeparator
());
for
(
ClassNode
innerClass
:
innerClasses
)
{
getSmali
(
innerClass
,
stringWriter
);
stringWriter
.
append
(
System
.
lineSeparator
());
}
smali
=
stringWriter
.
toString
();
}
}
return
smali
;
return
smali
;
}
}
protected
static
boolean
getSmali
(
ClassNode
classNode
,
StringWriter
stringWriter
)
{
stringWriter
.
append
(
String
.
format
(
"###### Class %s (%s)"
,
classNode
.
getFullName
(),
classNode
.
getRawName
()));
stringWriter
.
append
(
System
.
lineSeparator
());
return
SmaliUtils
.
getSmaliCode
(
classNode
.
dex
,
classNode
.
clsDefOffset
,
stringWriter
);
}
public
ProcessState
getState
()
{
public
ProcessState
getState
()
{
return
state
;
return
state
;
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/regions/SwitchRegion.java
浏览文件 @
cd7e5bf0
...
@@ -4,33 +4,50 @@ import java.util.ArrayList;
...
@@ -4,33 +4,50 @@ import java.util.ArrayList;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBranchRegion
;
import
jadx.core.dex.nodes.IBranchRegion
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.utils.Utils
;
public
final
class
SwitchRegion
extends
AbstractRegion
implements
IBranchRegion
{
public
final
class
SwitchRegion
extends
AbstractRegion
implements
IBranchRegion
{
private
final
BlockNode
header
;
private
final
BlockNode
header
;
private
final
List
<
List
<
Object
>>
keys
;
private
final
List
<
CaseInfo
>
cases
;
private
final
List
<
IContainer
>
cases
;
private
IContainer
defCase
;
private
IContainer
defCase
;
public
SwitchRegion
(
IRegion
parent
,
BlockNode
header
)
{
public
SwitchRegion
(
IRegion
parent
,
BlockNode
header
)
{
super
(
parent
);
super
(
parent
);
this
.
header
=
header
;
this
.
header
=
header
;
this
.
keys
=
new
ArrayList
<>();
this
.
cases
=
new
ArrayList
<>();
this
.
cases
=
new
ArrayList
<>();
}
}
public
static
final
class
CaseInfo
{
private
final
List
<
Object
>
keys
;
private
final
IContainer
container
;
public
CaseInfo
(
List
<
Object
>
keys
,
IContainer
container
)
{
this
.
keys
=
keys
;
this
.
container
=
container
;
}
public
List
<
Object
>
getKeys
()
{
return
keys
;
}
public
IContainer
getContainer
()
{
return
container
;
}
}
public
BlockNode
getHeader
()
{
public
BlockNode
getHeader
()
{
return
header
;
return
header
;
}
}
public
void
addCase
(
List
<
Object
>
keysList
,
IContainer
c
)
{
public
void
addCase
(
List
<
Object
>
keysList
,
IContainer
c
)
{
keys
.
add
(
keysList
);
cases
.
add
(
new
CaseInfo
(
keysList
,
c
));
cases
.
add
(
c
);
}
}
public
void
setDefaultCase
(
IContainer
block
)
{
public
void
setDefaultCase
(
IContainer
block
)
{
...
@@ -41,19 +58,19 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
...
@@ -41,19 +58,19 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
return
defCase
;
return
defCase
;
}
}
public
List
<
List
<
Object
>>
getKey
s
()
{
public
List
<
CaseInfo
>
getCase
s
()
{
return
key
s
;
return
case
s
;
}
}
public
List
<
IContainer
>
getCases
()
{
public
List
<
IContainer
>
getCase
Container
s
()
{
return
cases
;
return
Utils
.
collectionMap
(
cases
,
caseInfo
->
caseInfo
.
container
)
;
}
}
@Override
@Override
public
List
<
IContainer
>
getSubBlocks
()
{
public
List
<
IContainer
>
getSubBlocks
()
{
List
<
IContainer
>
all
=
new
ArrayList
<>(
cases
.
size
()
+
2
);
List
<
IContainer
>
all
=
new
ArrayList
<>(
cases
.
size
()
+
2
);
all
.
add
(
header
);
all
.
add
(
header
);
all
.
addAll
(
cases
);
all
.
addAll
(
getCaseContainers
()
);
if
(
defCase
!=
null
)
{
if
(
defCase
!=
null
)
{
all
.
add
(
defCase
);
all
.
add
(
defCase
);
}
}
...
@@ -63,7 +80,7 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
...
@@ -63,7 +80,7 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
@Override
@Override
public
List
<
IContainer
>
getBranches
()
{
public
List
<
IContainer
>
getBranches
()
{
List
<
IContainer
>
branches
=
new
ArrayList
<>(
cases
.
size
()
+
1
);
List
<
IContainer
>
branches
=
new
ArrayList
<>(
cases
.
size
()
+
1
);
branches
.
addAll
(
cases
);
branches
.
addAll
(
getCaseContainers
()
);
if
(
defCase
!=
null
)
{
if
(
defCase
!=
null
)
{
branches
.
add
(
defCase
);
branches
.
add
(
defCase
);
}
}
...
@@ -77,6 +94,16 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
...
@@ -77,6 +94,16 @@ public final class SwitchRegion extends AbstractRegion implements IBranchRegion
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
"Switch: "
+
cases
.
size
()
+
", default: "
+
defCase
;
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
"Switch: "
).
append
(
cases
.
size
());
for
(
CaseInfo
caseInfo
:
cases
)
{
sb
.
append
(
CodeWriter
.
NL
).
append
(
" case "
)
.
append
(
Utils
.
listToString
(
caseInfo
.
getKeys
()))
.
append
(
" -> "
).
append
(
caseInfo
.
getContainer
());
}
if
(
defCase
!=
null
)
{
sb
.
append
(
CodeWriter
.
NL
).
append
(
" default -> "
).
append
(
defCase
);
}
return
sb
.
toString
();
}
}
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
浏览文件 @
cd7e5bf0
...
@@ -11,6 +11,9 @@ import org.slf4j.LoggerFactory;
...
@@ -11,6 +11,9 @@ import org.slf4j.LoggerFactory;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.AttrNode
;
import
jadx.core.dex.attributes.annotations.Annotation
;
import
jadx.core.dex.attributes.annotations.AnnotationsList
;
import
jadx.core.dex.attributes.nodes.FieldReplaceAttr
;
import
jadx.core.dex.attributes.nodes.FieldReplaceAttr
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.info.MethodInfo
;
import
jadx.core.dex.info.MethodInfo
;
...
@@ -46,6 +49,7 @@ import jadx.core.dex.visitors.shrink.CodeShrinkVisitor;
...
@@ -46,6 +49,7 @@ import jadx.core.dex.visitors.shrink.CodeShrinkVisitor;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.InsnRemover
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
static
jadx
.
core
.
utils
.
BlockUtils
.
replaceInsn
;
import
static
jadx
.
core
.
utils
.
BlockUtils
.
replaceInsn
;
...
@@ -68,6 +72,12 @@ public class ModVisitor extends AbstractVisitor {
...
@@ -68,6 +72,12 @@ public class ModVisitor extends AbstractVisitor {
private
static
final
long
DOUBLE_TO_BITS
=
Double
.
doubleToLongBits
(
1
);
private
static
final
long
DOUBLE_TO_BITS
=
Double
.
doubleToLongBits
(
1
);
private
static
final
long
FLOAT_TO_BITS
=
Float
.
floatToIntBits
(
1
);
private
static
final
long
FLOAT_TO_BITS
=
Float
.
floatToIntBits
(
1
);
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
JadxException
{
replaceConstInAnnotations
(
cls
);
return
true
;
}
@Override
@Override
public
void
visit
(
MethodNode
mth
)
{
public
void
visit
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
{
if
(
mth
.
isNoCode
())
{
...
@@ -171,6 +181,33 @@ public class ModVisitor extends AbstractVisitor {
...
@@ -171,6 +181,33 @@ public class ModVisitor extends AbstractVisitor {
}
}
}
}
private
void
replaceConstInAnnotations
(
ClassNode
cls
)
{
if
(
cls
.
root
().
getArgs
().
isReplaceConsts
())
{
replaceConstsInAnnotationForAttrNode
(
cls
,
cls
);
cls
.
getFields
().
forEach
(
f
->
replaceConstsInAnnotationForAttrNode
(
cls
,
f
));
cls
.
getMethods
().
forEach
(
m
->
replaceConstsInAnnotationForAttrNode
(
cls
,
m
));
}
}
private
void
replaceConstsInAnnotationForAttrNode
(
ClassNode
parentCls
,
AttrNode
attrNode
)
{
AnnotationsList
annotationsList
=
attrNode
.
get
(
AType
.
ANNOTATION_LIST
);
if
(
annotationsList
==
null
)
{
return
;
}
for
(
Annotation
annotation
:
annotationsList
.
getAll
())
{
if
(
annotation
.
getVisibility
()
==
Annotation
.
Visibility
.
SYSTEM
)
{
continue
;
}
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
annotation
.
getValues
().
entrySet
())
{
Object
value
=
entry
.
getValue
();
FieldNode
constField
=
parentCls
.
getConstField
(
value
);
if
(
constField
!=
null
)
{
entry
.
setValue
(
constField
.
getFieldInfo
());
}
}
}
}
private
static
void
replaceConst
(
MethodNode
mth
,
ClassNode
parentClass
,
BlockNode
block
,
int
i
,
InsnNode
insn
)
{
private
static
void
replaceConst
(
MethodNode
mth
,
ClassNode
parentClass
,
BlockNode
block
,
int
i
,
InsnNode
insn
)
{
FieldNode
f
;
FieldNode
f
;
if
(
insn
.
getType
()
==
InsnType
.
CONST_STR
)
{
if
(
insn
.
getType
()
==
InsnType
.
CONST_STR
)
{
...
...
jadx-core/src/main/java/jadx/core/export/TemplateFile.java
浏览文件 @
cd7e5bf0
...
@@ -16,8 +16,6 @@ import org.jetbrains.annotations.Nullable;
...
@@ -16,8 +16,6 @@ import org.jetbrains.annotations.Nullable;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
static
jadx
.
core
.
utils
.
files
.
FileUtils
.
close
;
/**
/**
* Simple template engine
* Simple template engine
* Syntax for replace variable with value: '{{variable}}'
* Syntax for replace variable with value: '{{variable}}'
...
@@ -56,21 +54,15 @@ public class TemplateFile {
...
@@ -56,21 +54,15 @@ public class TemplateFile {
}
}
public
String
build
()
throws
IOException
{
public
String
build
()
throws
IOException
{
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
try
(
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
())
{
try
{
process
(
out
);
process
(
out
);
}
finally
{
close
(
out
);
}
return
out
.
toString
();
return
out
.
toString
();
}
}
}
public
void
save
(
File
outFile
)
throws
IOException
{
public
void
save
(
File
outFile
)
throws
IOException
{
OutputStream
out
=
new
FileOutputStream
(
outFile
);
try
(
OutputStream
out
=
new
FileOutputStream
(
outFile
))
{
try
{
process
(
out
);
process
(
out
);
}
finally
{
close
(
out
);
}
}
}
}
...
...
jadx-core/src/main/java/jadx/core/utils/DebugUtils.java
浏览文件 @
cd7e5bf0
package
jadx.core.utils
;
package
jadx.core.utils
;
import
java.io.File
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.Iterator
;
import
java.util.LinkedHashSet
;
import
java.util.LinkedHashSet
;
import
java.util.
Map
;
import
java.util.
List
;
import
java.util.Set
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
org.jetbrains.annotations.TestOnly
;
import
org.jetbrains.annotations.TestOnly
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
...
@@ -12,6 +15,7 @@ import org.slf4j.LoggerFactory;
...
@@ -12,6 +15,7 @@ import org.slf4j.LoggerFactory;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.codegen.InsnGen
;
import
jadx.core.codegen.InsnGen
;
import
jadx.core.codegen.MethodGen
;
import
jadx.core.codegen.MethodGen
;
import
jadx.core.dex.attributes.IAttributeNode
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IContainer
;
import
jadx.core.dex.nodes.IContainer
;
...
@@ -85,51 +89,74 @@ public class DebugUtils {
...
@@ -85,51 +89,74 @@ public class DebugUtils {
printRegions
(
mth
,
false
);
printRegions
(
mth
,
false
);
}
}
public
static
void
printRegion
(
MethodNode
mth
,
IRegion
region
,
boolean
printInsn
)
{
public
static
void
printRegion
s
(
MethodNode
mth
,
boolean
printInsns
)
{
printRegion
(
mth
,
region
,
""
,
printInsn
);
printRegion
(
mth
,
mth
.
getRegion
(),
printInsns
);
}
}
public
static
void
printRegions
(
MethodNode
mth
,
boolean
printInsns
)
{
public
static
void
printRegion
(
MethodNode
mth
,
IRegion
region
,
boolean
printInsns
)
{
LOG
.
debug
(
"|{}"
,
mth
);
CodeWriter
cw
=
new
CodeWriter
();
printRegion
(
mth
,
mth
.
getRegion
(),
"| "
,
printInsns
);
cw
.
startLine
(
'|'
).
add
(
mth
.
toString
());
printRegion
(
mth
,
region
,
cw
,
"| "
,
printInsns
);
LOG
.
debug
(
"\n{}"
,
cw
.
finish
().
getCodeStr
());
}
}
private
static
void
printRegion
(
MethodNode
mth
,
IRegion
region
,
String
indent
,
boolean
printInsns
)
{
private
static
void
printRegion
(
MethodNode
mth
,
IRegion
region
,
CodeWriter
cw
,
String
indent
,
boolean
printInsns
)
{
LOG
.
debug
(
"{}{} {}"
,
indent
,
region
,
region
.
getAttributesString
()
);
printWithAttributes
(
cw
,
indent
,
region
.
toString
(),
region
);
indent
+=
"| "
;
indent
+=
"| "
;
for
(
IContainer
container
:
region
.
getSubBlocks
())
{
for
(
IContainer
container
:
region
.
getSubBlocks
())
{
if
(
container
instanceof
IRegion
)
{
if
(
container
instanceof
IRegion
)
{
printRegion
(
mth
,
(
IRegion
)
container
,
indent
,
printInsns
);
printRegion
(
mth
,
(
IRegion
)
container
,
cw
,
indent
,
printInsns
);
}
else
{
}
else
{
LOG
.
debug
(
"{}{} {}"
,
indent
,
container
,
container
.
getAttributesString
()
);
printWithAttributes
(
cw
,
indent
,
container
.
toString
(),
container
);
if
(
printInsns
&&
container
instanceof
IBlock
)
{
if
(
printInsns
&&
container
instanceof
IBlock
)
{
IBlock
block
=
(
IBlock
)
container
;
IBlock
block
=
(
IBlock
)
container
;
printInsns
(
mth
,
indent
,
block
);
printInsns
(
mth
,
cw
,
indent
,
block
);
}
}
}
}
}
}
}
}
private
static
void
printInsns
(
MethodNode
mth
,
String
indent
,
IBlock
block
)
{
private
static
void
printInsns
(
MethodNode
mth
,
CodeWriter
cw
,
String
indent
,
IBlock
block
)
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
try
{
try
{
MethodGen
mg
=
MethodGen
.
getFallbackMethodGen
(
mth
);
MethodGen
mg
=
MethodGen
.
getFallbackMethodGen
(
mth
);
InsnGen
ig
=
new
InsnGen
(
mg
,
true
);
InsnGen
ig
=
new
InsnGen
(
mg
,
true
);
CodeWriter
code
=
new
CodeWriter
();
CodeWriter
code
=
new
CodeWriter
();
ig
.
makeInsn
(
insn
,
code
);
ig
.
makeInsn
(
insn
,
code
);
String
insnStr
=
code
.
toString
().
substring
(
CodeWriter
.
NL
.
length
());
String
codeStr
=
code
.
finish
().
getCodeStr
();
String
attrStr
=
insn
.
isAttrStorageEmpty
()
?
""
:
'\t'
+
insn
.
getAttributesString
();
LOG
.
debug
(
"{}|> {}{}"
,
indent
,
insnStr
,
attrStr
);
List
<
String
>
insnStrings
=
Arrays
.
stream
(
codeStr
.
split
(
CodeWriter
.
NL
))
.
filter
(
StringUtils:
:
notBlank
)
.
map
(
s
->
"|> "
+
s
)
.
collect
(
Collectors
.
toList
());
Iterator
<
String
>
it
=
insnStrings
.
iterator
();
while
(
true
)
{
String
insnStr
=
it
.
next
();
if
(
it
.
hasNext
())
{
cw
.
startLine
(
indent
).
add
(
insnStr
);
}
else
{
printWithAttributes
(
cw
,
indent
,
insnStr
,
insn
);
break
;
}
}
}
catch
(
CodegenException
e
)
{
}
catch
(
CodegenException
e
)
{
LOG
.
debug
(
"{}|>!! {}"
,
indent
,
insn
);
cw
.
startLine
(
indent
).
add
(
">!! "
).
add
(
insn
.
toString
()
);
}
}
}
}
}
}
public
static
void
printMap
(
String
desc
,
Map
<?,
?>
map
)
{
private
static
void
printWithAttributes
(
CodeWriter
cw
,
String
indent
,
String
codeStr
,
IAttributeNode
attrNode
)
{
LOG
.
debug
(
"Map of {}, size: {}"
,
desc
,
map
.
size
());
String
str
=
attrNode
.
isAttrStorageEmpty
()
?
codeStr
:
codeStr
+
' '
+
attrNode
.
getAttributesString
();
for
(
Map
.
Entry
<?,
?>
entry
:
map
.
entrySet
())
{
List
<
String
>
attrStrings
=
Arrays
.
stream
(
str
.
split
(
CodeWriter
.
NL
))
LOG
.
debug
(
" {} : {}"
,
entry
.
getKey
(),
entry
.
getValue
());
.
filter
(
StringUtils:
:
notBlank
)
.
collect
(
Collectors
.
toList
());
Iterator
<
String
>
it
=
attrStrings
.
iterator
();
if
(!
it
.
hasNext
())
{
return
;
}
cw
.
startLine
(
indent
).
add
(
it
.
next
());
while
(
it
.
hasNext
())
{
cw
.
startLine
(
indent
).
add
(
"|+ "
).
add
(
it
.
next
());
}
}
}
}
}
}
jadx-core/src/main/java/jadx/core/utils/SmaliUtils.java
浏览文件 @
cd7e5bf0
...
@@ -4,7 +4,6 @@ import java.io.IOException;
...
@@ -4,7 +4,6 @@ import java.io.IOException;
import
java.io.StringWriter
;
import
java.io.StringWriter
;
import
java.nio.file.Path
;
import
java.nio.file.Path
;
import
org.jetbrains.annotations.NotNull
;
import
org.jf.baksmali.Adaptors.ClassDefinition
;
import
org.jf.baksmali.Adaptors.ClassDefinition
;
import
org.jf.baksmali.BaksmaliOptions
;
import
org.jf.baksmali.BaksmaliOptions
;
import
org.jf.dexlib2.DexFileFactory
;
import
org.jf.dexlib2.DexFileFactory
;
...
@@ -34,24 +33,25 @@ public class SmaliUtils {
...
@@ -34,24 +33,25 @@ public class SmaliUtils {
}
}
}
}
@NotNull
public
static
boolean
getSmaliCode
(
DexNode
dex
,
int
clsDefOffset
,
StringWriter
stringWriter
)
{
public
static
String
getSmaliCode
(
DexNode
dex
,
int
clsDefOffset
)
{
try
{
try
{
Path
path
=
dex
.
getDexFile
().
getPath
();
Path
path
=
dex
.
getDexFile
().
getPath
();
DexBackedDexFile
dexFile
=
DexFileFactory
.
loadDexFile
(
path
.
toFile
(),
null
);
DexBackedDexFile
dexFile
=
DexFileFactory
.
loadDexFile
(
path
.
toFile
(),
null
);
DexBackedClassDef
dexBackedClassDef
=
new
DexBackedClassDef
(
dexFile
,
clsDefOffset
);
DexBackedClassDef
dexBackedClassDef
=
new
DexBackedClassDef
(
dexFile
,
clsDefOffset
);
return
getSmaliCode
(
dexBackedClassDef
);
getSmaliCode
(
dexBackedClassDef
,
stringWriter
);
return
true
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error generating smali"
,
e
);
LOG
.
error
(
"Error generating smali"
,
e
);
return
"Error generating smali code: "
+
e
.
getMessage
()
stringWriter
.
append
(
"Error generating smali code: "
);
+
'\n'
+
Utils
.
getStackTrace
(
e
);
stringWriter
.
append
(
e
.
getMessage
());
stringWriter
.
append
(
System
.
lineSeparator
());
stringWriter
.
append
(
Utils
.
getStackTrace
(
e
));
return
false
;
}
}
}
}
private
static
String
getSmaliCode
(
DexBackedClassDef
classDef
)
throws
IOException
{
private
static
void
getSmaliCode
(
DexBackedClassDef
classDef
,
StringWriter
stringWriter
)
throws
IOException
{
ClassDefinition
classDefinition
=
new
ClassDefinition
(
new
BaksmaliOptions
(),
classDef
);
ClassDefinition
classDefinition
=
new
ClassDefinition
(
new
BaksmaliOptions
(),
classDef
);
StringWriter
sw
=
new
StringWriter
();
classDefinition
.
writeTo
(
new
IndentingWriter
(
stringWriter
));
classDefinition
.
writeTo
(
new
IndentingWriter
(
sw
));
return
sw
.
toString
();
}
}
}
}
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
浏览文件 @
cd7e5bf0
...
@@ -211,6 +211,10 @@ public class StringUtils {
...
@@ -211,6 +211,10 @@ public class StringUtils {
return
str
==
null
||
str
.
isEmpty
();
return
str
==
null
||
str
.
isEmpty
();
}
}
public
static
boolean
notBlank
(
String
str
)
{
return
notEmpty
(
str
)
&&
!
str
.
trim
().
isEmpty
();
}
public
static
int
countMatches
(
String
str
,
String
subStr
)
{
public
static
int
countMatches
(
String
str
,
String
subStr
)
{
if
(
str
==
null
||
str
.
isEmpty
()
||
subStr
==
null
||
subStr
.
isEmpty
())
{
if
(
str
==
null
||
str
.
isEmpty
()
||
subStr
==
null
||
subStr
.
isEmpty
())
{
return
0
;
return
0
;
...
...
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
浏览文件 @
cd7e5bf0
...
@@ -10,12 +10,15 @@ import java.io.InputStream;
...
@@ -10,12 +10,15 @@ import java.io.InputStream;
import
java.io.OutputStream
;
import
java.io.OutputStream
;
import
java.nio.file.Files
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Comparator
;
import
java.util.Enumeration
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Objects
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarOutputStream
;
import
java.util.jar.JarOutputStream
;
import
java.util.stream.Stream
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipEntry
;
import
java.util.zip.ZipFile
;
import
java.util.zip.ZipFile
;
...
@@ -32,6 +35,9 @@ public class FileUtils {
...
@@ -32,6 +35,9 @@ public class FileUtils {
public
static
final
int
READ_BUFFER_SIZE
=
8
*
1024
;
public
static
final
int
READ_BUFFER_SIZE
=
8
*
1024
;
private
static
final
int
MAX_FILENAME_LENGTH
=
128
;
private
static
final
int
MAX_FILENAME_LENGTH
=
128
;
public
static
final
String
JADX_TMP_INSTANCE_PREFIX
=
"jadx-instance-"
;
public
static
final
String
JADX_TMP_PREFIX
=
"jadx-tmp-"
;
private
FileUtils
()
{
private
FileUtils
()
{
}
}
...
@@ -70,6 +76,12 @@ public class FileUtils {
...
@@ -70,6 +76,12 @@ public class FileUtils {
}
}
}
}
public
static
void
makeDirs
(
@Nullable
Path
dir
)
{
if
(
dir
!=
null
)
{
makeDirs
(
dir
.
toFile
());
}
}
public
static
boolean
deleteDir
(
File
dir
)
{
public
static
boolean
deleteDir
(
File
dir
)
{
File
[]
content
=
dir
.
listFiles
();
File
[]
content
=
dir
.
listFiles
();
if
(
content
!=
null
)
{
if
(
content
!=
null
)
{
...
@@ -80,11 +92,27 @@ public class FileUtils {
...
@@ -80,11 +92,27 @@ public class FileUtils {
return
dir
.
delete
();
return
dir
.
delete
();
}
}
public
static
void
deleteDir
(
Path
dir
)
{
try
(
Stream
<
Path
>
pathStream
=
Files
.
walk
(
dir
))
{
pathStream
.
sorted
(
Comparator
.
reverseOrder
())
.
map
(
Path:
:
toFile
)
.
forEach
(
File:
:
delete
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Failed to delete directory "
+
dir
,
e
);
}
}
private
static
final
Path
TEMP_ROOT_DIR
=
createTempRootDir
();
private
static
final
Path
TEMP_ROOT_DIR
=
createTempRootDir
();
private
static
Path
createTempRootDir
()
{
private
static
Path
createTempRootDir
()
{
try
{
try
{
Path
dir
=
Files
.
createTempDirectory
(
"jadx-instance-"
);
String
jadxTmpDir
=
System
.
getenv
(
"JADX_TMP_DIR"
);
Path
dir
;
if
(
jadxTmpDir
!=
null
)
{
dir
=
Files
.
createTempDirectory
(
Paths
.
get
(
jadxTmpDir
),
"jadx-instance-"
);
}
else
{
dir
=
Files
.
createTempDirectory
(
JADX_TMP_INSTANCE_PREFIX
);
}
dir
.
toFile
().
deleteOnExit
();
dir
.
toFile
().
deleteOnExit
();
return
dir
;
return
dir
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -92,6 +120,15 @@ public class FileUtils {
...
@@ -92,6 +120,15 @@ public class FileUtils {
}
}
}
}
public
static
void
deleteTempRootDir
()
{
deleteDir
(
TEMP_ROOT_DIR
);
}
public
static
void
clearTempRootDir
()
{
deleteDir
(
TEMP_ROOT_DIR
);
makeDirs
(
TEMP_ROOT_DIR
);
}
public
static
Path
createTempDir
(
String
prefix
)
{
public
static
Path
createTempDir
(
String
prefix
)
{
try
{
try
{
Path
dir
=
Files
.
createTempDirectory
(
TEMP_ROOT_DIR
,
prefix
);
Path
dir
=
Files
.
createTempDirectory
(
TEMP_ROOT_DIR
,
prefix
);
...
@@ -104,7 +141,7 @@ public class FileUtils {
...
@@ -104,7 +141,7 @@ public class FileUtils {
public
static
Path
createTempFile
(
String
suffix
)
{
public
static
Path
createTempFile
(
String
suffix
)
{
try
{
try
{
Path
path
=
Files
.
createTempFile
(
TEMP_ROOT_DIR
,
"jadx-tmp-"
,
suffix
);
Path
path
=
Files
.
createTempFile
(
TEMP_ROOT_DIR
,
JADX_TMP_PREFIX
,
suffix
);
path
.
toFile
().
deleteOnExit
();
path
.
toFile
().
deleteOnExit
();
return
path
;
return
path
;
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -112,6 +149,14 @@ public class FileUtils {
...
@@ -112,6 +149,14 @@ public class FileUtils {
}
}
}
}
public
static
Path
createTempFileNoDelete
(
String
suffix
)
{
try
{
return
Files
.
createTempFile
(
TEMP_ROOT_DIR
,
JADX_TMP_PREFIX
,
suffix
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Failed to create temp file with suffix: "
+
suffix
,
e
);
}
}
public
static
void
copyStream
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
public
static
void
copyStream
(
InputStream
input
,
OutputStream
output
)
throws
IOException
{
byte
[]
buffer
=
new
byte
[
READ_BUFFER_SIZE
];
byte
[]
buffer
=
new
byte
[
READ_BUFFER_SIZE
];
while
(
true
)
{
while
(
true
)
{
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
浏览文件 @
cd7e5bf0
...
@@ -6,7 +6,6 @@ import java.io.IOException;
...
@@ -6,7 +6,6 @@ import java.io.IOException;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Modifier
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.Path
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
...
@@ -21,6 +20,7 @@ import java.util.concurrent.TimeUnit;
...
@@ -21,6 +20,7 @@ import java.util.concurrent.TimeUnit;
import
java.util.concurrent.TimeoutException
;
import
java.util.concurrent.TimeoutException
;
import
java.util.jar.JarOutputStream
;
import
java.util.jar.JarOutputStream
;
import
org.junit.jupiter.api.AfterEach
;
import
org.junit.jupiter.api.BeforeEach
;
import
org.junit.jupiter.api.BeforeEach
;
import
jadx.api.ICodeInfo
;
import
jadx.api.ICodeInfo
;
...
@@ -119,6 +119,11 @@ public abstract class IntegrationTest extends TestUtils {
...
@@ -119,6 +119,11 @@ public abstract class IntegrationTest extends TestUtils {
args
.
setFsCaseSensitive
(
false
);
// use same value on all systems
args
.
setFsCaseSensitive
(
false
);
// use same value on all systems
}
}
@AfterEach
public
void
after
()
{
FileUtils
.
clearTempRootDir
();
}
public
String
getTestName
()
{
public
String
getTestName
()
{
return
this
.
getClass
().
getSimpleName
();
return
this
.
getClass
().
getSimpleName
();
}
}
...
@@ -414,7 +419,7 @@ public abstract class IntegrationTest extends TestUtils {
...
@@ -414,7 +419,7 @@ public abstract class IntegrationTest extends TestUtils {
temp
=
FileUtils
.
createTempFile
(
suffix
);
temp
=
FileUtils
.
createTempFile
(
suffix
);
}
else
{
}
else
{
// don't delete on exit
// don't delete on exit
temp
=
File
s
.
createTempFile
(
"jadx"
,
suffix
);
temp
=
File
Utils
.
createTempFileNoDelete
(
suffix
);
System
.
out
.
println
(
"Temporary file saved: "
+
temp
.
toAbsolutePath
());
System
.
out
.
println
(
"Temporary file saved: "
+
temp
.
toAbsolutePath
());
}
}
return
temp
.
toFile
();
return
temp
.
toFile
();
...
...
jadx-core/src/test/java/jadx/tests/integration/inner/TestRFieldRestore3.java
0 → 100644
浏览文件 @
cd7e5bf0
package
jadx.tests.integration.inner
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestRFieldRestore3
extends
IntegrationTest
{
public
static
class
TestCls
{
@T
(
2131230730
)
public
static
class
A
{
@F
(
2131230730
)
private
int
f
;
@M
(
bind
=
2137373737
)
private
void
mth
()
{
}
@T
(
2137373737
)
private
class
D
{
}
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
@interface
T
{
int
value
();
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
FIELD
})
@interface
F
{
int
value
();
}
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
METHOD
})
@interface
M
{
int
bind
();
}
public
static
class
R
{
}
}
@Test
public
void
test
()
{
Map
<
Integer
,
String
>
map
=
new
HashMap
<>();
map
.
put
(
2131230730
,
"id.Button"
);
map
.
put
(
2137373737
,
"id.MyId"
);
setResMap
(
map
);
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
containsOnlyOnce
(
"@T(R.id.Button)"
)
.
containsOnlyOnce
(
"@T(R.id.MyId)"
)
.
containsOnlyOnce
(
"@F(R.id.Button)"
)
.
containsOnlyOnce
(
"@M(bind = R.id.MyId)"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/inner/TestReplaceConstsInAnnotations.java
0 → 100644
浏览文件 @
cd7e5bf0
package
jadx.tests.integration.inner
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestReplaceConstsInAnnotations
extends
IntegrationTest
{
public
static
class
TestCls
{
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
A
{
int
i
();
float
f
();
}
@A
(
i
=
-
1
,
f
=
C
.
FLOAT_CONST
)
public
static
class
C
{
public
static
final
float
FLOAT_CONST
=
3.14f
;
}
}
@Test
public
void
test
()
{
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
containsOnlyOnce
(
"f = C.FLOAT_CONST"
);
}
}
jadx-core/src/test/java/jadx/tests/integration/switches/TestSwitchFallThrough.java
0 → 100644
浏览文件 @
cd7e5bf0
package
jadx.tests.integration.switches
;
import
org.junit.jupiter.api.Test
;
import
jadx.NotYetImplemented
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestSwitchFallThrough
extends
IntegrationTest
{
public
static
class
TestCls
{
public
int
r
;
public
void
test
(
int
a
)
{
int
i
=
10
;
switch
(
a
)
{
case
1
:
i
=
1000
;
// fallthrough
case
2
:
r
=
i
;
break
;
default
:
r
=
-
1
;
break
;
}
r
*=
2
;
System
.
out
.
println
(
"in: "
+
a
+
", out: "
+
r
);
}
public
int
testWrap
(
int
a
)
{
r
=
0
;
test
(
a
);
return
r
;
}
public
void
check
()
{
assertThat
(
testWrap
(
1
)).
isEqualTo
(
2000
);
assertThat
(
testWrap
(
2
)).
isEqualTo
(
20
);
assertThat
(
testWrap
(
0
)).
isEqualTo
(-
2
);
}
}
@NotYetImplemented
(
"switch fallthrough"
)
@Test
public
void
test
()
{
assertThat
(
getClassNode
(
TestCls
.
class
))
.
code
()
.
containsOnlyOnce
(
"switch"
);
// code correctness checks done in 'check' method
}
}
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
浏览文件 @
cd7e5bf0
...
@@ -77,6 +77,7 @@ import jadx.api.JadxArgs;
...
@@ -77,6 +77,7 @@ import jadx.api.JadxArgs;
import
jadx.api.JavaClass
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaNode
;
import
jadx.api.JavaNode
;
import
jadx.api.ResourceFile
;
import
jadx.api.ResourceFile
;
import
jadx.core.utils.files.FileUtils
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.jobs.BackgroundExecutor
;
import
jadx.gui.jobs.BackgroundExecutor
;
import
jadx.gui.jobs.BackgroundWorker
;
import
jadx.gui.jobs.BackgroundWorker
;
...
@@ -1109,6 +1110,8 @@ public class MainWindow extends JFrame {
...
@@ -1109,6 +1110,8 @@ public class MainWindow extends JFrame {
settings
.
setMainWindowExtendedState
(
getExtendedState
());
settings
.
setMainWindowExtendedState
(
getExtendedState
());
cancelBackgroundJobs
();
cancelBackgroundJobs
();
dispose
();
dispose
();
FileUtils
.
deleteTempRootDir
();
System
.
exit
(
0
);
System
.
exit
(
0
);
}
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/codearea/SearchBar.java
浏览文件 @
cd7e5bf0
...
@@ -40,7 +40,6 @@ class SearchBar extends JToolBar {
...
@@ -40,7 +40,6 @@ class SearchBar extends JToolBar {
private
final
JCheckBox
wholeWordCB
;
private
final
JCheckBox
wholeWordCB
;
private
final
JCheckBox
matchCaseCB
;
private
final
JCheckBox
matchCaseCB
;
private
ActionListener
forwardListener
=
e
->
search
(
0
);
public
SearchBar
(
RSyntaxTextArea
textArea
)
{
public
SearchBar
(
RSyntaxTextArea
textArea
)
{
rTextArea
=
textArea
;
rTextArea
=
textArea
;
...
@@ -81,6 +80,8 @@ class SearchBar extends JToolBar {
...
@@ -81,6 +80,8 @@ class SearchBar extends JToolBar {
nextButton
.
setBorderPainted
(
false
);
nextButton
.
setBorderPainted
(
false
);
add
(
nextButton
);
add
(
nextButton
);
ActionListener
forwardListener
=
e
->
search
(
0
);
markAllCB
=
new
JCheckBox
(
NLS
.
str
(
"search.mark_all"
));
markAllCB
=
new
JCheckBox
(
NLS
.
str
(
"search.mark_all"
));
markAllCB
.
addActionListener
(
forwardListener
);
markAllCB
.
addActionListener
(
forwardListener
);
add
(
markAllCB
);
add
(
markAllCB
);
...
...
jadx-gui/src/main/java/jadx/gui/utils/SystemInfo.java
浏览文件 @
cd7e5bf0
...
@@ -17,4 +17,7 @@ public class SystemInfo {
...
@@ -17,4 +17,7 @@ public class SystemInfo {
public
static
final
boolean
IS_WINDOWS
=
LOWER_OS_NAME
.
startsWith
(
"windows"
);
public
static
final
boolean
IS_WINDOWS
=
LOWER_OS_NAME
.
startsWith
(
"windows"
);
public
static
final
boolean
IS_MAC
=
LOWER_OS_NAME
.
startsWith
(
"mac"
);
public
static
final
boolean
IS_MAC
=
LOWER_OS_NAME
.
startsWith
(
"mac"
);
public
static
final
boolean
IS_LINUX
=
LOWER_OS_NAME
.
startsWith
(
"linux"
);
public
static
final
boolean
IS_LINUX
=
LOWER_OS_NAME
.
startsWith
(
"linux"
);
private
SystemInfo
()
{
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录