提交 c801269d 编写于 作者: J Jan Peter Stotz

feat: Support decompilation of Jar files with Java 8+ code and embedded Jar files

上级 7227f1ac
......@@ -6,7 +6,7 @@ dependencies {
api(project(":jadx-plugins:jadx-plugins-api"))
implementation(project(":jadx-plugins:jadx-dex-input"))
implementation(files('lib/dx-1.16.jar'))
implementation 'com.android.tools:r8:2.1.75'
implementation 'org.ow2.asm:asm:8.0.1'
}
package jadx.plugins.input.javaconvert;
import java.nio.file.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.Diagnostic;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.OutputMode;
public class D8Converter {
private static final Logger LOG = LoggerFactory.getLogger(D8Converter.class);
public static void run(Path pathToBeConverted, Path outputDirectory) {
LOG.info("Converting {} to dex - output dir {}", pathToBeConverted, outputDirectory);
D8Command.Builder builder = D8Command.builder(new LogHelper()).addProgramFiles(pathToBeConverted)
.setMinApiLevel(28)
.setMode(CompilationMode.DEBUG)
.setDisableDesugaring(true)
.setOutput(outputDirectory, OutputMode.DexIndexed);
try {
D8Command command = builder.build();
D8.run(command);
} catch (Exception e) {
throw new RuntimeException("d8 conversion failed: " + e.getMessage(), e);
}
}
private static class LogHelper implements DiagnosticsHandler {
@Override
public void error(Diagnostic diagnostic) {
LOG.error(diagnosticToString(diagnostic));
}
@Override
public void warning(Diagnostic diagnostic) {
LOG.warn(diagnosticToString(diagnostic));
}
@Override
public void info(Diagnostic diagnostic) {
LOG.info(diagnosticToString(diagnostic));
}
private static String diagnosticToString(Diagnostic diagnostic) {
return "D8:" + diagnostic.getDiagnosticMessage() + " origin=" + diagnostic.getOrigin() + " position="
+ diagnostic.getPosition();
}
}
}
package jadx.plugins.input.javaconvert;
import java.io.ByteArrayOutputStream;
import java.nio.file.Path;
import com.android.dx.command.dexer.DxContext;
import com.android.dx.command.dexer.Main;
public class DxConverter {
private static final String CHARSET_NAME = "UTF-8";
private static class DxArgs extends com.android.dx.command.dexer.Main.Arguments {
public DxArgs(DxContext context, String dexDir, String[] input) {
super(context);
outName = dexDir;
fileNames = input;
jarOutput = false;
multiDex = true;
optimize = true;
localInfo = true;
coreLibrary = true;
debug = true;
warnings = true;
minSdkVersion = 28;
}
}
public static void run(Path path, Path tempDirectory) {
int result;
String dxErrors;
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream errOut = new ByteArrayOutputStream()) {
DxContext context = new DxContext(out, errOut);
DxArgs args = new DxArgs(
context,
tempDirectory.toAbsolutePath().toString(),
new String[] { path.toAbsolutePath().toString() });
result = new Main(context).runDx(args);
dxErrors = errOut.toString(CHARSET_NAME);
} catch (Exception e) {
throw new RuntimeException("dx exception: " + e.getMessage(), e);
}
if (result != 0) {
throw new RuntimeException("Java to dex conversion error, code: " + result + "\n errors: " + dxErrors);
}
}
}
......@@ -99,13 +99,38 @@ public class JavaConvertLoader {
}));
}
/**
* Process a jar file by converting the contained class files and extract the embedded JAR files
*
* @param result
* @param path
* @throws Exception
*/
private static void convertJar(ConvertResult result, Path path) throws Exception {
// Convert the contained class files
convertSimpleJar(result, path);
// Process the embedded jar files
ZipSecurity.readZipEntries(path.toFile(), (entry, in) -> {
try {
if (entry.getName().endsWith(".jar")) {
Path tempJar = saveInputStreamToFile(in, ".jar");
result.addTempPath(tempJar);
convertSimpleJar(result, tempJar);
}
} catch (Exception e) {
LOG.error("Failed to process jar entry: {} in {}", entry, path, e);
}
});
}
private static void convertSimpleJar(ConvertResult result, Path toBeConvertedPath) throws Exception {
Path tempDirectory = Files.createTempDirectory("jadx-");
result.addTempPath(tempDirectory);
DxConverter.run(path, tempDirectory);
D8Converter.run(toBeConvertedPath, tempDirectory);
LOG.debug("Converted to dex: {}", path.toAbsolutePath());
LOG.debug("Converted to dex: {}", toBeConvertedPath.toAbsolutePath());
result.addConvertedFiles(collectFilesInDir(tempDirectory));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册