Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
365c1faf
Commit
365c1faf
authored
Mar 20, 2019
by
Skylot
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into type-inference-wip
parents
cf79a519
9797fe5b
Hide whitespace changes
Inline
Side-by-side
Showing
44 changed files
with
515 additions
and
228 deletions
+515
-228
.travis.yml
.travis.yml
+18
-32
build.gradle
build.gradle
+3
-3
gradle-wrapper.properties
gradle/wrapper/gradle-wrapper.properties
+1
-1
build.gradle
jadx-core/build.gradle
+9
-5
JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+6
-8
ProcessClass.java
jadx-core/src/main/java/jadx/core/ProcessClass.java
+5
-7
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+1
-1
CodeGen.java
jadx-core/src/main/java/jadx/core/codegen/CodeGen.java
+11
-6
CodeWriter.java
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
+5
-2
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+3
-10
ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+25
-1
InsnNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
+20
-0
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+12
-4
ClassModifier.java
...e/src/main/java/jadx/core/dex/visitors/ClassModifier.java
+27
-20
DependencyCollector.java
...main/java/jadx/core/dex/visitors/DependencyCollector.java
+7
-0
RegionUtils.java
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
+6
-1
AndroidResourcesUtils.java
...n/java/jadx/core/utils/android/AndroidResourcesUtils.java
+55
-11
InputFile.java
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
+2
-2
BinaryXMLParser.java
...-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
+10
-33
IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+2
-2
ClassFileManager.java
...c/test/java/jadx/tests/api/compiler/ClassFileManager.java
+0
-2
BaseExternalTest.java
...e/src/test/java/jadx/tests/external/BaseExternalTest.java
+3
-9
TestInnerClassFakeSyntheticConstructor.java
...gration/inner/TestInnerClassFakeSyntheticConstructor.java
+0
-1
TestInnerClassSyntheticConstructor.java
...integration/inner/TestInnerClassSyntheticConstructor.java
+0
-4
TestEndlessLoop.java
...st/java/jadx/tests/integration/loops/TestEndlessLoop.java
+0
-1
TestSwitchReturnFromCase2.java
...tests/integration/switches/TestSwitchReturnFromCase2.java
+0
-2
TestTryCatchStartOnMove.java
...x/tests/integration/trycatch/TestTryCatchStartOnMove.java
+33
-0
TestTryCatchStartOnMove.smali
...ore/src/test/smali/trycatch/TestTryCatchStartOnMove.smali
+45
-0
build.gradle
jadx-gui/build.gradle
+7
-6
JadxWrapper.java
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
+24
-5
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+1
-0
JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+4
-0
JPackage.java
jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java
+35
-10
JResource.java
jadx-gui/src/main/java/jadx/gui/treemodel/JResource.java
+9
-0
JSources.java
jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java
+3
-3
AboutDialog.java
jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java
+26
-2
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+80
-29
Utils.java
jadx-gui/src/main/java/jadx/gui/utils/Utils.java
+11
-0
jadx-logo.png
jadx-gui/src/main/resources/icons-16/jadx-logo.png
+0
-0
jadx-logo.ico
jadx-gui/src/main/resources/logos/jadx-logo.ico
+0
-0
jadx-logo.svg
jadx-gui/src/main/resources/logos/jadx-logo.svg
+1
-0
bintray-upload.sh
scripts/bintray-upload.sh
+3
-3
travis-master.sh
scripts/travis-master.sh
+1
-1
travis-release.sh
scripts/travis-release.sh
+1
-1
No files found.
.travis.yml
View file @
365c1faf
...
...
@@ -12,8 +12,7 @@ before_install:
-
chmod +x gradlew
# override install to skip 'gradle assemble'
install
:
-
true
install
:
true
env
:
global
:
...
...
@@ -21,34 +20,21 @@ env:
-
JADX_LAST_TAG=$(git describe --abbrev=0 --tags)
-
JADX_VERSION="${JADX_LAST_TAG:1}-b$TRAVIS_BUILD_NUMBER-$(git rev-parse --short HEAD)"
matrix
:
jdk
:
-
openjdk8
-
oraclejdk8
-
openjdk11
script
:
./gradlew clean build
jobs
:
include
:
-
env
:
JDK=oracle-8
jdk
:
oraclejdk8
-
env
:
JDK=openjdk11
jdk
:
openjdk11
script
:
-
java -version
-
./gradlew clean build
deploy
:
-
provider
:
script
skip_cleanup
:
true
on
:
branch
:
master
tags
:
false
condition
:
$JDK = oracle-8
script
:
bash scripts/travis-master.sh
-
provider
:
script
skip_cleanup
:
true
on
:
branch
:
release
tags
:
false
condition
:
$JDK = oracle-8
script
:
bash scripts/travis-release.sh
notifications
:
email
:
-
skylot@gmail.com
-
stage
:
deploy-unstable
jdk
:
openjdk8
if
:
branch = master AND repo = env(MAIN_REPO) AND type = push
script
:
bash scripts/travis-master.sh
-
stage
:
deploy-release
jdk
:
openjdk8
if
:
branch = release AND repo = env(MAIN_REPO) AND type = push
script
:
bash scripts/travis-release.sh
build.gradle
View file @
365c1faf
plugins
{
id
'org.sonarqube'
version
'2.7'
id
'com.github.ben-manes.versions'
version
'0.2
0
.0'
id
'com.github.ben-manes.versions'
version
'0.2
1
.0'
}
ext
.
jadxVersion
=
System
.
getenv
(
'JADX_VERSION'
)
?:
"dev"
...
...
@@ -35,12 +35,12 @@ allprojects {
}
dependencies
{
compile
'org.slf4j:slf4j-api:1.7.2
5
'
compile
'org.slf4j:slf4j-api:1.7.2
6
'
testCompile
'ch.qos.logback:logback-classic:1.2.3'
testCompile
'junit:junit:4.12'
testCompile
'org.hamcrest:hamcrest-library:2.1'
testCompile
'org.mockito:mockito-core:2.2
3.4
'
testCompile
'org.mockito:mockito-core:2.2
5.0
'
testCompile
'org.spockframework:spock-core:1.1-groovy-2.4'
}
...
...
gradle/wrapper/gradle-wrapper.properties
View file @
365c1faf
distributionBase
=
GRADLE_USER_HOME
distributionPath
=
wrapper/dists
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-5.
1
.1-bin.zip
distributionUrl
=
https
\:
//services.gradle.org/distributions/gradle-5.
2
.1-bin.zip
zipStoreBase
=
GRADLE_USER_HOME
zipStorePath
=
wrapper/dists
jadx-core/build.gradle
View file @
365c1faf
...
...
@@ -5,13 +5,17 @@ dependencies {
compile
files
(
'lib/dx-1.16.jar'
)
compile
'commons-io:commons-io:2.6'
compile
'org.ow2.asm:asm:7.
0
'
compile
'org.jetbrains:annotations:1
6.0.3
'
compile
'uk.com.robust-it:cloning:1.9.1
1
'
compile
'org.ow2.asm:asm:7.
1
'
compile
'org.jetbrains:annotations:1
7.0.0
'
compile
'uk.com.robust-it:cloning:1.9.1
2
'
testCompile
'org.smali:smali:2.2.
5
'
testCompile
'org.smali:baksmali:2.2.
5
'
testCompile
'org.smali:smali:2.2.
6
'
testCompile
'org.smali:baksmali:2.2.
6
'
testCompile
'org.apache.commons:commons-lang3:3.8.1'
// update dependency in smali
testCompile
'com.google.guava:guava:27.1-jre'
testCompile
'com.beust:jcommander:1.74'
}
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
View file @
365c1faf
...
...
@@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory;
import
jadx.core.Jadx
;
import
jadx.core.ProcessClass
;
import
jadx.core.codegen.CodeGen
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.FieldNode
;
...
...
@@ -59,7 +58,6 @@ public final class JadxDecompiler {
private
RootNode
root
;
private
List
<
IDexTreeVisitor
>
passes
;
private
CodeGen
codeGen
;
private
List
<
JavaClass
>
classes
;
private
List
<
ResourceFile
>
resources
;
...
...
@@ -97,7 +95,6 @@ public final class JadxDecompiler {
void
init
()
{
this
.
passes
=
Jadx
.
getPassesList
(
args
);
this
.
codeGen
=
new
CodeGen
();
}
void
reset
()
{
...
...
@@ -106,7 +103,6 @@ public final class JadxDecompiler {
xmlParser
=
null
;
root
=
null
;
passes
=
null
;
codeGen
=
null
;
}
public
static
String
getVersion
()
{
...
...
@@ -215,9 +211,11 @@ public final class JadxDecompiler {
List
<
JavaClass
>
clsList
=
new
ArrayList
<>(
classNodeList
.
size
());
classesMap
.
clear
();
for
(
ClassNode
classNode
:
classNodeList
)
{
JavaClass
javaClass
=
new
JavaClass
(
classNode
,
this
);
clsList
.
add
(
javaClass
);
classesMap
.
put
(
classNode
,
javaClass
);
if
(!
classNode
.
contains
(
AFlag
.
DONT_GENERATE
))
{
JavaClass
javaClass
=
new
JavaClass
(
classNode
,
this
);
clsList
.
add
(
javaClass
);
classesMap
.
put
(
classNode
,
javaClass
);
}
}
classes
=
Collections
.
unmodifiableList
(
clsList
);
}
...
...
@@ -289,7 +287,7 @@ public final class JadxDecompiler {
}
void
processClass
(
ClassNode
cls
)
{
ProcessClass
.
process
(
cls
,
passes
,
codeGen
);
ProcessClass
.
process
(
cls
,
passes
,
true
);
}
RootNode
getRoot
()
{
...
...
jadx-core/src/main/java/jadx/core/ProcessClass.java
View file @
365c1faf
...
...
@@ -2,8 +2,6 @@ package jadx.core;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.codegen.CodeGen
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.visitors.DepthTraversal
;
...
...
@@ -19,8 +17,8 @@ public final class ProcessClass {
private
ProcessClass
()
{
}
public
static
void
process
(
ClassNode
cls
,
List
<
IDexTreeVisitor
>
passes
,
@Nullable
CodeGen
codeGen
)
{
if
(
codeGen
==
null
&&
cls
.
getState
()
==
PROCESSED
)
{
public
static
void
process
(
ClassNode
cls
,
List
<
IDexTreeVisitor
>
passes
,
boolean
generateCode
)
{
if
(
!
generateCode
&&
cls
.
getState
()
==
PROCESSED
)
{
return
;
}
synchronized
(
getSyncObj
(
cls
))
{
...
...
@@ -33,9 +31,9 @@ public final class ProcessClass {
}
cls
.
setState
(
PROCESSED
);
}
if
(
cls
.
getState
()
==
PROCESSED
&&
codeGen
!=
null
)
{
if
(
cls
.
getState
()
==
PROCESSED
&&
generateCode
)
{
processDependencies
(
cls
,
passes
);
codeGen
.
visit
(
cls
);
CodeGen
.
generate
(
cls
);
}
}
catch
(
Exception
e
)
{
ErrorsCounter
.
classError
(
cls
,
e
.
getClass
().
getSimpleName
(),
e
);
...
...
@@ -48,6 +46,6 @@ public final class ProcessClass {
}
private
static
void
processDependencies
(
ClassNode
cls
,
List
<
IDexTreeVisitor
>
passes
)
{
cls
.
getDependencies
().
forEach
(
depCls
->
process
(
depCls
,
passes
,
null
));
cls
.
getDependencies
().
forEach
(
depCls
->
process
(
depCls
,
passes
,
false
));
}
}
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
365c1faf
...
...
@@ -97,7 +97,7 @@ public class ClassGen {
imports
.
clear
();
}
clsCode
.
add
(
clsBody
);
return
clsCode
;
return
clsCode
.
finish
()
;
}
public
void
addClassCode
(
CodeWriter
code
)
throws
CodegenException
{
...
...
jadx-core/src/main/java/jadx/core/codegen/CodeGen.java
View file @
365c1faf
package
jadx
.
core
.
codegen
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.utils.exceptions.CodegenException
;
public
class
CodeGen
{
public
boolean
visit
(
ClassNode
cls
)
throws
CodegenException
{
ClassGen
clsGen
=
new
ClassGen
(
cls
,
cls
.
root
().
getArgs
());
CodeWriter
clsCode
=
clsGen
.
makeClass
();
clsCode
.
finish
();
cls
.
setCode
(
clsCode
);
return
false
;
public
static
void
generate
(
ClassNode
cls
)
throws
CodegenException
{
if
(
cls
.
contains
(
AFlag
.
DONT_GENERATE
))
{
cls
.
setCode
(
CodeWriter
.
EMPTY
);
}
else
{
ClassGen
clsGen
=
new
ClassGen
(
cls
,
cls
.
root
().
getArgs
());
cls
.
setCode
(
clsGen
.
makeClass
());
}
}
private
CodeGen
()
{
}
}
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
View file @
365c1faf
...
...
@@ -24,6 +24,8 @@ public class CodeWriter {
public
static
final
String
NL
=
System
.
getProperty
(
"line.separator"
);
public
static
final
String
INDENT_STR
=
" "
;
public
static
final
CodeWriter
EMPTY
=
new
CodeWriter
().
finish
();
private
static
final
boolean
ADD_LINE_NUMBERS
=
false
;
private
static
final
String
[]
INDENT_CACHE
=
{
...
...
@@ -250,7 +252,7 @@ public class CodeWriter {
return
lineMap
;
}
public
void
finish
()
{
public
CodeWriter
finish
()
{
removeFirstEmptyLine
();
buf
.
trimToSize
();
code
=
buf
.
toString
();
...
...
@@ -266,11 +268,12 @@ public class CodeWriter {
it
.
remove
();
}
}
return
this
;
}
private
void
removeFirstEmptyLine
()
{
int
len
=
NL
.
length
();
if
(
buf
.
substring
(
0
,
len
).
equals
(
NL
))
{
if
(
buf
.
length
()
>
len
&&
buf
.
substring
(
0
,
len
).
equals
(
NL
))
{
buf
.
delete
(
0
,
len
);
}
}
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
365c1faf
...
...
@@ -48,7 +48,6 @@ import jadx.core.dex.nodes.FieldNode;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.RegionUtils
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -549,7 +548,7 @@ public class InsnGen {
throws
CodegenException
{
ClassNode
cls
=
mth
.
dex
().
resolveClass
(
insn
.
getClassType
());
if
(
cls
!=
null
&&
cls
.
contains
(
AFlag
.
ANONYMOUS_CLASS
)
&&
!
fallback
)
{
inlineAnonymousConstr
(
code
,
cls
,
insn
);
inlineAnonymousConstr
uctor
(
code
,
cls
,
insn
);
return
;
}
if
(
insn
.
isSelf
())
{
...
...
@@ -567,20 +566,14 @@ public class InsnGen {
generateMethodArguments
(
code
,
insn
,
0
,
callMth
);
}
private
void
inlineAnonymousConstr
(
CodeWriter
code
,
ClassNode
cls
,
ConstructorInsn
insn
)
throws
CodegenException
{
// anonymous class construction
if
(
cls
.
contains
(
AFlag
.
DONT_GENERATE
))
{
code
.
add
(
"/* anonymous class already generated */"
);
ErrorsCounter
.
methodWarn
(
mth
,
"Anonymous class already generated: "
+
cls
);
return
;
}
private
void
inlineAnonymousConstructor
(
CodeWriter
code
,
ClassNode
cls
,
ConstructorInsn
insn
)
throws
CodegenException
{
cls
.
add
(
AFlag
.
DONT_GENERATE
);
ArgType
parent
;
if
(
cls
.
getInterfaces
().
size
()
==
1
)
{
parent
=
cls
.
getInterfaces
().
get
(
0
);
}
else
{
parent
=
cls
.
getSuperClass
();
}
cls
.
add
(
AFlag
.
DONT_GENERATE
);
MethodNode
defCtr
=
cls
.
getDefaultConstructor
();
if
(
defCtr
!=
null
)
{
if
(
RegionUtils
.
notEmpty
(
defCtr
.
getRegion
()))
{
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
View file @
365c1faf
...
...
@@ -19,6 +19,7 @@ import org.slf4j.LoggerFactory;
import
jadx.core.Consts
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.annotations.Annotation
;
import
jadx.core.dex.attributes.nodes.LineAttrNode
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
...
...
@@ -123,7 +124,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
accFlagsValue
=
cls
.
getAccessFlags
();
}
this
.
accessFlags
=
new
AccessInfo
(
accFlagsValue
,
AFType
.
CLASS
);
markAnonymousClass
(
this
);
buildCache
();
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Error decode class: "
+
clsInfo
,
e
);
...
...
@@ -394,6 +395,29 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode {
&&
getDefaultConstructor
()
!=
null
;
}
public
boolean
isLambdaCls
()
{
return
accessFlags
.
isSynthetic
()
&&
accessFlags
.
isFinal
()
&&
clsInfo
.
getType
().
getObject
().
contains
(
".-$$Lambda$"
)
&&
countStaticFields
()
==
0
;
}
private
int
countStaticFields
()
{
int
c
=
0
;
for
(
FieldNode
field
:
fields
)
{
if
(
field
.
getAccessFlags
().
isStatic
())
{
c
++;
}
}
return
c
;
}
private
static
void
markAnonymousClass
(
ClassNode
cls
)
{
if
(
cls
.
isAnonymous
()
||
cls
.
isLambdaCls
())
{
cls
.
add
(
AFlag
.
ANONYMOUS_CLASS
);
cls
.
add
(
AFlag
.
DONT_GENERATE
);
}
}
@Nullable
public
MethodNode
getClassInitMth
()
{
return
searchMethodByName
(
"<clinit>()V"
);
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/InsnNode.java
View file @
365c1faf
...
...
@@ -327,4 +327,24 @@ public class InsnNode extends LineAttrNode {
}
return
INSN_CLONER
.
deepClone
(
this
);
}
public
boolean
canThrowException
()
{
switch
(
getType
())
{
case
RETURN:
case
IF:
case
GOTO:
case
MOVE:
case
MOVE_EXCEPTION:
case
NEG:
case
CONST:
case
CONST_STR:
case
CONST_CLASS:
case
CMP_L:
case
CMP_G:
return
false
;
default
:
return
true
;
}
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
365c1faf
...
...
@@ -329,16 +329,24 @@ public class MethodNode extends LineAttrNode implements ILoadable, ICodeNode {
int
offset
=
aTry
.
getStartAddress
();
int
end
=
offset
+
aTry
.
getInstructionCount
()
-
1
;
InsnNode
insn
=
insnByOffset
[
offset
]
;
insn
.
add
(
AFlag
.
TRY_ENTER
)
;
boolean
tryBlockStarted
=
false
;
InsnNode
insn
=
null
;
while
(
offset
<=
end
&&
offset
>=
0
)
{
insn
=
insnByOffset
[
offset
];
catchBlock
.
addInsn
(
insn
);
if
(
insn
!=
null
)
{
if
(
tryBlockStarted
)
{
catchBlock
.
addInsn
(
insn
);
}
else
if
(
insn
.
canThrowException
())
{
insn
.
add
(
AFlag
.
TRY_ENTER
);
catchBlock
.
addInsn
(
insn
);
tryBlockStarted
=
true
;
}
}
offset
=
InsnDecoder
.
getNextInsnOffset
(
insnByOffset
,
offset
);
}
if
(
insnByOffset
[
end
]
!=
null
)
{
insnByOffset
[
end
].
add
(
AFlag
.
TRY_LEAVE
);
}
else
{
}
else
if
(
insn
!=
null
)
{
insn
.
add
(
AFlag
.
TRY_LEAVE
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ClassModifier.java
View file @
365c1faf
...
...
@@ -51,11 +51,10 @@ public class ClassModifier extends AbstractVisitor {
cls
.
add
(
AFlag
.
DONT_GENERATE
);
return
false
;
}
markAnonymousClass
(
cls
);
removeSyntheticFields
(
cls
);
cls
.
getMethods
().
forEach
(
mth
->
removeSyntheticMethods
(
cls
,
mth
)
);
cls
.
getMethods
().
forEach
(
ClassModifier:
:
removeSyntheticMethods
);
cls
.
getMethods
().
forEach
(
ClassModifier:
:
removeEmptyMethods
);
markAnonymousClass
(
cls
);
return
false
;
}
...
...
@@ -69,29 +68,36 @@ public class ClassModifier extends AbstractVisitor {
private
void
markAnonymousClass
(
ClassNode
cls
)
{
if
(
cls
.
isAnonymous
())
{
cls
.
add
(
AFlag
.
ANONYMOUS_CLASS
);
cls
.
add
(
AFlag
.
DONT_GENERATE
);
}
}
/**
* Remove synthetic fields if type is outer class or class will be inlined (anonymous)
*/
private
static
void
removeSyntheticFields
(
ClassNode
cls
)
{
if
(
!
cls
.
getClassInfo
().
isInner
()
||
cls
.
getAccessFlags
().
isStatic
())
{
if
(
cls
.
getAccessFlags
().
isStatic
())
{
return
;
}
// remove fields if it is synthetic and type is a outer class
for
(
FieldNode
field
:
cls
.
getFields
())
{
if
(
field
.
getAccessFlags
().
isSynthetic
()
&&
field
.
getType
().
isObject
())
{
ClassInfo
clsInfo
=
ClassInfo
.
fromType
(
cls
.
root
(),
field
.
getType
());
ClassNode
fieldsCls
=
cls
.
dex
().
resolveClass
(
clsInfo
);
ClassInfo
parentClass
=
cls
.
getClassInfo
().
getParentClass
();
if
(
fieldsCls
!=
null
&&
parentClass
.
equals
(
fieldsCls
.
getClassInfo
()))
{
int
found
=
0
;
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
if
(
removeFieldUsageFromConstructor
(
mth
,
field
,
fieldsCls
))
{
found
++;
boolean
inline
=
cls
.
contains
(
AFlag
.
ANONYMOUS_CLASS
);
if
(
inline
||
cls
.
getClassInfo
().
isInner
())
{
for
(
FieldNode
field
:
cls
.
getFields
())
{
if
(
field
.
getAccessFlags
().
isSynthetic
()
&&
field
.
getType
().
isObject
())
{
ClassInfo
clsInfo
=
ClassInfo
.
fromType
(
cls
.
root
(),
field
.
getType
());
ClassNode
fieldsCls
=
cls
.
dex
().
resolveClass
(
clsInfo
);
ClassInfo
parentClass
=
cls
.
getClassInfo
().
getParentClass
();
if
(
fieldsCls
!=
null
&&
(
inline
||
parentClass
.
equals
(
fieldsCls
.
getClassInfo
())))
{
int
found
=
0
;
for
(
MethodNode
mth
:
cls
.
getMethods
())
{
if
(
removeFieldUsageFromConstructor
(
mth
,
field
,
fieldsCls
))
{
found
++;
}
}
if
(
found
!=
0
)
{
field
.
addAttr
(
new
FieldReplaceAttr
(
fieldsCls
.
getClassInfo
()));
field
.
add
(
AFlag
.
DONT_GENERATE
);
}
}
if
(
found
!=
0
)
{
field
.
addAttr
(
new
FieldReplaceAttr
(
parentClass
));
field
.
add
(
AFlag
.
DONT_GENERATE
);
}
}
}
...
...
@@ -137,7 +143,7 @@ public class ClassModifier extends AbstractVisitor {
return
true
;
}
private
static
void
removeSyntheticMethods
(
ClassNode
cls
,
MethodNode
mth
)
{
private
static
void
removeSyntheticMethods
(
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
{
return
;
}
...
...
@@ -145,6 +151,7 @@ public class ClassModifier extends AbstractVisitor {
if
(!
af
.
isSynthetic
())
{
return
;
}
ClassNode
cls
=
mth
.
getParentClass
();
if
(
removeBridgeMethod
(
cls
,
mth
))
{
if
(
Consts
.
DEBUG
)
{
mth
.
addAttr
(
AType
.
COMMENTS
,
"Removed as synthetic bridge method"
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DependencyCollector.java
View file @
365c1faf
...
...
@@ -18,6 +18,7 @@ import jadx.core.dex.nodes.DexNode;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.parser.FieldInitAttr
;
import
jadx.core.utils.exceptions.JadxException
;
public
class
DependencyCollector
extends
AbstractVisitor
{
...
...
@@ -41,6 +42,12 @@ public class DependencyCollector extends AbstractVisitor {
}
for
(
FieldNode
fieldNode
:
cls
.
getFields
())
{
addDep
(
dex
,
depList
,
fieldNode
.
getType
());
// process instructions from field init
FieldInitAttr
fieldInitAttr
=
fieldNode
.
get
(
AType
.
FIELD_INIT
);
if
(
fieldInitAttr
!=
null
&&
fieldInitAttr
.
getValueType
()
==
FieldInitAttr
.
InitType
.
INSN
)
{
processInsn
(
dex
,
depList
,
fieldInitAttr
.
getInsn
());
}
}
// TODO: process annotations and generics
for
(
MethodNode
methodNode
:
cls
.
getMethods
())
{
...
...
jadx-core/src/main/java/jadx/core/utils/RegionUtils.java
View file @
365c1faf
...
...
@@ -5,6 +5,8 @@ import java.util.Collections;
import
java.util.List
;
import
java.util.Set
;
import
org.jetbrains.annotations.Nullable
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.nodes.BlockNode
;
...
...
@@ -136,7 +138,10 @@ public class RegionUtils {
return
!
notEmpty
(
container
);
}
public
static
boolean
notEmpty
(
IContainer
container
)
{
public
static
boolean
notEmpty
(
@Nullable
IContainer
container
)
{
if
(
container
==
null
)
{
return
false
;
}
if
(
container
instanceof
IBlock
)
{
return
!((
IBlock
)
container
).
getInstructions
().
isEmpty
();
}
else
if
(
container
instanceof
IRegion
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java
View file @
365c1faf
package
jadx
.
core
.
utils
.
android
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TreeMap
;
import
com.android.dx.rop.code.AccessFlags
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.codegen.ClassGen
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.deobf.NameMapper
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.ConstStorage
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.nodes.ClassNode
;
...
...
@@ -86,6 +91,7 @@ public class AndroidResourcesUtils {
}
private
static
void
addResourceFields
(
ClassNode
resCls
,
ResourceStorage
resStorage
,
boolean
rClsExists
)
{
Map
<
Integer
,
FieldNode
>
resFieldsMap
=
fillResFieldsMap
(
resCls
);
Map
<
String
,
ClassNode
>
innerClsMap
=
new
TreeMap
<>();
if
(
rClsExists
)
{
for
(
ClassNode
innerClass
:
resCls
.
getInnerClasses
())
{
...
...
@@ -93,18 +99,20 @@ public class AndroidResourcesUtils {
}
}
for
(
ResourceEntry
resource
:
resStorage
.
getResources
())
{
ClassNode
typeCls
=
innerClsMap
.
computeIfAbsent
(
resource
.
getTypeName
(),
name
->
{
ClassNode
newTypeCls
=
new
ClassNode
(
resCls
.
dex
(),
resCls
.
getFullName
()
+
"$"
+
name
,
AccessFlags
.
ACC_PUBLIC
|
AccessFlags
.
ACC_STATIC
|
AccessFlags
.
ACC_FINAL
);
resCls
.
addInnerClass
(
newTypeCls
);
if
(
rClsExists
)
{
newTypeCls
.
addAttr
(
AType
.
COMMENTS
,
"added by JADX"
);
}
return
newTypeCls
;
});
FieldNode
rField
=
typeCls
.
searchFieldByName
(
resource
.
getKeyName
());
final
String
resTypeName
=
resource
.
getTypeName
();
ClassNode
typeCls
=
innerClsMap
.
computeIfAbsent
(
resTypeName
,
name
->
addClassForResType
(
resCls
,
rClsExists
,
name
)
);
final
String
resName
;
if
(
"style"
.
equals
(
resTypeName
))
{
resName
=
resource
.
getKeyName
().
replace
(
'.'
,
'_'
);
}
else
{
resName
=
resource
.
getKeyName
();
}
FieldNode
rField
=
typeCls
.
searchFieldByName
(
resName
);
if
(
rField
==
null
)
{
FieldInfo
rFieldInfo
=
FieldInfo
.
from
(
typeCls
.
dex
(),
typeCls
.
getClassInfo
(),
res
ource
.
getKeyName
()
,
ArgType
.
INT
);
FieldInfo
rFieldInfo
=
FieldInfo
.
from
(
typeCls
.
dex
(),
typeCls
.
getClassInfo
(),
res
Name
,
ArgType
.
INT
);
rField
=
new
FieldNode
(
typeCls
,
rFieldInfo
,
AccessFlags
.
ACC_PUBLIC
|
AccessFlags
.
ACC_STATIC
|
AccessFlags
.
ACC_FINAL
);
rField
.
addAttr
(
FieldInitAttr
.
constValue
(
resource
.
getId
()));
typeCls
.
getFields
().
add
(
rField
);
...
...
@@ -112,6 +120,42 @@ public class AndroidResourcesUtils {
rField
.
addAttr
(
AType
.
COMMENTS
,
"added by JADX"
);
}
}
FieldNode
fieldNode
=
resFieldsMap
.
get
(
resource
.
getId
());
if
(
fieldNode
!=
null
&&
!
fieldNode
.
getName
().
equals
(
resName
)
&&
NameMapper
.
isValidIdentifier
(
resName
))
{
fieldNode
.
getFieldInfo
().
setAlias
(
resName
);
}
}
}
@NotNull
private
static
ClassNode
addClassForResType
(
ClassNode
resCls
,
boolean
rClsExists
,
String
typeName
)
{
ClassNode
newTypeCls
=
new
ClassNode
(
resCls
.
dex
(),
resCls
.
getFullName
()
+
"$"
+
typeName
,
AccessFlags
.
ACC_PUBLIC
|
AccessFlags
.
ACC_STATIC
|
AccessFlags
.
ACC_FINAL
);
resCls
.
addInnerClass
(
newTypeCls
);
if
(
rClsExists
)
{
newTypeCls
.
addAttr
(
AType
.
COMMENTS
,
"added by JADX"
);
}
return
newTypeCls
;
}
@NotNull
private
static
Map
<
Integer
,
FieldNode
>
fillResFieldsMap
(
ClassNode
resCls
)
{
Map
<
Integer
,
FieldNode
>
resFieldsMap
=
new
HashMap
<>();
ConstStorage
constStorage
=
resCls
.
root
().
getConstValues
();
Map
<
Object
,
FieldNode
>
constFields
=
constStorage
.
getGlobalConstFields
();
for
(
Map
.
Entry
<
Object
,
FieldNode
>
entry
:
constFields
.
entrySet
())
{
Object
key
=
entry
.
getKey
();
FieldNode
field
=
entry
.
getValue
();
AccessInfo
accessFlags
=
field
.
getAccessFlags
();
if
(
field
.
getType
().
equals
(
ArgType
.
INT
)
&&
accessFlags
.
isStatic
()
&&
accessFlags
.
isFinal
()
&&
key
instanceof
Integer
)
{
resFieldsMap
.
put
((
Integer
)
key
,
field
);
}
}
return
resFieldsMap
;
}
}
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
View file @
365c1faf
...
...
@@ -59,8 +59,8 @@ public class InputFile {
loadFromZip
(
".dex"
);
return
;
}
if
(
fileName
.
endsWith
(
".jar"
))
{
// check if jar contains '.dex' files
if
(
fileName
.
endsWith
(
".jar"
)
||
fileName
.
endsWith
(
".aar"
)
)
{
// check if jar
/aar
contains '.dex' files
if
(
loadFromZip
(
".dex"
))
{
return
;
}
...
...
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
View file @
365c1faf
...
...
@@ -15,8 +15,6 @@ import org.slf4j.LoggerFactory;
import
jadx.api.ResourcesLoader
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.info.ConstStorage
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.StringUtils
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -40,7 +38,6 @@ public class BinaryXMLParser extends CommonBinaryParser {
private
static
final
boolean
ATTR_NEW_LINE
=
false
;
private
final
Map
<
Integer
,
String
>
styleMap
=
new
HashMap
<>();
private
final
Map
<
Integer
,
FieldNode
>
localStyleMap
=
new
HashMap
<>();
private
final
Map
<
Integer
,
String
>
resNames
;
private
final
Map
<
String
,
String
>
nsMap
=
new
HashMap
<>();
private
Set
<
String
>
nsMapGenerated
;
...
...
@@ -63,16 +60,7 @@ public class BinaryXMLParser extends CommonBinaryParser {
this
.
rootNode
=
rootNode
;
try
{
readAndroidRStyleClass
();
// add application constants
ConstStorage
constStorage
=
rootNode
.
getConstValues
();
Map
<
Object
,
FieldNode
>
constFields
=
constStorage
.
getGlobalConstFields
();
for
(
Map
.
Entry
<
Object
,
FieldNode
>
entry
:
constFields
.
entrySet
())
{
Object
key
=
entry
.
getKey
();
FieldNode
field
=
entry
.
getValue
();
if
(
field
.
getType
().
equals
(
ArgType
.
INT
)
&&
key
instanceof
Integer
)
{
localStyleMap
.
put
((
Integer
)
key
,
field
);
}
}
resNames
=
constStorage
.
getResourcesNames
();
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"BinaryXMLParser init error"
,
e
);
...
...
@@ -381,38 +369,27 @@ public class BinaryXMLParser extends CommonBinaryParser {
private
void
decodeAttribute
(
int
attributeNS
,
int
attrValDataType
,
int
attrValData
,
String
shortNsName
,
String
attrName
)
{
if
(
attrValDataType
==
TYPE_REFERENCE
)
{
// reference custom processing
String
name
=
styleMap
.
get
(
attrValData
);
if
(
name
!=
null
)
{
writer
.
add
(
"@style/"
).
add
(
name
.
replaceAll
(
"_"
,
"."
));
}
else
{
FieldNode
field
=
localStyleMap
.
get
(
attrValData
);
if
(
field
!=
null
)
{
String
cls
=
field
.
getParentClass
().
getShortName
().
toLowerCase
();
String
resName
=
resNames
.
get
(
attrValData
);
if
(
resName
!=
null
)
{
writer
.
add
(
"@"
);
if
(
"id"
.
equals
(
cls
))
{
writer
.
add
(
'+'
);
if
(
resName
.
startsWith
(
"id/"
))
{
writer
.
add
(
"+"
);
}
writer
.
add
(
cls
).
add
(
"/"
).
add
(
field
.
getName
()
);
writer
.
add
(
resName
);
}
else
{
String
resName
=
resNames
.
get
(
attrValData
);
resName
=
ValuesParser
.
getAndroidResMap
()
.
get
(
attrValData
);
if
(
resName
!=
null
)
{
writer
.
add
(
"@"
);
if
(
resName
.
startsWith
(
"id/"
))
{
writer
.
add
(
"+"
);
}
writer
.
add
(
resName
);
writer
.
add
(
"@android:"
).
add
(
resName
);
}
else
if
(
attrValData
==
0
)
{
writer
.
add
(
"@null"
);
}
else
{
resName
=
ValuesParser
.
getAndroidResMap
().
get
(
attrValData
);
if
(
resName
!=
null
)
{
writer
.
add
(
"@android:"
).
add
(
resName
);
}
else
if
(
attrValData
==
0
)
{
writer
.
add
(
"@null"
);
}
else
{
writer
.
add
(
"0x"
).
add
(
Integer
.
toHexString
(
attrValData
));
}
writer
.
add
(
"0x"
).
add
(
Integer
.
toHexString
(
attrValData
));
}
}
}
...
...
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
View file @
365c1faf
...
...
@@ -140,7 +140,7 @@ public abstract class IntegrationTest extends TestUtils {
protected
void
decompile
(
JadxDecompiler
jadx
,
ClassNode
cls
)
{
List
<
IDexTreeVisitor
>
passes
=
JadxInternalAccess
.
getPassList
(
jadx
);
ProcessClass
.
process
(
cls
,
passes
,
new
CodeGen
()
);
ProcessClass
.
process
(
cls
,
passes
,
true
);
}
protected
void
decompileWithoutUnload
(
JadxDecompiler
jadx
,
ClassNode
cls
)
{
...
...
@@ -154,7 +154,7 @@ public abstract class IntegrationTest extends TestUtils {
protected
void
generateClsCode
(
ClassNode
cls
)
{
try
{
new
CodeGen
().
visit
(
cls
);
CodeGen
.
generate
(
cls
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
...
...
jadx-core/src/test/java/jadx/tests/api/compiler/ClassFileManager.java
View file @
365c1faf
...
...
@@ -6,10 +6,8 @@ import javax.tools.JavaFileObject;
import
javax.tools.StandardJavaFileManager
;
import
java.io.IOException
;
import
java.security.SecureClassLoader
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
static
javax
.
tools
.
JavaFileObject
.
Kind
;
...
...
jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java
View file @
365c1faf
...
...
@@ -15,12 +15,11 @@ import jadx.api.JadxArgs;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JadxInternalAccess
;
import
jadx.api.JavaClass
;
import
jadx.core.
codegen.CodeGen
;
import
jadx.core.
ProcessClass
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.dex.visitors.DepthTraversal
;
import
jadx.core.dex.visitors.IDexTreeVisitor
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.tests.api.IntegrationTest
;
...
...
@@ -99,15 +98,10 @@ public abstract class BaseExternalTest extends IntegrationTest {
if
(!
decompile
)
{
return
false
;
}
// ProcessClass.process(classNode, passes, new CodeGen());
for
(
IDexTreeVisitor
visitor
:
passes
)
{
DepthTraversal
.
visit
(
visitor
,
classNode
);
}
try
{
new
CodeGen
().
visit
(
classNod
e
);
ProcessClass
.
process
(
classNode
,
passes
,
tru
e
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"C
odegen
failed"
,
e
);
throw
new
JadxRuntimeException
(
"C
lass process
failed"
,
e
);
}
LOG
.
info
(
"----------------------------------------------------------------"
);
LOG
.
info
(
"Print class: {}, {}"
,
classNode
.
getFullName
(),
classNode
.
dex
());
...
...
jadx-core/src/test/java/jadx/tests/integration/inner/TestInnerClassFakeSyntheticConstructor.java
View file @
365c1faf
...
...
@@ -3,7 +3,6 @@ package jadx.tests.integration.inner;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
...
...
jadx-core/src/test/java/jadx/tests/integration/inner/TestInnerClassSyntheticConstructor.java
View file @
365c1faf
...
...
@@ -3,10 +3,6 @@ package jadx.tests.integration.inner;
import
org.junit.Test
;
import
jadx.tests.api.IntegrationTest
;
import
jadx.tests.api.SmaliTest
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestInnerClassSyntheticConstructor
extends
IntegrationTest
{
...
...
jadx-core/src/test/java/jadx/tests/integration/loops/TestEndlessLoop.java
View file @
365c1faf
...
...
@@ -5,7 +5,6 @@ import org.junit.Test;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertThat
;
...
...
jadx-core/src/test/java/jadx/tests/integration/switches/TestSwitchReturnFromCase2.java
View file @
365c1faf
...
...
@@ -4,9 +4,7 @@ import jadx.core.dex.nodes.ClassNode;
import
jadx.tests.api.IntegrationTest
;
import
org.junit.Test
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
hamcrest
.
CoreMatchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
...
...
jadx-core/src/test/java/jadx/tests/integration/trycatch/TestTryCatchStartOnMove.java
0 → 100644
View file @
365c1faf
package
jadx
.
tests
.
integration
.
trycatch
;
import
org.junit.Test
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
JadxMatchers
.
containsOne
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TestTryCatchStartOnMove
extends
SmaliTest
{
// private static void test(String s) {
// try {
// call(s);
// } catch (Exception unused) {
// System.out.println("Failed call for " + s);
// }
// }
//
// private static void call(String s) {
// }
@Test
public
void
test
()
{
ClassNode
cls
=
getClassNodeFromSmaliWithPkg
(
"trycatch"
,
"TestTryCatchStartOnMove"
);
String
code
=
cls
.
getCode
().
toString
();
assertThat
(
code
,
containsOne
(
"try {"
));
assertThat
(
code
,
containsOne
(
"} catch (Exception e) {"
));
assertThat
(
code
,
containsOne
(
"System.out.println(\"Failed call for \" + str"
));
}
}
jadx-core/src/test/smali/trycatch/TestTryCatchStartOnMove.smali
0 → 100644
View file @
365c1faf
.class public Ltrycatch/TestTryCatchStartOnMove;
.super Ljava/lang/Object;
# direct methods
.method private static test(Ljava/lang/String;)V
.registers 5
:try_start
move v3, p0
invoke-static {v3}, Ltrycatch/TestTryCatchStartOnMove;->call(Ljava/lang/String;)V
:try_end
.catch Ljava/lang/Exception; {:try_start .. :try_end} :catch
:goto_ret
return-void
:catch
move-exception v0
sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;
new-instance v1, Ljava/lang/StringBuilder;
invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V
const-string v2, "Failed call for "
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
goto :goto_ret
.end method
.method public constructor <init>()V
.registers 1
invoke-direct {p0}, Ljadx/tests/api/SmaliTest;-><init>()V
return-void
.end method
.method private static call(Ljava/lang/String;)V
.registers 1
return-void
.end method
jadx-gui/build.gradle
View file @
365c1faf
plugins
{
id
'edu.sc.seis.launch4j'
version
'2.4.
4
'
id
'com.github.johnrengelman.shadow'
version
'
4.0.3
'
id
'edu.sc.seis.launch4j'
version
'2.4.
5
'
id
'com.github.johnrengelman.shadow'
version
'
5.0.0
'
}
apply
plugin:
'application'
...
...
@@ -13,7 +13,8 @@ targetCompatibility = JavaVersion.VERSION_1_8
dependencies
{
compile
(
project
(
":jadx-core"
))
compile
(
project
(
":jadx-cli"
))
compile
'com.fifesoft:rsyntaxtextarea:3.0.0'
compile
'com.fifesoft:rsyntaxtextarea:3.0.2'
compile
'com.google.code.gson:gson:2.8.5'
compile
files
(
'libs/jfontchooser-1.0.5.jar'
)
compile
'hu.kazocsaba:image-viewer:1.2.3'
...
...
@@ -21,9 +22,9 @@ dependencies {
compile
'org.apache.commons:commons-lang3:3.8.1'
compile
'org.apache.commons:commons-text:1.6'
compile
'io.reactivex.rxjava2:rxjava:2.2.
5
'
compile
"com.github.akarnokd:rxjava2-swing:0.3.
3
"
compile
'com.android.tools.build:apksig:3.3.
0
'
compile
'io.reactivex.rxjava2:rxjava:2.2.
7
'
compile
"com.github.akarnokd:rxjava2-swing:0.3.
4
"
compile
'com.android.tools.build:apksig:3.3.
2
'
}
applicationDistribution
.
with
{
...
...
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
View file @
365c1faf
package
jadx
.
gui
;
import
javax.swing.*
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.stream.Collectors
;
import
javax.swing.ProgressMonitor
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -78,14 +81,13 @@ public class JadxWrapper {
*/
public
List
<
JavaClass
>
getIncludedClasses
()
{
List
<
JavaClass
>
classList
=
decompiler
.
getClasses
();
String
excludedPackages
=
settings
.
getExcludedPackages
().
trim
();
if
(
excludedPackages
.
length
()
==
0
)
{
List
<
String
>
excludedPackages
=
getExcludedPackages
();
if
(
excludedPackages
.
isEmpty
()
)
{
return
classList
;
}
String
[]
excluded
=
excludedPackages
.
split
(
"[ ]+"
);
return
classList
.
stream
().
filter
(
cls
->
{
for
(
String
exclude
:
excluded
)
{
for
(
String
exclude
:
excluded
Packages
)
{
if
(
cls
.
getFullName
().
startsWith
(
exclude
))
{
return
false
;
}
...
...
@@ -94,6 +96,23 @@ public class JadxWrapper {
}).
collect
(
Collectors
.
toList
());
}
public
List
<
String
>
getExcludedPackages
()
{
String
excludedPackages
=
settings
.
getExcludedPackages
().
trim
();
return
Arrays
.
asList
(
excludedPackages
.
split
(
"[ ]+"
));
}
public
void
addExcludedPackage
(
String
packageToExclude
)
{
settings
.
setExcludedPackages
(
settings
.
getExcludedPackages
()
+
' '
+
packageToExclude
);
settings
.
sync
();
}
public
void
removeExcludedPackage
(
String
packageToRemoveFromExclusion
)
{
List
<
String
>
list
=
new
ArrayList
<>(
getExcludedPackages
());
list
.
remove
(
packageToRemoveFromExclusion
);
settings
.
setExcludedPackages
(
String
.
join
(
" "
,
list
));
settings
.
sync
();
}
public
List
<
JavaPackage
>
getPackages
()
{
return
decompiler
.
getPackages
();
}
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
View file @
365c1faf
...
...
@@ -333,4 +333,5 @@ public class JadxSettings extends JadxCLIArgs {
settingsVersion
=
CURRENT_SETTINGS_VERSION
;
sync
();
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
View file @
365c1faf
...
...
@@ -247,10 +247,14 @@ public class JadxSettingsWindow extends JDialog {
JButton
editExcludedPackages
=
new
JButton
(
NLS
.
str
(
"preferences.excludedPackages.button"
));
editExcludedPackages
.
addActionListener
(
event
->
{
String
oldExcludedPackages
=
settings
.
getExcludedPackages
();
String
result
=
JOptionPane
.
showInputDialog
(
this
,
NLS
.
str
(
"preferences.excludedPackages.editDialog"
),
settings
.
getExcludedPackages
());
if
(
result
!=
null
)
{
settings
.
setExcludedPackages
(
result
);
if
(!
oldExcludedPackages
.
equals
(
result
))
{
needReload
();
}
}
});
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java
View file @
365c1faf
package
jadx
.
gui
.
treemodel
;
import
javax.swing.*
;
import
java.util.ArrayList
;
import
java.util.List
;
import
javax.swing.Icon
;
import
javax.swing.ImageIcon
;
import
org.jetbrains.annotations.NotNull
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaPackage
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.utils.Utils
;
public
class
JPackage
extends
JNode
implements
Comparable
<
JPackage
>
{
...
...
@@ -15,12 +18,16 @@ public class JPackage extends JNode implements Comparable<JPackage> {
private
static
final
ImageIcon
PACKAGE_ICON
=
Utils
.
openIcon
(
"package_obj"
);
private
final
String
fullName
;
private
String
name
;
private
boolean
enabled
;
private
final
List
<
JClass
>
classes
;
private
final
List
<
JPackage
>
innerPackages
=
new
ArrayList
<>(
1
);
public
JPackage
(
JavaPackage
pkg
)
{
public
JPackage
(
JavaPackage
pkg
,
JadxWrapper
wrapper
)
{
this
.
fullName
=
pkg
.
getName
();
this
.
name
=
pkg
.
getName
();
setEnabled
(
wrapper
);
List
<
JavaClass
>
javaClasses
=
pkg
.
getClasses
();
this
.
classes
=
new
ArrayList
<>(
javaClasses
.
size
());
for
(
JavaClass
javaClass
:
javaClasses
)
{
...
...
@@ -29,20 +36,30 @@ public class JPackage extends JNode implements Comparable<JPackage> {
update
();
}
public
JPackage
(
String
name
)
{
public
JPackage
(
String
name
,
JadxWrapper
wrapper
)
{
this
.
fullName
=
name
;
this
.
name
=
name
;
setEnabled
(
wrapper
);
this
.
classes
=
new
ArrayList
<>(
1
);
}
private
void
setEnabled
(
JadxWrapper
wrapper
)
{
List
<
String
>
excludedPackages
=
wrapper
.
getExcludedPackages
();
this
.
enabled
=
excludedPackages
.
isEmpty
()
||
excludedPackages
.
stream
().
filter
(
p
->
!
p
.
isEmpty
()).
noneMatch
(
p
->
name
.
startsWith
(
p
));
}
public
final
void
update
()
{
removeAllChildren
();
for
(
JPackage
pkg
:
innerPackages
)
{
pkg
.
update
();
add
(
pkg
);
}
for
(
JClass
cls
:
classes
)
{
cls
.
update
();
add
(
cls
);
if
(
isEnabled
())
{
for
(
JPackage
pkg
:
innerPackages
)
{
pkg
.
update
();
add
(
pkg
);
}
for
(
JClass
cls
:
classes
)
{
cls
.
update
();
add
(
cls
);
}
}
}
...
...
@@ -51,6 +68,10 @@ public class JPackage extends JNode implements Comparable<JPackage> {
return
name
;
}
public
String
getFullName
()
{
return
fullName
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
...
...
@@ -108,4 +129,8 @@ public class JPackage extends JNode implements Comparable<JPackage> {
public
String
makeLongString
()
{
return
name
;
}
public
boolean
isEnabled
()
{
return
enabled
;
}
}
jadx-gui/src/main/java/jadx/gui/treemodel/JResource.java
View file @
365c1faf
...
...
@@ -3,6 +3,7 @@ package jadx.gui.treemodel;
import
javax.swing.*
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -68,6 +69,14 @@ public class JResource extends JLoadableNode implements Comparable<JResource> {
}
}
else
{
removeAllChildren
();
Comparator
<
JResource
>
typeComparator
=
(
r1
,
r2
)
->
r1
.
type
.
ordinal
()
-
r2
.
type
.
ordinal
();
Comparator
<
JResource
>
nameComparator
=
Comparator
.
comparing
(
JResource:
:
getName
,
String
.
CASE_INSENSITIVE_ORDER
);
files
.
sort
(
typeComparator
.
thenComparing
(
nameComparator
));
for
(
JResource
res
:
files
)
{
res
.
update
();
add
(
res
);
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JSources.java
View file @
365c1faf
...
...
@@ -33,7 +33,7 @@ public class JSources extends JNode {
removeAllChildren
();
if
(
flatPackages
)
{
for
(
JavaPackage
pkg
:
wrapper
.
getPackages
())
{
add
(
new
JPackage
(
pkg
));
add
(
new
JPackage
(
pkg
,
wrapper
));
}
}
else
{
// build packages hierarchy
...
...
@@ -54,7 +54,7 @@ public class JSources extends JNode {
List
<
JPackage
>
getHierarchyPackages
(
List
<
JavaPackage
>
packages
)
{
Map
<
String
,
JPackage
>
pkgMap
=
new
HashMap
<>();
for
(
JavaPackage
pkg
:
packages
)
{
addPackage
(
pkgMap
,
new
JPackage
(
pkg
));
addPackage
(
pkgMap
,
new
JPackage
(
pkg
,
wrapper
));
}
// merge packages without classes
boolean
repeat
;
...
...
@@ -114,7 +114,7 @@ public class JSources extends JNode {
pkg
.
setName
(
shortName
);
JPackage
prevPkg
=
pkgs
.
get
(
prevPart
);
if
(
prevPkg
==
null
)
{
prevPkg
=
new
JPackage
(
prevPart
);
prevPkg
=
new
JPackage
(
prevPart
,
wrapper
);
addPackage
(
pkgs
,
prevPkg
);
}
prevPkg
.
getInnerPackages
().
add
(
pkg
);
...
...
jadx-gui/src/main/java/jadx/gui/ui/AboutDialog.java
View file @
365c1faf
...
...
@@ -2,9 +2,11 @@ package jadx.gui.ui;
import
javax.swing.*
;
import
java.awt.*
;
import
java.net.URL
;
import
jadx.api.JadxDecompiler
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Utils
;
class
AboutDialog
extends
JDialog
{
private
static
final
long
serialVersionUID
=
5763493590584039096L
;
...
...
@@ -16,7 +18,10 @@ class AboutDialog extends JDialog {
public
final
void
initUI
()
{
Font
font
=
new
Font
(
"Serif"
,
Font
.
BOLD
,
13
);
JLabel
name
=
new
JLabel
(
"jadx"
);
URL
logoURL
=
getClass
().
getResource
(
"/logos/jadx-logo-48px.png"
);
Icon
logo
=
new
ImageIcon
(
logoURL
,
"jadx logo"
);
JLabel
name
=
new
JLabel
(
"jadx"
,
logo
,
SwingConstants
.
CENTER
);
name
.
setFont
(
font
);
name
.
setAlignmentX
(
0.5f
);
...
...
@@ -24,10 +29,24 @@ class AboutDialog extends JDialog {
desc
.
setFont
(
font
);
desc
.
setAlignmentX
(
0.5f
);
JLabel
version
=
new
JLabel
(
"version: "
+
JadxDecompiler
.
getVersion
());
JLabel
version
=
new
JLabel
(
"
jadx
version: "
+
JadxDecompiler
.
getVersion
());
version
.
setFont
(
font
);
version
.
setAlignmentX
(
0.5f
);
String
javaVm
=
System
.
getProperty
(
"java.vm.name"
);
String
javaVer
=
System
.
getProperty
(
"java.vm.version"
);
javaVm
=
javaVm
==
null
?
""
:
javaVm
;
JLabel
javaVmLabel
=
new
JLabel
(
"Java VM: "
+
javaVm
);
javaVmLabel
.
setFont
(
font
);
javaVmLabel
.
setAlignmentX
(
0.5f
);
javaVer
=
javaVer
==
null
?
""
:
javaVer
;
JLabel
javaVerLabel
=
new
JLabel
(
"Java version: "
+
javaVer
);
javaVerLabel
.
setFont
(
font
);
javaVerLabel
.
setAlignmentX
(
0.5f
);
JPanel
textPane
=
new
JPanel
();
textPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
15
,
15
,
15
,
15
));
textPane
.
setLayout
(
new
BoxLayout
(
textPane
,
BoxLayout
.
PAGE_AXIS
));
...
...
@@ -38,6 +57,9 @@ class AboutDialog extends JDialog {
textPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
10
)));
textPane
.
add
(
version
);
textPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
20
)));
textPane
.
add
(
javaVmLabel
);
textPane
.
add
(
javaVerLabel
);
textPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
0
,
20
)));
JButton
close
=
new
JButton
(
NLS
.
str
(
"tabs.close"
));
close
.
addActionListener
(
event
->
dispose
());
...
...
@@ -47,6 +69,8 @@ class AboutDialog extends JDialog {
contentPane
.
add
(
textPane
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
close
,
BorderLayout
.
PAGE_END
);
Utils
.
setWindowIcons
(
this
);
setModalityType
(
ModalityType
.
APPLICATION_MODAL
);
setTitle
(
NLS
.
str
(
"about_dialog.title"
));
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
365c1faf
package
jadx
.
gui
.
ui
;
import
javax.swing.*
;
import
javax.swing.event.MenuEvent
;
import
javax.swing.event.MenuListener
;
import
javax.swing.event.TreeExpansionEvent
;
import
javax.swing.event.TreeWillExpandListener
;
import
javax.swing.filechooser.FileNameExtensionFilter
;
import
javax.swing.tree.DefaultMutableTreeNode
;
import
javax.swing.tree.DefaultTreeCellRenderer
;
import
javax.swing.tree.DefaultTreeModel
;
import
javax.swing.tree.TreeNode
;
import
javax.swing.tree.TreePath
;
import
javax.swing.tree.TreeSelectionModel
;
import
java.awt.*
;
import
static
javax
.
swing
.
KeyStroke
.
getKeyStroke
;
import
java.awt.BorderLayout
;
import
java.awt.Component
;
import
java.awt.DisplayMode
;
import
java.awt.Font
;
import
java.awt.GraphicsDevice
;
import
java.awt.GraphicsEnvironment
;
import
java.awt.dnd.DnDConstants
;
import
java.awt.dnd.DropTarget
;
import
java.awt.event.ActionEvent
;
...
...
@@ -23,12 +18,42 @@ import java.awt.event.MouseAdapter;
import
java.awt.event.MouseEvent
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
javax.swing.AbstractAction
;
import
javax.swing.Action
;
import
javax.swing.Box
;
import
javax.swing.ImageIcon
;
import
javax.swing.JCheckBoxMenuItem
;
import
javax.swing.JFileChooser
;
import
javax.swing.JFrame
;
import
javax.swing.JMenu
;
import
javax.swing.JMenuBar
;
import
javax.swing.JMenuItem
;
import
javax.swing.JPanel
;
import
javax.swing.JPopupMenu
;
import
javax.swing.JScrollPane
;
import
javax.swing.JSplitPane
;
import
javax.swing.JToggleButton
;
import
javax.swing.JToolBar
;
import
javax.swing.JTree
;
import
javax.swing.ProgressMonitor
;
import
javax.swing.SwingUtilities
;
import
javax.swing.WindowConstants
;
import
javax.swing.event.MenuEvent
;
import
javax.swing.event.MenuListener
;
import
javax.swing.event.TreeExpansionEvent
;
import
javax.swing.event.TreeWillExpandListener
;
import
javax.swing.filechooser.FileNameExtensionFilter
;
import
javax.swing.tree.DefaultMutableTreeNode
;
import
javax.swing.tree.DefaultTreeCellRenderer
;
import
javax.swing.tree.DefaultTreeModel
;
import
javax.swing.tree.TreeNode
;
import
javax.swing.tree.TreePath
;
import
javax.swing.tree.TreeSelectionModel
;
import
org.fife.ui.rsyntaxtextarea.Theme
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
...
...
@@ -46,6 +71,7 @@ import jadx.gui.treemodel.JCertificate;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JLoadableNode
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.JPackage
;
import
jadx.gui.treemodel.JResource
;
import
jadx.gui.treemodel.JRoot
;
import
jadx.gui.update.JadxUpdate
;
...
...
@@ -57,8 +83,6 @@ import jadx.gui.utils.Link;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Utils
;
import
static
javax
.
swing
.
KeyStroke
.
getKeyStroke
;
@SuppressWarnings
(
"serial"
)
public
class
MainWindow
extends
JFrame
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
MainWindow
.
class
);
...
...
@@ -82,6 +106,7 @@ public class MainWindow extends JFrame {
private
static
final
ImageIcon
ICON_PREF
=
Utils
.
openIcon
(
"wrench"
);
private
static
final
ImageIcon
ICON_DEOBF
=
Utils
.
openIcon
(
"lock_edit"
);
private
static
final
ImageIcon
ICON_LOG
=
Utils
.
openIcon
(
"report"
);
private
static
final
ImageIcon
ICON_JADX
=
Utils
.
openIcon
(
"jadx-logo"
);
private
final
transient
JadxWrapper
wrapper
;
private
final
transient
JadxSettings
settings
;
...
...
@@ -116,16 +141,7 @@ public class MainWindow extends JFrame {
registerBundledFonts
();
initUI
();
initMenuAndToolbar
();
setWindowIcons
();
}
private
void
setWindowIcons
()
{
List
<
Image
>
icons
=
new
ArrayList
<>();
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-16px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-32px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-48px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo.png"
));
setIconImages
(
icons
);
Utils
.
setWindowIcons
(
this
);
loadSettings
();
checkForUpdate
();
}
...
...
@@ -323,6 +339,14 @@ public class MainWindow extends JFrame {
}
}
private
void
treeRightClickAction
(
MouseEvent
e
)
{
Object
obj
=
tree
.
getLastSelectedPathComponent
();
if
(
obj
instanceof
JPackage
)
{
JPackagePopUp
menu
=
new
JPackagePopUp
((
JPackage
)
obj
);
menu
.
show
(
e
.
getComponent
(),
e
.
getX
(),
e
.
getY
());
}
}
private
void
syncWithEditor
()
{
ContentPanel
selectedContentPanel
=
tabbedPane
.
getSelectedCodePanel
();
if
(
selectedContentPanel
==
null
)
{
...
...
@@ -462,7 +486,7 @@ public class MainWindow extends JFrame {
logAction
.
putValue
(
Action
.
ACCELERATOR_KEY
,
getKeyStroke
(
KeyEvent
.
VK_L
,
KeyEvent
.
CTRL_DOWN_MASK
|
KeyEvent
.
SHIFT_DOWN_MASK
));
Action
aboutAction
=
new
AbstractAction
(
NLS
.
str
(
"menu.about"
))
{
Action
aboutAction
=
new
AbstractAction
(
NLS
.
str
(
"menu.about"
)
,
ICON_JADX
)
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
new
AboutDialog
().
setVisible
(
true
);
...
...
@@ -582,7 +606,12 @@ public class MainWindow extends JFrame {
tree
.
addMouseListener
(
new
MouseAdapter
()
{
@Override
public
void
mouseClicked
(
MouseEvent
e
)
{
treeClickAction
();
if
(
SwingUtilities
.
isRightMouseButton
(
e
))
{
treeRightClickAction
(
e
);
}
else
{
treeClickAction
();
}
}
});
tree
.
addKeyListener
(
new
KeyAdapter
()
{
...
...
@@ -602,6 +631,9 @@ public class MainWindow extends JFrame {
if
(
value
instanceof
JNode
)
{
setIcon
(((
JNode
)
value
).
getIcon
());
}
if
(
value
instanceof
JPackage
)
{
setEnabled
(((
JPackage
)
value
).
isEnabled
());
}
return
c
;
}
});
...
...
@@ -748,4 +780,23 @@ public class MainWindow extends JFrame {
public
void
menuCanceled
(
MenuEvent
e
)
{
}
}
private
class
JPackagePopUp
extends
JPopupMenu
{
JMenuItem
excludeItem
=
new
JCheckBoxMenuItem
(
"Exclude"
);
public
JPackagePopUp
(
JPackage
pkg
)
{
excludeItem
.
setSelected
(!
pkg
.
isEnabled
());
add
(
excludeItem
);
excludeItem
.
addItemListener
(
e
->
{
String
fullName
=
pkg
.
getFullName
();
if
(
excludeItem
.
isSelected
())
{
wrapper
.
addExcludedPackage
(
fullName
);
}
else
{
wrapper
.
removeExcludedPackage
(
fullName
);
}
reOpenFile
();
});
}
}
}
jadx-gui/src/main/java/jadx/gui/utils/Utils.java
View file @
365c1faf
...
...
@@ -7,6 +7,8 @@ import java.awt.datatransfer.StringSelection;
import
java.awt.datatransfer.Transferable
;
import
java.io.InputStream
;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
...
...
@@ -191,4 +193,13 @@ public class Utils {
}
return
sb
.
toString
().
trim
();
}
public
static
void
setWindowIcons
(
Window
window
)
{
List
<
Image
>
icons
=
new
ArrayList
<>();
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-16px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-32px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo-48px.png"
));
icons
.
add
(
Utils
.
openImage
(
"/logos/jadx-logo.png"
));
window
.
setIconImages
(
icons
);
}
}
jadx-gui/src/main/resources/icons-16/jadx-logo.png
0 → 100644
View file @
365c1faf
814 Bytes
jadx-gui/src/main/resources/logos/jadx-logo.ico
View replaced file @
cf79a519
View file @
365c1faf
9.44 KB
|
W:
|
H:
14.7 KB
|
W:
|
H:
2-up
Swipe
Onion skin
jadx-gui/src/main/resources/logos/jadx-logo.svg
0 → 100644
View file @
365c1faf
<svg
id=
"Layer_1"
data-name=
"Layer 1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
viewBox=
"0 0 252.23 252"
><defs><style>
.cls-1,.cls-14{fill:none;}.cls-2{fill:#231f20;}.cls-3{fill:#461bbc;}.cls-4{clip-path:url(#clip-path);}.cls-5{clip-path:url(#clip-path-2);}.cls-6{fill:#008275;}.cls-7{font-size:132.44px;}.cls-12,.cls-7{fill:#fff;font-family:FuturaPT-Heavy, Futura PT;}.cls-8{letter-spacing:-0.03em;}.cls-9{clip-path:url(#clip-path-3);}.cls-10{fill:#f15a29;}.cls-11{fill:#9e1f63;}.cls-12{font-size:134.04px;letter-spacing:-0.01em;}.cls-13{letter-spacing:0em;}.cls-14{stroke:#fff;stroke-miterlimit:10;stroke-width:8.91px;}
</style><clipPath
id=
"clip-path"
transform=
"translate(0.23)"
><circle
class=
"cls-1"
cx=
"126"
cy=
"126"
r=
"125.72"
/></clipPath><clipPath
id=
"clip-path-2"
transform=
"translate(0.23)"
><polygon
class=
"cls-1"
points=
"45.29 223.57 176.25 75.9 258.09 69.98 258.09 242.47 45.29 242.47 45.29 223.57"
/></clipPath><clipPath
id=
"clip-path-3"
transform=
"translate(0.23)"
><polygon
class=
"cls-1"
points=
"57.93 195.53 179.7 63.23 69.69 5.58 3.53 19.58 -15.33 132.35 57.93 195.53"
/></clipPath></defs><title>
jadxlogo
</title><circle
class=
"cls-2"
cx=
"126.23"
cy=
"126"
r=
"126"
/><path
class=
"cls-3"
d=
"M122.66-68.19"
transform=
"translate(0.23)"
/><g
class=
"cls-4"
><g
class=
"cls-5"
><polygon
class=
"cls-3"
points=
"198.71 223.57 37.48 223.57 142.14 105.88 198.71 223.57"
/><polygon
class=
"cls-6"
points=
"170.52 74.83 238.84 87.48 247.15 198.65 190.4 207.09 142.14 105.88 170.52 74.83"
/><text
class=
"cls-7"
transform=
"translate(82.68 208.04) scale(0.95 1)"
><tspan
class=
"cls-8"
>
D
</tspan><tspan
x=
"86.48"
y=
"0"
>
X
</tspan></text></g><g
class=
"cls-9"
><polyline
class=
"cls-10"
points=
"73.68 193.85 0 126.28 140.52 53.49 171.12 88.7"
/><polyline
class=
"cls-11"
points=
"30.86 19.58 30.86 110.86 129.83 59.59 160.42 94.8 181.86 67.19"
/><text
class=
"cls-12"
transform=
"translate(10.71 121.84) scale(1.01 1)"
>
J
<tspan
class=
"cls-13"
x=
"54.29"
y=
"0"
>
A
</tspan></text></g></g><circle
class=
"cls-14"
cx=
"126.08"
cy=
"125.86"
r=
"120.86"
/></svg>
\ No newline at end of file
scripts/bintray-upload.sh
View file @
365c1faf
#!/usr/bin/env bash
set
-
x
e
set
-e
export
JFROG_CLI_OFFER_CONFIG
=
false
export
JFROG_CLI_LOG_LEVEL
=
DEBUG
npm
install
-g
jfrog-cli-go
TARGET
=
skylot
/jadx/
${
BINTRAY_PACKAGE
}
/v
${
JADX_VERSION
}
CREDENTIALS
=
"--user=
skylot
--key=
${
BINTRAY_KEY
}
"
TARGET
=
${
BINTRAY_USER
}
/jadx/
${
BINTRAY_PACKAGE
}
/v
${
JADX_VERSION
}
CREDENTIALS
=
"--user=
${
BINTRAY_USER
}
--key=
${
BINTRAY_KEY
}
"
jfrog bt version-create
${
TARGET
}
${
CREDENTIALS
}
--desc
=
${
JADX_VERSION
}
jfrog bt upload
'build/jadx.*\.(zip|exe)'
${
TARGET
}
${
CREDENTIALS
}
--regexp
=
true
--publish
=
true
...
...
scripts/travis-master.sh
View file @
365c1faf
#!/usr/bin/env bash
set
-
x
e
set
-e
# upload coverage to codecov
./gradlew clean build jacocoTestReport
...
...
scripts/travis-release.sh
View file @
365c1faf
#!/usr/bin/env bash
set
-
x
e
set
-e
npm
install
-g
semantic-release
npm
install
-g
semantic-release/exec
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment