feat: add options for java-convert plugin
This commit is contained in:
+2
-2
@@ -16,14 +16,14 @@ import com.android.tools.r8.OutputMode;
|
||||
public class D8Converter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(D8Converter.class);
|
||||
|
||||
public static void run(Path path, Path tempDirectory) throws CompilationFailedException {
|
||||
public static void run(Path path, Path tempDirectory, JavaConvertOptions options) throws CompilationFailedException {
|
||||
D8Command d8Command = D8Command.builder(new LogHandler())
|
||||
.addProgramFiles(path)
|
||||
.setOutput(tempDirectory, OutputMode.DexIndexed)
|
||||
.setMode(CompilationMode.DEBUG)
|
||||
.setMinApiLevel(30)
|
||||
.setIntermediate(true)
|
||||
.setDisableDesugaring(true)
|
||||
.setDisableDesugaring(!options.isD8Desugar())
|
||||
.build();
|
||||
D8.run(d8Command);
|
||||
}
|
||||
|
||||
+48
-17
@@ -23,7 +23,13 @@ import jadx.api.plugins.utils.ZipSecurity;
|
||||
public class JavaConvertLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JavaConvertLoader.class);
|
||||
|
||||
public static ConvertResult process(List<Path> input) {
|
||||
private final JavaConvertOptions options;
|
||||
|
||||
public JavaConvertLoader(JavaConvertOptions options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public ConvertResult process(List<Path> input) {
|
||||
ConvertResult result = new ConvertResult();
|
||||
processJars(input, result);
|
||||
processAars(input, result);
|
||||
@@ -31,7 +37,7 @@ public class JavaConvertLoader {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void processJars(List<Path> input, ConvertResult result) {
|
||||
private void processJars(List<Path> input, ConvertResult result) {
|
||||
PathMatcher jarMatcher = FileSystems.getDefault().getPathMatcher("glob:**.jar");
|
||||
input.stream()
|
||||
.filter(jarMatcher::matches)
|
||||
@@ -44,7 +50,7 @@ public class JavaConvertLoader {
|
||||
});
|
||||
}
|
||||
|
||||
private static void processClassFiles(List<Path> input, ConvertResult result) {
|
||||
private void processClassFiles(List<Path> input, ConvertResult result) {
|
||||
PathMatcher jarMatcher = FileSystems.getDefault().getPathMatcher("glob:**.class");
|
||||
List<Path> clsFiles = input.stream()
|
||||
.filter(jarMatcher::matches)
|
||||
@@ -72,7 +78,7 @@ public class JavaConvertLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private static void processAars(List<Path> input, ConvertResult result) {
|
||||
private void processAars(List<Path> input, ConvertResult result) {
|
||||
PathMatcher aarMatcher = FileSystems.getDefault().getPathMatcher("glob:**.aar");
|
||||
input.stream()
|
||||
.filter(aarMatcher::matches)
|
||||
@@ -91,14 +97,14 @@ public class JavaConvertLoader {
|
||||
}));
|
||||
}
|
||||
|
||||
private static void convertJar(ConvertResult result, Path path) throws Exception {
|
||||
private void convertJar(ConvertResult result, Path path) throws Exception {
|
||||
if (repackAndConvertJar(result, path)) {
|
||||
return;
|
||||
}
|
||||
convertSimpleJar(result, path);
|
||||
}
|
||||
|
||||
private static boolean repackAndConvertJar(ConvertResult result, Path path) throws Exception {
|
||||
private boolean repackAndConvertJar(ConvertResult result, Path path) throws Exception {
|
||||
// check if jar need a full repackage
|
||||
Boolean repackNeeded = ZipSecurity.visitZipEntries(path.toFile(), (zipFile, zipEntry) -> {
|
||||
String entryName = zipEntry.getName();
|
||||
@@ -154,25 +160,50 @@ public class JavaConvertLoader {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void convertSimpleJar(ConvertResult result, Path path) throws Exception {
|
||||
private void convertSimpleJar(ConvertResult result, Path path) throws Exception {
|
||||
Path tempDirectory = Files.createTempDirectory("jadx-");
|
||||
result.addTempPath(tempDirectory);
|
||||
LOG.debug("Converting to dex ...");
|
||||
try {
|
||||
DxConverter.run(path, tempDirectory);
|
||||
} catch (Throwable e) {
|
||||
LOG.warn("DX convert failed, trying D8, path: {}", path);
|
||||
try {
|
||||
D8Converter.run(path, tempDirectory);
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("D8 convert failed: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
convert(path, tempDirectory);
|
||||
List<Path> dexFiles = collectFilesInDir(tempDirectory);
|
||||
LOG.debug("Converted {} to {} dex", path.toAbsolutePath(), dexFiles.size());
|
||||
result.addConvertedFiles(dexFiles);
|
||||
}
|
||||
|
||||
private void convert(Path path, Path tempDirectory) {
|
||||
JavaConvertOptions.Mode mode = options.getMode();
|
||||
switch (mode) {
|
||||
case DX:
|
||||
try {
|
||||
DxConverter.run(path, tempDirectory);
|
||||
} catch (Throwable e) {
|
||||
LOG.error("DX convert failed, path: {}", path, e);
|
||||
}
|
||||
break;
|
||||
|
||||
case D8:
|
||||
try {
|
||||
D8Converter.run(path, tempDirectory, options);
|
||||
} catch (Throwable e) {
|
||||
LOG.error("D8 convert failed, path: {}", path, e);
|
||||
}
|
||||
break;
|
||||
|
||||
case BOTH:
|
||||
try {
|
||||
DxConverter.run(path, tempDirectory);
|
||||
} catch (Throwable e) {
|
||||
LOG.warn("DX convert failed, trying D8, path: {}", path);
|
||||
try {
|
||||
D8Converter.run(path, tempDirectory, options);
|
||||
} catch (Throwable ex) {
|
||||
LOG.error("D8 convert failed: {}", ex.getMessage());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Path> collectFilesInDir(Path tempDirectory) throws IOException {
|
||||
PathMatcher dexMatcher = FileSystems.getDefault().getPathMatcher("glob:**.dex");
|
||||
try (Stream<Path> pathStream = Files.walk(tempDirectory, 1)) {
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package jadx.plugins.input.javaconvert;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import jadx.api.plugins.options.OptionDescription;
|
||||
import jadx.api.plugins.options.impl.BaseOptionsParser;
|
||||
import jadx.api.plugins.options.impl.JadxOptionDescription;
|
||||
|
||||
public class JavaConvertOptions extends BaseOptionsParser {
|
||||
|
||||
private static final String MODE_OPT = JavaConvertPlugin.PLUGIN_ID + ".mode";
|
||||
private static final String D8_DESUGAR_OPT = JavaConvertPlugin.PLUGIN_ID + ".d8-desugar";
|
||||
|
||||
public enum Mode {
|
||||
DX, D8, BOTH
|
||||
}
|
||||
|
||||
private Mode mode = Mode.BOTH;
|
||||
private boolean d8Desugar = false;
|
||||
|
||||
public void apply(Map<String, String> options) {
|
||||
mode = getOption(options, MODE_OPT, name -> Mode.valueOf(name.toUpperCase(Locale.ROOT)), Mode.BOTH);
|
||||
d8Desugar = getBooleanOption(options, D8_DESUGAR_OPT, false);
|
||||
}
|
||||
|
||||
public List<OptionDescription> buildOptionsDescriptions() {
|
||||
return Arrays.asList(
|
||||
new JadxOptionDescription(
|
||||
MODE_OPT,
|
||||
"Convert mode",
|
||||
"both",
|
||||
Arrays.asList("dx", "d8", "both")),
|
||||
new JadxOptionDescription(
|
||||
D8_DESUGAR_OPT,
|
||||
"Use desugar in d8",
|
||||
"no",
|
||||
Arrays.asList("yes", "no")));
|
||||
}
|
||||
|
||||
public Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public boolean isD8Desugar() {
|
||||
return d8Desugar;
|
||||
}
|
||||
}
|
||||
+20
-3
@@ -2,21 +2,28 @@ package jadx.plugins.input.javaconvert;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jadx.api.plugins.JadxPluginInfo;
|
||||
import jadx.api.plugins.input.JadxInputPlugin;
|
||||
import jadx.api.plugins.input.data.ILoadResult;
|
||||
import jadx.api.plugins.input.data.impl.EmptyLoadResult;
|
||||
import jadx.api.plugins.options.JadxPluginOptions;
|
||||
import jadx.api.plugins.options.OptionDescription;
|
||||
import jadx.plugins.input.dex.DexInputPlugin;
|
||||
|
||||
public class JavaConvertPlugin implements JadxInputPlugin {
|
||||
public class JavaConvertPlugin implements JadxInputPlugin, JadxPluginOptions {
|
||||
|
||||
public static final String PLUGIN_ID = "java-convert";
|
||||
|
||||
private final DexInputPlugin dexInput = new DexInputPlugin();
|
||||
private final JavaConvertOptions options = new JavaConvertOptions();
|
||||
private final JavaConvertLoader loader = new JavaConvertLoader(options);
|
||||
|
||||
@Override
|
||||
public JadxPluginInfo getPluginInfo() {
|
||||
return new JadxPluginInfo(
|
||||
"java-convert",
|
||||
PLUGIN_ID,
|
||||
"JavaConvert",
|
||||
"Convert .jar and .class files to dex",
|
||||
"java-input");
|
||||
@@ -24,11 +31,21 @@ public class JavaConvertPlugin implements JadxInputPlugin {
|
||||
|
||||
@Override
|
||||
public ILoadResult loadFiles(List<Path> input) {
|
||||
ConvertResult result = JavaConvertLoader.process(input);
|
||||
ConvertResult result = loader.process(input);
|
||||
if (result.isEmpty()) {
|
||||
result.close();
|
||||
return EmptyLoadResult.INSTANCE;
|
||||
}
|
||||
return dexInput.loadFiles(result.getConverted(), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOptions(Map<String, String> options) {
|
||||
this.options.apply(options);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OptionDescription> getOptionsDescriptions() {
|
||||
return this.options.buildOptionsDescriptions();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user