diff --git a/.DS_Store b/.DS_Store
index 7c11c7830..eb8e5a2f7 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index 3065caeca..fab3b96fc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,9 +10,12 @@ out/
*.ipr
*.iws
+**/.DS_Store
+
bin/
target/
build/
+classes/
idea/
.gradle/
gradle.properties
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000..1690787fd
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,23 @@
+image: java:8
+
+variables:
+ GRADLE_OPTS: "-Dorg.gradle.daemon=false"
+ TERM: "dumb"
+
+before_script:
+ - chmod +x gradlew
+
+stages:
+ - build
+
+build:
+ stage: build
+ script:
+ - sed -i " 1 s/.*/&-b${CI_JOB_ID}/" version
+ - cat version
+ - ./gradlew -g /cache/.gradle clean build jacocoTestReport
+ - ./gradlew -g /cache/.gradle clean sonarqube -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_TOKEN
+ - ./gradlew -g /cache/.gradle clean dist
+ artifacts:
+ paths:
+ - build/jadx*.zip
diff --git a/.travis.yml b/.travis.yml
index f39d9e124..2d37e4d7b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,6 @@
language: java
jdk:
- oraclejdk8
- - oraclejdk7
- - openjdk6
before_install:
- chmod +x gradlew
diff --git a/README.md b/README.md
index 6e7418e81..1c803b158 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,13 @@
## JADX
[](https://travis-ci.org/skylot/jadx)
-[](https://drone.io/github.com/skylot/jadx/latest)
+[](https://gitlab.com/skylot/jadx/builds)
+[](https://gitlab.com/skylot/jadx/builds)
[](https://codecov.io/gh/skylot/jadx)
[](https://scan.coverity.com/projects/2166)
+[](https://sonarcloud.io/dashboard?id=jadx)
+[](https://github.com/skylot/jadx/releases/latest)
+[](https://github.com/skylot/jadx/releases/latest)
[](http://www.apache.org/licenses/LICENSE-2.0.html)
**jadx** - Dex to Java decompiler
@@ -12,13 +16,16 @@ Command line and GUI tools for produce Java source code from Android Dex and Apk

+
### Downloads
-- [unstable](https://drone.io/github.com/skylot/jadx/files)
+- [unstable](https://gitlab.com/skylot/jadx/builds/artifacts/master/browse/build?job=build)
- from [github](https://github.com/skylot/jadx/releases)
- from [sourceforge](http://sourceforge.net/projects/jadx/files/)
### Building from source
+Java 8 JDK or higher must be installed:
+
git clone https://github.com/skylot/jadx.git
cd jadx
./gradlew dist
@@ -34,7 +41,7 @@ Run **jadx** on itself:
cd build/jadx/
bin/jadx -d out lib/jadx-core-*.jar
- #or
+ # or
bin/jadx-gui lib/jadx-core-*.jar
@@ -82,12 +89,7 @@ To support this project you can:
* Java code examples which decompiles incorrectly
* Error log and link to _public available_ apk file or app page on Google play
-And any other comments will be very helpfull,
-because at current stage of development it is very time consuming
-to **find** new bugs, design and implement new features.
-Also I need to **prioritize** these task for complete most important at first.
-
---------------------------------------
*Licensed under the Apache 2.0 License*
-*Copyright 2016 by Skylot*
+*Copyright 2018 by Skylot*
diff --git a/build.gradle b/build.gradle
index 83bf5179c..10f30aa84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,3 +1,8 @@
+plugins {
+ id 'com.github.ksoichiro.console.reporter' version '0.5.0'
+ id 'org.sonarqube' version '2.4'
+}
+
ext.jadxVersion = file('version').readLines().get(0)
version = jadxVersion
@@ -5,12 +10,13 @@ allprojects {
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'jacoco'
+ apply plugin: 'com.github.ksoichiro.console.reporter'
version = jadxVersion
tasks.withType(JavaCompile) {
- sourceCompatibility = JavaVersion.VERSION_1_6
- targetCompatibility = JavaVersion.VERSION_1_6
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
if (!"$it".contains(':jadx-samples:')) {
options.compilerArgs << '-Xlint' << '-Xlint:unchecked' << '-Xlint:deprecation'
@@ -49,6 +55,13 @@ allprojects {
}
}
+sonarqube {
+ properties {
+ property 'sonar.exclusions', '**/jadx/samples/**/*,**/test-app/**/*'
+ property 'sonar.coverage.exclusions', '**/jadx/gui/**/*'
+ }
+}
+
task copyArtifacts(type: Sync, dependsOn: ['jadx-cli:installDist', 'jadx-gui:installDist']) {
destinationDir file("$buildDir/jadx")
['jadx-cli', 'jadx-gui'].each {
@@ -72,9 +85,6 @@ task samples(dependsOn: 'jadx-samples:samples') {
task testAppCheck(dependsOn: 'jadx-test-app:testAppCheck') {
}
-task pitest(overwrite: true, dependsOn: 'jadx-core:pitest') {
-}
-
task cleanBuildDir(type: Delete) {
delete buildDir
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 085a1cdc2..99340b4ad 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 165e8bb21..2c2bbe5f9 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=http\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip
diff --git a/gradlew b/gradlew
index 91a7e269e..cccdd3d51 100755
--- a/gradlew
+++ b/gradlew
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
##############################################################################
##
@@ -6,47 +6,6 @@
##
##############################################################################
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn ( ) {
- echo "$*"
-}
-
-die ( ) {
- echo
- echo "$*"
- echo
- exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
-esac
-
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +20,49 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -90,7 +89,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -114,6 +113,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,11 +154,19 @@ if $cygwin ; then
esac
fi
-# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
-function splitJvmOpts() {
- JVM_OPTS=("$@")
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
}
-eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
-JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+APP_ARGS=$(save "$@")
-exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index aec99730b..e95643d6a 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
-
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,10 +46,9 @@ echo location of your Java installation.
goto fail
:init
-@rem Get command-line arguments, handling Windowz variants
+@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
-if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -60,11 +59,6 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
-goto execute
-
-:4NT_args
-@rem Get arguments from the 4NT Shell from JP Software
-set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
diff --git a/jadx-cli/build.gradle b/jadx-cli/build.gradle
index e58594bde..131f8a91a 100644
--- a/jadx-cli/build.gradle
+++ b/jadx-cli/build.gradle
@@ -18,3 +18,6 @@ applicationDistribution.with {
}
}
+startScripts {
+ defaultJvmOpts = [ '-Xms2g', '-Xmx4g' ]
+}
diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java
index 1aed0f167..d67d7183e 100644
--- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java
@@ -1,23 +1,23 @@
package jadx.cli;
-import jadx.api.JadxDecompiler;
-import jadx.core.utils.exceptions.JadxException;
-
import java.io.File;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import jadx.api.JadxDecompiler;
+import jadx.core.utils.exceptions.JadxException;
+
public class JadxCLI {
private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class);
- public static void main(String[] args) throws JadxException {
+ public static void main(String[] args) {
try {
JadxCLIArgs jadxArgs = new JadxCLIArgs();
if (processArgs(jadxArgs, args)) {
processAndSave(jadxArgs);
}
- } catch (Throwable e) {
+ } catch (Exception e) {
LOG.error("jadx error: {}", e.getMessage(), e);
System.exit(1);
}
diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
index 8d70658fe..488def2fb 100644
--- a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+++ b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
@@ -1,11 +1,5 @@
package jadx.cli;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import jadx.api.IJadxArgs;
-import jadx.api.JadxDecompiler;
-import jadx.core.utils.exceptions.JadxException;
-
import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Field;
@@ -14,17 +8,24 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterDescription;
import com.beust.jcommander.ParameterException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jadx.api.IJadxArgs;
+import jadx.api.JadxDecompiler;
+import jadx.core.utils.exceptions.JadxException;
public class JadxCLIArgs implements IJadxArgs {
+ protected static final int DEFAULT_THREADS_COUNT = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
+
@Parameter(description = " (.dex, .apk, .jar or .class)")
protected List files;
@@ -32,7 +33,7 @@ public class JadxCLIArgs implements IJadxArgs {
protected String outDirName;
@Parameter(names = {"-j", "--threads-count"}, description = "processing threads count")
- protected int threadsCount = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
+ protected int threadsCount = DEFAULT_THREADS_COUNT;
@Parameter(names = {"-r", "--no-res"}, description = "do not decode resources")
protected boolean skipResources = false;
@@ -83,7 +84,7 @@ public class JadxCLIArgs implements IJadxArgs {
@Parameter(names = {"-h", "--help"}, description = "print this help", help = true)
protected boolean printHelp = false;
- private final List input = new ArrayList(1);
+ private final List input = new ArrayList<>(1);
private File outputDir;
public boolean processArgs(String[] args) {
@@ -108,7 +109,7 @@ public class JadxCLIArgs implements IJadxArgs {
}
try {
if (threadsCount <= 0) {
- throw new JadxException("Threads count must be positive");
+ throw new JadxException("Threads count must be positive, got: " + threadsCount);
}
if (files != null) {
for (String fileName : files) {
@@ -154,7 +155,7 @@ public class JadxCLIArgs implements IJadxArgs {
out.println("options:");
List params = jc.getParameters();
- Map paramsMap = new LinkedHashMap(params.size());
+ Map paramsMap = new LinkedHashMap<>(params.size());
int maxNamesLen = 0;
for (ParameterDescription p : params) {
paramsMap.put(p.getParameterized().getName(), p);
diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle
index ed6b2ccff..a5f47fde1 100644
--- a/jadx-core/build.gradle
+++ b/jadx-core/build.gradle
@@ -3,7 +3,7 @@ ext.jadxClasspath = 'clsp-data/android-5.1.jar'
dependencies {
runtime files(jadxClasspath)
- compile files('lib/dx-1.10.jar')
+ compile files('lib/dx-1.13.jar')
compile 'commons-io:commons-io:2.4'
compile 'org.ow2.asm:asm:5.0.3'
compile 'com.intellij:annotations:12.0'
diff --git a/jadx-core/lib/dx-1.10.jar b/jadx-core/lib/dx-1.10.jar
deleted file mode 100644
index 727999dd9..000000000
Binary files a/jadx-core/lib/dx-1.10.jar and /dev/null differ
diff --git a/jadx-core/lib/dx-1.13.jar b/jadx-core/lib/dx-1.13.jar
new file mode 100644
index 000000000..37773c811
Binary files /dev/null and b/jadx-core/lib/dx-1.13.jar differ
diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java
index 5382b02e0..680e9b977 100644
--- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java
@@ -26,6 +26,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -53,7 +54,7 @@ public final class JadxDecompiler {
private static final Logger LOG = LoggerFactory.getLogger(JadxDecompiler.class);
private final IJadxArgs args;
- private final List inputFiles = new ArrayList();
+ private final List inputFiles = new ArrayList<>();
private File outDir;
@@ -66,9 +67,9 @@ public final class JadxDecompiler {
private BinaryXMLParser xmlParser;
- private Map classesMap = new HashMap();
- private Map methodsMap = new HashMap();
- private Map fieldsMap = new HashMap();
+ private Map classesMap = new ConcurrentHashMap<>();
+ private Map methodsMap = new ConcurrentHashMap<>();
+ private Map fieldsMap = new ConcurrentHashMap<>();
public JadxDecompiler() {
this(new JadxArgs());
@@ -139,12 +140,13 @@ public final class JadxDecompiler {
}
private void save(boolean saveSources, boolean saveResources) {
+ ExecutorService ex = getSaveExecutor(saveSources, saveResources);
+ ex.shutdown();
try {
- ExecutorService ex = getSaveExecutor(saveSources, saveResources);
- ex.shutdown();
ex.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
- throw new JadxRuntimeException("Save interrupted", e);
+ LOG.error("Save interrupted", e);
+ Thread.currentThread().interrupt();
}
}
@@ -188,17 +190,14 @@ public final class JadxDecompiler {
}
}
- private void appendSourcesSave(ExecutorService executor, final File outDir) {
- for (final JavaClass cls : getClasses()) {
+ private void appendSourcesSave(ExecutorService executor, File outDir) {
+ for (JavaClass cls : getClasses()) {
if (cls.getClassNode().contains(AFlag.DONT_GENERATE)) {
continue;
}
- executor.execute(new Runnable() {
- @Override
- public void run() {
- cls.decompile();
- SaveCode.save(outDir, args, cls.getClassNode());
- }
+ executor.execute(() -> {
+ cls.decompile();
+ SaveCode.save(outDir, args, cls.getClassNode());
});
}
}
@@ -209,7 +208,7 @@ public final class JadxDecompiler {
}
if (classes == null) {
List classNodeList = root.getClasses(false);
- List clsList = new ArrayList(classNodeList.size());
+ List clsList = new ArrayList<>(classNodeList.size());
classesMap.clear();
for (ClassNode classNode : classNodeList) {
JavaClass javaClass = new JavaClass(classNode, this);
@@ -236,28 +235,19 @@ public final class JadxDecompiler {
if (classList.isEmpty()) {
return Collections.emptyList();
}
- Map> map = new HashMap>();
+ Map> map = new HashMap<>();
for (JavaClass javaClass : classList) {
String pkg = javaClass.getPackage();
- List clsList = map.get(pkg);
- if (clsList == null) {
- clsList = new ArrayList();
- map.put(pkg, clsList);
- }
+ List clsList = map.computeIfAbsent(pkg, k -> new ArrayList<>());
clsList.add(javaClass);
}
- List packages = new ArrayList(map.size());
+ List packages = new ArrayList<>(map.size());
for (Map.Entry> entry : map.entrySet()) {
packages.add(new JavaPackage(entry.getKey(), entry.getValue()));
}
Collections.sort(packages);
for (JavaPackage pkg : packages) {
- Collections.sort(pkg.getClasses(), new Comparator() {
- @Override
- public int compare(JavaClass o1, JavaClass o2) {
- return o1.getName().compareTo(o2.getName());
- }
- });
+ pkg.getClasses().sort(Comparator.comparing(JavaClass::getName));
}
return Collections.unmodifiableList(packages);
}
diff --git a/jadx-core/src/main/java/jadx/api/JavaClass.java b/jadx-core/src/main/java/jadx/api/JavaClass.java
index 4c48d81d0..e4ef762b0 100644
--- a/jadx-core/src/main/java/jadx/api/JavaClass.java
+++ b/jadx-core/src/main/java/jadx/api/JavaClass.java
@@ -72,7 +72,7 @@ public final class JavaClass implements JavaNode {
JadxDecompiler rootDecompiler = getRootDecompiler();
int inClsCount = cls.getInnerClasses().size();
if (inClsCount != 0) {
- List list = new ArrayList(inClsCount);
+ List list = new ArrayList<>(inClsCount);
for (ClassNode inner : cls.getInnerClasses()) {
if (!inner.contains(AFlag.DONT_GENERATE)) {
JavaClass javaClass = new JavaClass(inner, this);
@@ -86,7 +86,7 @@ public final class JavaClass implements JavaNode {
int fieldsCount = cls.getFields().size();
if (fieldsCount != 0) {
- List flds = new ArrayList(fieldsCount);
+ List flds = new ArrayList<>(fieldsCount);
for (FieldNode f : cls.getFields()) {
if (!f.contains(AFlag.DONT_GENERATE)) {
JavaField javaField = new JavaField(f, this);
@@ -99,7 +99,7 @@ public final class JavaClass implements JavaNode {
int methodsCount = cls.getMethods().size();
if (methodsCount != 0) {
- List mths = new ArrayList(methodsCount);
+ List mths = new ArrayList<>(methodsCount);
for (MethodNode m : cls.getMethods()) {
if (!m.contains(AFlag.DONT_GENERATE)) {
JavaMethod javaMethod = new JavaMethod(this, m);
@@ -134,7 +134,7 @@ public final class JavaClass implements JavaNode {
if (map.isEmpty() || decompiler == null) {
return Collections.emptyMap();
}
- Map resultMap = new HashMap(map.size());
+ Map resultMap = new HashMap<>(map.size());
for (Map.Entry entry : map.entrySet()) {
CodePosition codePosition = entry.getKey();
Object obj = entry.getValue();
diff --git a/jadx-core/src/main/java/jadx/api/ResourceFile.java b/jadx-core/src/main/java/jadx/api/ResourceFile.java
index 48da90881..182fb4f22 100644
--- a/jadx-core/src/main/java/jadx/api/ResourceFile.java
+++ b/jadx-core/src/main/java/jadx/api/ResourceFile.java
@@ -56,7 +56,7 @@ public class ResourceFile {
this.zipRef = zipRef;
}
- ZipRef getZipRef() {
+ public ZipRef getZipRef() {
return zipRef;
}
diff --git a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java
index dc21fb3b6..38599df14 100644
--- a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java
+++ b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java
@@ -12,6 +12,7 @@ import jadx.core.xmlgen.ResTableParser;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -40,7 +41,7 @@ public final class ResourcesLoader {
}
List load(List inputFiles) {
- List list = new ArrayList(inputFiles.size());
+ List list = new ArrayList<>(inputFiles.size());
for (InputFile file : inputFiles) {
loadFile(list, file.getFile());
}
@@ -52,48 +53,49 @@ public final class ResourcesLoader {
}
public static ResContainer decodeStream(ResourceFile rf, ResourceDecoder decoder) throws JadxException {
- ZipRef zipRef = rf.getZipRef();
- if (zipRef == null) {
- return null;
- }
ZipFile zipFile = null;
InputStream inputStream = null;
- ResContainer result = null;
+ ResContainer result;
try {
- zipFile = new ZipFile(zipRef.getZipFile());
- ZipEntry entry = zipFile.getEntry(zipRef.getEntryName());
- if (entry == null) {
- throw new IOException("Zip entry not found: " + zipRef);
+ long size;
+ ZipRef zipRef = rf.getZipRef();
+ if (zipRef == null) {
+ File file = new File(rf.getName());
+ inputStream = new BufferedInputStream(new FileInputStream(file));
+ size = file.length();
+ } else {
+ zipFile = new ZipFile(zipRef.getZipFile());
+ ZipEntry entry = zipFile.getEntry(zipRef.getEntryName());
+
+ if(!ZipSecurity.isValidZipEntry(entry)) {
+ return null;
+ }
+
+ if (entry == null) {
+ throw new IOException("Zip entry not found: " + zipRef);
+ }
+ inputStream = new BufferedInputStream(zipFile.getInputStream(entry));
+ size = entry.getSize();
}
- if(!ZipSecurity.isValidZipEntry(entry)) {
- return null;
- }
-
- inputStream = new BufferedInputStream(zipFile.getInputStream(entry));
- result = decoder.decode(entry.getSize(), inputStream);
+ result = decoder.decode(size, inputStream);
} catch (Exception e) {
- throw new JadxException("Error decode: " + zipRef.getEntryName(), e);
+ throw new JadxException("Error decode: " + rf.getName(), e);
} finally {
try {
if (zipFile != null) {
zipFile.close();
}
} catch (Exception e) {
- LOG.error("Error close zip file: {}", zipRef, e);
+ LOG.error("Error close zip file: {}", rf.getName(), e);
}
close(inputStream);
}
return result;
}
- static ResContainer loadContent(final JadxDecompiler jadxRef, final ResourceFile rf) {
+ static ResContainer loadContent(JadxDecompiler jadxRef, ResourceFile rf) {
try {
- return decodeStream(rf, new ResourceDecoder() {
- @Override
- public ResContainer decode(long size, InputStream is) throws IOException {
- return loadContent(jadxRef, rf, is, size);
- }
- });
+ return decodeStream(rf, (size, is) -> loadContent(jadxRef, rf, is, size));
} catch (JadxException e) {
LOG.error("Decode error", e);
CodeWriter cw = new CodeWriter();
@@ -140,6 +142,7 @@ public final class ResourcesLoader {
}
} catch (IOException e) {
LOG.debug("Not a zip file: {}", file.getAbsolutePath());
+ addResourceFile(list, file);
} finally {
if (zip != null) {
try {
@@ -151,6 +154,13 @@ public final class ResourcesLoader {
}
}
+ private void addResourceFile(List list, File file) {
+ String name = file.getAbsolutePath();
+ ResourceType type = ResourceType.getFileType(name);
+ ResourceFile rf = new ResourceFile(jadxRef, name, type);
+ list.add(rf);
+ }
+
private void addEntry(List list, File zipFile, ZipEntry entry) {
if (entry.isDirectory()) {
return;
diff --git a/jadx-core/src/main/java/jadx/core/Jadx.java b/jadx-core/src/main/java/jadx/core/Jadx.java
index 739888e25..aba779605 100644
--- a/jadx-core/src/main/java/jadx/core/Jadx.java
+++ b/jadx-core/src/main/java/jadx/core/Jadx.java
@@ -46,6 +46,9 @@ import org.slf4j.LoggerFactory;
public class Jadx {
private static final Logger LOG = LoggerFactory.getLogger(Jadx.class);
+ private Jadx() {
+ }
+
static {
if (Consts.DEBUG) {
LOG.info("debug enabled");
@@ -53,7 +56,7 @@ public class Jadx {
}
public static List getPassesList(IJadxArgs args, File outDir) {
- List passes = new ArrayList();
+ List passes = new ArrayList<>();
if (args.isFallbackMode()) {
passes.add(new FallbackModeVisitor());
} else {
diff --git a/jadx-core/src/main/java/jadx/core/ProcessClass.java b/jadx-core/src/main/java/jadx/core/ProcessClass.java
index 868899e09..c62816230 100644
--- a/jadx-core/src/main/java/jadx/core/ProcessClass.java
+++ b/jadx-core/src/main/java/jadx/core/ProcessClass.java
@@ -9,8 +9,6 @@ import jadx.core.utils.ErrorsCounter;
import java.util.List;
import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import static jadx.core.dex.nodes.ProcessState.GENERATED;
import static jadx.core.dex.nodes.ProcessState.NOT_LOADED;
@@ -19,7 +17,6 @@ import static jadx.core.dex.nodes.ProcessState.STARTED;
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
public final class ProcessClass {
- private static final Logger LOG = LoggerFactory.getLogger(ProcessClass.class);
private ProcessClass() {
}
@@ -28,7 +25,7 @@ public final class ProcessClass {
if (codeGen == null && cls.getState() == PROCESSED) {
return;
}
- synchronized (cls) {
+ synchronized (cls.getClassInfo()) {
try {
if (cls.getState() == NOT_LOADED) {
cls.load();
@@ -54,7 +51,7 @@ public final class ProcessClass {
}
}
- static void processDependencies(ClassNode cls, List passes) {
+ private static void processDependencies(ClassNode cls, List passes) {
for (ClassNode depCls : cls.getDependencies()) {
process(depCls, passes, null);
}
diff --git a/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java b/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
index 76c190a1b..e0fe1da11 100644
--- a/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
+++ b/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java
@@ -49,7 +49,7 @@ public class ClsSet {
public void load(RootNode root) {
List list = root.getClasses(true);
- Map names = new HashMap(list.size());
+ Map names = new HashMap<>(list.size());
int k = 0;
for (ClassNode cls : list) {
String clsRawName = cls.getRawName();
@@ -79,7 +79,7 @@ public class ClsSet {
}
public static NClass[] makeParentsArray(ClassNode cls, Map names) {
- List parents = new ArrayList(1 + cls.getInterfaces().size());
+ List parents = new ArrayList<>(1 + cls.getInterfaces().size());
ArgType superClass = cls.getSuperClass();
if (superClass != null) {
NClass c = getCls(superClass.getObject(), names);
@@ -106,9 +106,7 @@ public class ClsSet {
void save(File output) throws IOException {
FileUtils.makeDirsForFile(output);
-
- BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(output));
- try {
+ try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(output))) {
String outputName = output.getName();
if (outputName.endsWith(CLST_EXTENSION)) {
save(outputStream);
@@ -123,14 +121,11 @@ public class ClsSet {
} else {
throw new JadxRuntimeException("Unknown file format: " + outputName);
}
- } finally {
- close(outputStream);
}
}
public void save(OutputStream output) throws IOException {
- DataOutputStream out = new DataOutputStream(output);
- try {
+ try (DataOutputStream out = new DataOutputStream(output)) {
out.writeBytes(JADX_CLS_SET_HEADER);
out.writeByte(VERSION);
@@ -146,32 +141,25 @@ public class ClsSet {
out.writeInt(parent.getId());
}
}
- } finally {
- close(out);
}
}
public void load() throws IOException, DecodeException {
- InputStream input = getClass().getResourceAsStream(CLST_FILENAME);
- if (input == null) {
- throw new JadxRuntimeException("Can't load classpath file: " + CLST_FILENAME);
- }
- try {
+ try (InputStream input = getClass().getResourceAsStream(CLST_FILENAME)) {
+ if (input == null) {
+ throw new JadxRuntimeException("Can't load classpath file: " + CLST_FILENAME);
+ }
load(input);
- } finally {
- close(input);
}
}
public void load(File input) throws IOException, DecodeException {
String name = input.getName();
- InputStream inputStream = new FileInputStream(input);
- try {
+ try (InputStream inputStream = new FileInputStream(input)) {
if (name.endsWith(CLST_EXTENSION)) {
load(inputStream);
} else if (name.endsWith(".jar")) {
- ZipInputStream in = new ZipInputStream(inputStream);
- try {
+ try (ZipInputStream in = new ZipInputStream(inputStream)) {
ZipEntry entry = in.getNextEntry();
while (entry != null) {
if (entry.getName().endsWith(CLST_EXTENSION) && ZipSecurity.isValidZipEntry(entry)) {
@@ -179,20 +167,15 @@ public class ClsSet {
}
entry = in.getNextEntry();
}
- } finally {
- close(in);
}
} else {
throw new JadxRuntimeException("Unknown file format: " + name);
}
- } finally {
- close(inputStream);
}
}
public void load(InputStream input) throws IOException, DecodeException {
- DataInputStream in = new DataInputStream(input);
- try {
+ try (DataInputStream in = new DataInputStream(input)) {
byte[] header = new byte[JADX_CLS_SET_HEADER.length()];
int readHeaderLength = in.read(header);
int version = in.readByte();
@@ -215,8 +198,6 @@ public class ClsSet {
}
classes[i].setParents(parents);
}
- } finally {
- close(in);
}
}
diff --git a/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java b/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
index 2f78059c8..168cc74d5 100644
--- a/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
+++ b/jadx-core/src/main/java/jadx/core/clsp/ClspGraph.java
@@ -23,10 +23,10 @@ import org.slf4j.LoggerFactory;
public class ClspGraph {
private static final Logger LOG = LoggerFactory.getLogger(ClspGraph.class);
- private final Map> ancestorCache = new WeakHashMap>();
+ private final Map> ancestorCache = Collections.synchronizedMap(new WeakHashMap>());
private Map nameMap;
- private final Set missingClasses = new HashSet();
+ private final Set missingClasses = new HashSet<>();
public void load() throws IOException, DecodeException {
ClsSet set = new ClsSet();
@@ -36,7 +36,7 @@ public class ClspGraph {
public void addClasspath(ClsSet set) {
if (nameMap == null) {
- nameMap = new HashMap(set.getClassesCount());
+ nameMap = new HashMap<>(set.getClassesCount());
set.addToMap(nameMap);
} else {
throw new JadxRuntimeException("Classpath already loaded");
@@ -110,7 +110,7 @@ public class ClspGraph {
missingClasses.add(clsName);
return Collections.emptySet();
}
- result = new HashSet();
+ result = new HashSet<>();
addAncestorsNames(cls, result);
if (result.isEmpty()) {
result = Collections.emptySet();
@@ -133,7 +133,7 @@ public class ClspGraph {
}
LOG.warn("Found {} references to unknown classes", count);
if (LOG.isDebugEnabled()) {
- List clsNames = new ArrayList(missingClasses);
+ List clsNames = new ArrayList<>(missingClasses);
Collections.sort(clsNames);
for (String cls : clsNames) {
LOG.debug(" {}", cls);
diff --git a/jadx-core/src/main/java/jadx/core/clsp/ConvertToClsSet.java b/jadx-core/src/main/java/jadx/core/clsp/ConvertToClsSet.java
index 2d4485fd2..0b257a250 100644
--- a/jadx-core/src/main/java/jadx/core/clsp/ConvertToClsSet.java
+++ b/jadx-core/src/main/java/jadx/core/clsp/ConvertToClsSet.java
@@ -30,7 +30,7 @@ public class ConvertToClsSet {
}
File output = new File(args[0]);
- List inputFiles = new ArrayList(args.length - 1);
+ List inputFiles = new ArrayList<>(args.length - 1);
for (int i = 1; i < args.length; i++) {
File f = new File(args[i]);
if (f.isDirectory()) {
diff --git a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
index 60f760863..0216d24cd 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
@@ -54,7 +54,7 @@ public class ClassGen {
private final boolean fallback;
private final boolean showInconsistentCode;
- private final Set imports = new HashSet();
+ private final Set imports = new HashSet<>();
private int clsDeclLine;
public ClassGen(ClassNode cls, IJadxArgs jadxArgs) {
@@ -89,7 +89,7 @@ public class ClassGen {
}
int importsCount = imports.size();
if (importsCount != 0) {
- List sortImports = new ArrayList(importsCount);
+ List sortImports = new ArrayList<>(importsCount);
for (ClassInfo ic : imports) {
sortImports.add(ic.getAlias().getFullName());
}
@@ -273,7 +273,7 @@ public class ClassGen {
}
private static List sortMethodsByLine(List methods) {
- List out = new ArrayList(methods);
+ List out = new ArrayList<>(methods);
Collections.sort(out, METHOD_LINE_COMPARATOR);
return out;
}
@@ -339,6 +339,10 @@ public class ClassGen {
continue;
}
annotationGen.addForField(code, f);
+
+ if (f.getFieldInfo().isRenamed()) {
+ code.startLine("/* renamed from: ").add(f.getName()).add(" */");
+ }
code.startLine(f.getAccessFlags().makeString());
useType(code, f.getType());
code.add(' ');
@@ -586,9 +590,8 @@ public class ClassGen {
private void insertRenameInfo(CodeWriter code, ClassNode cls) {
ClassInfo classInfo = cls.getClassInfo();
- if (classInfo.isRenamed()
- && !cls.getShortName().equals(cls.getAlias().getShortName())) {
- code.startLine("/* renamed from: ").add(classInfo.getFullName()).add(" */");
+ if (classInfo.isRenamed()) {
+ code.startLine("/* renamed from: ").add(classInfo.getType().getObject()).add(" */");
}
}
diff --git a/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java b/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
index 3fb1e9150..1db7a9146 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
@@ -16,23 +16,21 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static jadx.core.utils.files.FileUtils.close;
-
public class CodeWriter {
private static final Logger LOG = LoggerFactory.getLogger(CodeWriter.class);
public static final String NL = System.getProperty("line.separator");
- public static final String INDENT = " ";
+ public static final String INDENT_STR = " ";
private static final boolean ADD_LINE_NUMBERS = false;
private static final String[] INDENT_CACHE = {
"",
- INDENT,
- INDENT + INDENT,
- INDENT + INDENT + INDENT,
- INDENT + INDENT + INDENT + INDENT,
- INDENT + INDENT + INDENT + INDENT + INDENT,
+ INDENT_STR,
+ INDENT_STR + INDENT_STR,
+ INDENT_STR + INDENT_STR + INDENT_STR,
+ INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR,
+ INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR + INDENT_STR,
};
private StringBuilder buf = new StringBuilder();
@@ -127,7 +125,7 @@ public class CodeWriter {
}
public CodeWriter addIndent() {
- add(INDENT);
+ add(INDENT_STR);
return this;
}
@@ -148,9 +146,9 @@ public class CodeWriter {
if (curIndent < INDENT_CACHE.length) {
this.indentStr = INDENT_CACHE[curIndent];
} else {
- StringBuilder s = new StringBuilder(curIndent * INDENT.length());
+ StringBuilder s = new StringBuilder(curIndent * INDENT_STR.length());
for (int i = 0; i < curIndent; i++) {
- s.append(INDENT);
+ s.append(INDENT_STR);
}
this.indentStr = s.toString();
}
@@ -209,7 +207,7 @@ public class CodeWriter {
private Object attachAnnotation(Object obj, CodePosition pos) {
if (annotations.isEmpty()) {
- annotations = new HashMap();
+ annotations = new HashMap<>();
}
return annotations.put(pos, obj);
}
@@ -227,7 +225,7 @@ public class CodeWriter {
private void attachSourceLine(int decompiledLine, int sourceLine) {
if (lineMap.isEmpty()) {
- lineMap = new TreeMap();
+ lineMap = new TreeMap<>();
}
lineMap.put(decompiledLine, sourceLine);
}
@@ -286,15 +284,10 @@ public class CodeWriter {
finish();
}
File outFile = FileUtils.prepareFile(file);
- PrintWriter out = null;
- try {
- out = new PrintWriter(outFile, "UTF-8");
+ try (PrintWriter out = new PrintWriter(outFile, "UTF-8")) {
out.println(code);
} catch (Exception e) {
LOG.error("Save file error", e);
- } finally {
- close(out);
}
}
-
}
diff --git a/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java b/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
index 6f1f5e9b0..b9c66395f 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
@@ -26,7 +26,7 @@ public class ConditionGen extends InsnGen {
private static final Logger LOG = LoggerFactory.getLogger(ConditionGen.class);
private static class CondStack {
- private final Queue stack = new LinkedList();
+ private final Queue stack = new LinkedList<>();
public Queue getStack() {
return stack;
diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
index 471834eea..31f58a15e 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
@@ -752,7 +752,7 @@ public class InsnGen {
}
// replace args
InsnNode inlCopy = inl.copy();
- List inlArgs = new ArrayList();
+ List inlArgs = new ArrayList<>();
inlCopy.getRegisterArgs(inlArgs);
for (RegisterArg r : inlArgs) {
int regNum = r.getRegNum();
diff --git a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
index b38936901..0d6dad9d2 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
@@ -80,6 +80,10 @@ public class MethodGen {
if (clsAccFlags.isAnnotation()) {
ai = ai.remove(AccessFlags.ACC_PUBLIC);
}
+
+ if (mth.getMethodInfo().isRenamed()) {
+ code.startLine("/* renamed from: ").add(mth.getName()).add(" */");
+ }
code.startLineWithNum(mth.getSourceLine());
code.add(ai.makeString());
@@ -129,7 +133,7 @@ public class MethodGen {
annotationGen.addForParameter(argsCode, paramsAnnotation, i);
}
SSAVar argSVar = arg.getSVar();
- if (argSVar!= null && argSVar.contains(AFlag.FINAL)) {
+ if (argSVar != null && argSVar.contains(AFlag.FINAL)) {
argsCode.add("final ");
}
if (!it.hasNext() && mth.getAccessFlags().isVarArgs()) {
diff --git a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java
index b8f16be78..535d9007c 100644
--- a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+++ b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java
@@ -26,12 +26,12 @@ public class NameGen {
private static final Map OBJ_ALIAS;
- private final Set varNames = new HashSet();
+ private final Set varNames = new HashSet<>();
private final MethodNode mth;
private final boolean fallback;
static {
- OBJ_ALIAS = new HashMap();
+ OBJ_ALIAS = new HashMap<>();
OBJ_ALIAS.put(Consts.CLASS_STRING, "str");
OBJ_ALIAS.put(Consts.CLASS_CLASS, "cls");
OBJ_ALIAS.put(Consts.CLASS_THROWABLE, "th");
@@ -164,6 +164,9 @@ public class NameGen {
if (vName != null) {
return vName;
}
+ if (shortName != null) {
+ return StringUtils.escape(shortName.toLowerCase());
+ }
}
return StringUtils.escape(type.toString());
}
diff --git a/jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java b/jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
index 5918204ed..81af0224b 100644
--- a/jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
+++ b/jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
@@ -24,9 +24,9 @@ class DeobfPresets {
private final Deobfuscator deobfuscator;
private final File deobfMapFile;
- private final Map clsPresetMap = new HashMap();
- private final Map fldPresetMap = new HashMap();
- private final Map mthPresetMap = new HashMap();
+ private final Map clsPresetMap = new HashMap<>();
+ private final Map fldPresetMap = new HashMap<>();
+ private final Map mthPresetMap = new HashMap<>();
public DeobfPresets(Deobfuscator deobfuscator, File deobfMapFile) {
this.deobfuscator = deobfuscator;
@@ -98,7 +98,7 @@ class DeobfPresets {
* Saves DefaultDeobfuscator presets
*/
private void dumpMapping() throws IOException {
- List list = new ArrayList();
+ List list = new ArrayList<>();
// packages
for (PackageNode p : deobfuscator.getRootPackage().getInnerPackages()) {
for (PackageNode pp : p.getInnerPackages()) {
diff --git a/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java b/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
index 4a8bad03b..a01f7be4f 100644
--- a/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+++ b/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
@@ -16,7 +16,6 @@ import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -40,15 +39,15 @@ public class Deobfuscator {
private final List dexNodes;
private final DeobfPresets deobfPresets;
- private final Map clsMap = new HashMap();
- private final Map fldMap = new HashMap();
- private final Map mthMap = new HashMap();
+ private final Map clsMap = new HashMap<>();
+ private final Map fldMap = new HashMap<>();
+ private final Map mthMap = new HashMap<>();
- private final Map ovrdMap = new HashMap();
- private final List ovrd = new ArrayList();
+ private final Map ovrdMap = new HashMap<>();
+ private final List ovrd = new ArrayList<>();
private final PackageNode rootPackage = new PackageNode("");
- private final Set pkgSet = new TreeSet();
+ private final Set pkgSet = new TreeSet<>();
private final int maxLength;
private final int minLength;
@@ -111,22 +110,23 @@ public class Deobfuscator {
private void postProcess() {
int id = 1;
for (OverridedMethodsNode o : ovrd) {
-
- Iterator it = o.getMethods().iterator();
- if (it.hasNext()) {
- MethodInfo mth = it.next();
-
- if (mth.isRenamed() && !mth.isAliasFromPreset()) {
- mth.setAlias(String.format("mo%d%s", id, makeName(mth.getName())));
+ boolean aliasFromPreset = false;
+ String aliasToUse = null;
+ for (MethodInfo mth : o.getMethods()) {
+ if (mth.isAliasFromPreset()) {
+ aliasToUse = mth.getAlias();
+ aliasFromPreset = true;
}
- String firstMethodAlias = mth.getAlias();
-
- while (it.hasNext()) {
- mth = it.next();
- if (!mth.getAlias().equals(firstMethodAlias)) {
- mth.setAlias(firstMethodAlias);
+ }
+ for (MethodInfo mth : o.getMethods()) {
+ if (aliasToUse == null) {
+ if (mth.isRenamed() && !mth.isAliasFromPreset()) {
+ mth.setAlias(String.format("mo%d%s", id, makeName(mth.getName())));
}
+ aliasToUse = mth.getAlias();
}
+ mth.setAlias(aliasToUse);
+ mth.setAliasFromPreset(aliasFromPreset);
}
id++;
@@ -201,9 +201,8 @@ public class Deobfuscator {
}
private void resolveOverriding(DexNode dex, ClassNode cls, MethodNode mth) {
- Set overrideSet = new HashSet();
+ Set overrideSet = new HashSet<>();
resolveOverridingInternal(dex, cls, mth.getMethodInfo().makeSignature(false), overrideSet, cls);
-
if (overrideSet.size() > 1) {
OverridedMethodsNode overrideNode = null;
for (MethodInfo _mth : overrideSet) {
@@ -212,12 +211,10 @@ public class Deobfuscator {
break;
}
}
-
if (overrideNode == null) {
overrideNode = new OverridedMethodsNode(overrideSet);
ovrd.add(overrideNode);
}
-
for (MethodInfo _mth : overrideSet) {
if (!ovrdMap.containsKey(_mth)) {
ovrdMap.put(_mth, overrideNode);
@@ -228,7 +225,6 @@ public class Deobfuscator {
}
} else {
overrideSet.clear();
- overrideSet = null;
}
}
@@ -442,9 +438,9 @@ public class Deobfuscator {
parentPkg = parentPkg.getParentPackage();
}
- final String pkgName = pkg.getName();
+ String pkgName = pkg.getName();
if (!pkg.hasAlias() && shouldRename(pkgName)) {
- final String pkgAlias = String.format("p%03d%s", pkgIndex++, makeName(pkgName));
+ String pkgAlias = String.format("p%03d%s", pkgIndex++, makeName(pkgName));
pkg.setAlias(pkgAlias);
}
}
@@ -501,7 +497,7 @@ public class Deobfuscator {
}
private String getPackageName(String packageName) {
- final PackageNode pkg = getPackageNode(packageName, false);
+ PackageNode pkg = getPackageNode(packageName, false);
if (pkg != null) {
return pkg.getFullAlias();
}
@@ -509,7 +505,7 @@ public class Deobfuscator {
}
private String getClassName(ClassInfo clsInfo) {
- final DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
+ DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
if (deobfClsInfo != null) {
return deobfClsInfo.makeNameWithoutPkg();
}
@@ -521,7 +517,7 @@ public class Deobfuscator {
}
private String getClassFullName(ClassInfo clsInfo) {
- final DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
+ DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo);
if (deobfClsInfo != null) {
return deobfClsInfo.getFullName();
}
diff --git a/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java b/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
index 1571a3604..b71d2058e 100644
--- a/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
+++ b/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java
@@ -13,7 +13,7 @@ public class NameMapper {
private static final Pattern VALID_JAVA_FULL_IDENTIFIER = Pattern.compile(
"(" + VALID_JAVA_IDENTIFIER + "\\.)*" + VALID_JAVA_IDENTIFIER);
- private static final Set RESERVED_NAMES = new HashSet(
+ private static final Set RESERVED_NAMES = new HashSet<>(
Arrays.asList(new String[]{
"abstract",
"assert",
diff --git a/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java b/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java
index cb0a0dfe6..afb2fbcfb 100644
--- a/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java
+++ b/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java
@@ -1,9 +1,10 @@
package jadx.core.deobf;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Deque;
import java.util.List;
-import java.util.Stack;
public class PackageNode {
@@ -29,11 +30,11 @@ public class PackageNode {
public String getFullName() {
if (cachedPackageFullName == null) {
- Stack pp = getParentPackages();
+ Deque pp = getParentPackages();
StringBuilder result = new StringBuilder();
result.append(pp.pop().getName());
- while (pp.size() > 0) {
+ while (!pp.isEmpty()) {
result.append(SEPARATOR_CHAR);
result.append(pp.pop().getName());
}
@@ -59,12 +60,12 @@ public class PackageNode {
public String getFullAlias() {
if (cachedPackageFullAlias == null) {
- Stack pp = getParentPackages();
+ Deque pp = getParentPackages();
StringBuilder result = new StringBuilder();
- if (pp.size() > 0) {
+ if (!pp.isEmpty()) {
result.append(pp.pop().getAlias());
- while (pp.size() > 0) {
+ while (!pp.isEmpty()) {
result.append(SEPARATOR_CHAR);
result.append(pp.pop().getAlias());
}
@@ -86,7 +87,7 @@ public class PackageNode {
public void addInnerPackage(PackageNode pkg) {
if (innerPackages.isEmpty()) {
- innerPackages = new ArrayList();
+ innerPackages = new ArrayList<>();
}
innerPackages.add(pkg);
pkg.parentPackage = this;
@@ -114,16 +115,15 @@ public class PackageNode {
*
* @return stack with parent packages
*/
- private Stack getParentPackages() {
- Stack pp = new Stack();
+ private Deque getParentPackages() {
+ Deque pp = new ArrayDeque<>();
- PackageNode currentP = this;
- PackageNode parentP = currentP.getParentPackage();
-
- while (currentP != parentP) {
- pp.push(currentP);
- currentP = parentP;
- parentP = currentP.getParentPackage();
+ PackageNode currentPkg = this;
+ PackageNode parentPkg = currentPkg.getParentPackage();
+ while (currentPkg != parentPkg) {
+ pp.push(currentPkg);
+ currentPkg = parentPkg;
+ parentPkg = currentPkg.getParentPackage();
}
return pp;
}
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java
index 1ad75335e..ca024e0ac 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AType.java
@@ -29,25 +29,25 @@ import jadx.core.dex.trycatch.SplitterBlockAttr;
*/
public class AType {
- public static final AType> JUMP = new AType>();
- public static final AType> LOOP = new AType>();
- public static final AType> EDGE_INSN = new AType>();
+ public static final AType> JUMP = new AType<>();
+ public static final AType> LOOP = new AType<>();
+ public static final AType> EDGE_INSN = new AType<>();
- public static final AType EXC_HANDLER = new AType();
- public static final AType CATCH_BLOCK = new AType();
- public static final AType SPLITTER_BLOCK = new AType();
- public static final AType FORCE_RETURN = new AType();
- public static final AType FIELD_INIT = new AType();
- public static final AType FIELD_REPLACE = new AType();
- public static final AType JADX_ERROR = new AType();
- public static final AType METHOD_INLINE = new AType();
- public static final AType ENUM_CLASS = new AType();
- public static final AType ENUM_MAP = new AType();
- public static final AType ANNOTATION_LIST = new AType();
- public static final AType ANNOTATION_MTH_PARAMETERS = new AType();
- public static final AType PHI_LIST = new AType();
- public static final AType SOURCE_FILE = new AType();
- public static final AType DECLARE_VARIABLES = new AType();
- public static final AType LOOP_LABEL = new AType();
- public static final AType IGNORE_EDGE = new AType();
+ public static final AType EXC_HANDLER = new AType<>();
+ public static final AType CATCH_BLOCK = new AType<>();
+ public static final AType SPLITTER_BLOCK = new AType<>();
+ public static final AType FORCE_RETURN = new AType<>();
+ public static final AType FIELD_INIT = new AType<>();
+ public static final AType FIELD_REPLACE = new AType<>();
+ public static final AType JADX_ERROR = new AType<>();
+ public static final AType METHOD_INLINE = new AType<>();
+ public static final AType ENUM_CLASS = new AType<>();
+ public static final AType ENUM_MAP = new AType<>();
+ public static final AType ANNOTATION_LIST = new AType<>();
+ public static final AType ANNOTATION_MTH_PARAMETERS = new AType<>();
+ public static final AType PHI_LIST = new AType<>();
+ public static final AType SOURCE_FILE = new AType<>();
+ public static final AType DECLARE_VARIABLES = new AType<>();
+ public static final AType LOOP_LABEL = new AType<>();
+ public static final AType IGNORE_EDGE = new AType<>();
}
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AttrList.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AttrList.java
index eeabbfea8..30fa1e4f6 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/AttrList.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AttrList.java
@@ -8,7 +8,7 @@ import java.util.List;
public class AttrList implements IAttribute {
private final AType> type;
- private final List list = new LinkedList();
+ private final List list = new LinkedList<>();
public AttrList(AType> type) {
this.type = type;
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java
index 2b3595814..4184c4d7a 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeStorage.java
@@ -24,7 +24,7 @@ public class AttributeStorage {
public AttributeStorage() {
flags = EnumSet.noneOf(AFlag.class);
- attributes = new IdentityHashMap, IAttribute>();
+ attributes = new IdentityHashMap<>();
}
public void add(AFlag flag) {
@@ -38,7 +38,7 @@ public class AttributeStorage {
public void add(AType> type, T obj) {
AttrList list = get(type);
if (list == null) {
- list = new AttrList(type);
+ list = new AttrList<>(type);
add(list);
}
list.getList().add(obj);
@@ -84,7 +84,7 @@ public class AttributeStorage {
}
public void remove(IAttribute attr) {
- AType> type = attr.getType();
+ AType extends IAttribute> type = attr.getType();
IAttribute a = attributes.get(type);
if (a == attr) {
attributes.remove(type);
@@ -101,7 +101,7 @@ public class AttributeStorage {
if (size == 0) {
return Collections.emptyList();
}
- List list = new ArrayList(size);
+ List list = new ArrayList<>(size);
for (AFlag a : flags) {
list.add(a.toString());
}
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/IAttribute.java b/jadx-core/src/main/java/jadx/core/dex/attributes/IAttribute.java
index 18bb476b6..cac361c26 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/IAttribute.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/IAttribute.java
@@ -1,7 +1,5 @@
package jadx.core.dex.attributes;
public interface IAttribute {
-
- AType> getType();
-
+ AType extends IAttribute> getType();
}
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/AnnotationsList.java b/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/AnnotationsList.java
index e2d075006..85c8e8f6b 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/AnnotationsList.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/AnnotationsList.java
@@ -17,7 +17,7 @@ public class AnnotationsList implements IAttribute {
private final Map map;
public AnnotationsList(List anList) {
- map = new HashMap(anList.size());
+ map = new HashMap<>(anList.size());
for (Annotation a : anList) {
map.put(a.getAnnotationClass(), a);
}
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/MethodParameters.java b/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/MethodParameters.java
index 28778f9b5..acfb66c5f 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/MethodParameters.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/annotations/MethodParameters.java
@@ -12,7 +12,7 @@ public class MethodParameters implements IAttribute {
private final List paramList;
public MethodParameters(int paramCount) {
- paramList = new ArrayList(paramCount);
+ paramList = new ArrayList<>(paramCount);
}
public List getParamList() {
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/DeclareVariablesAttr.java b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/DeclareVariablesAttr.java
index a06a704a7..9780770c3 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/DeclareVariablesAttr.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/DeclareVariablesAttr.java
@@ -13,7 +13,7 @@ import java.util.List;
*/
public class DeclareVariablesAttr implements IAttribute {
- private final List vars = new LinkedList();
+ private final List vars = new LinkedList<>();
public Iterable getVars() {
return vars;
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumClassAttr.java b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumClassAttr.java
index b5ab0157f..a0530a4ef 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumClassAttr.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumClassAttr.java
@@ -54,7 +54,7 @@ public class EnumClassAttr implements IAttribute {
private MethodNode staticMethod;
public EnumClassAttr(int fieldsCount) {
- this.fields = new ArrayList(fieldsCount);
+ this.fields = new ArrayList<>(fieldsCount);
}
public List getFields() {
diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java
index 20efada1b..9221da8aa 100644
--- a/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java
+++ b/jadx-core/src/main/java/jadx/core/dex/attributes/nodes/EnumMapAttr.java
@@ -10,7 +10,7 @@ import java.util.Map;
public class EnumMapAttr implements IAttribute {
public static class KeyValueMap {
- private final Map