diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle index 1f9b0ebb9..a2d8275f7 100644 --- a/jadx-core/build.gradle +++ b/jadx-core/build.gradle @@ -4,20 +4,16 @@ dependencies { runtime files(jadxClasspath) compile files('lib/dx-1.16.jar') - compile 'commons-io:commons-io:2.6' + compile 'org.ow2.asm:asm:7.1' compile 'org.jetbrains:annotations:17.0.0' compile 'uk.com.robust-it:cloning:1.9.12' + + compile 'org.smali:baksmali:2.2.7' compile('org.smali:smali:2.2.7') { exclude group: 'com.google.guava' } compile 'com.google.guava:guava:27.1-jre' - compile 'org.smali:baksmali:2.2.7' - 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' } 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 230822fe0..49205c061 100644 --- a/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java +++ b/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java @@ -160,7 +160,7 @@ public class ClsSet { } void save(Path path) throws IOException { - Files.createDirectories(path.getParent()); + FileUtils.makeDirsForFile(path); String outputName = path.getFileName().toString(); if (outputName.endsWith(CLST_EXTENSION)) { try (BufferedOutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) { diff --git a/jadx-core/src/main/java/jadx/core/utils/android/Res9patchStreamDecoder.java b/jadx-core/src/main/java/jadx/core/utils/android/Res9patchStreamDecoder.java index 7d4bb22ef..669df893a 100644 --- a/jadx-core/src/main/java/jadx/core/utils/android/Res9patchStreamDecoder.java +++ b/jadx-core/src/main/java/jadx/core/utils/android/Res9patchStreamDecoder.java @@ -25,7 +25,7 @@ import java.io.OutputStream; import javax.imageio.ImageIO; -import org.apache.commons.io.IOUtils; +import com.google.common.io.ByteStreams; import jadx.core.utils.exceptions.JadxException; @@ -36,7 +36,7 @@ public class Res9patchStreamDecoder { public void decode(InputStream in, OutputStream out) throws JadxException { try { - byte[] data = IOUtils.toByteArray(in); + byte[] data = ByteStreams.toByteArray(in); BufferedImage im = ImageIO.read(new ByteArrayInputStream(data)); int w = im.getWidth(); diff --git a/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java b/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java index ad825c8df..31e65e8a6 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java @@ -45,6 +45,12 @@ public class FileUtils { } } + public static void makeDirsForFile(Path path) { + if (path != null) { + makeDirs(path.getParent().toFile()); + } + } + public static void makeDirsForFile(File file) { if (file != null) { makeDirs(file.getParentFile()); @@ -63,13 +69,35 @@ public class FileUtils { } } + private static final Path TEMP_ROOT_DIR = createTempRootDir(); + + private static Path createTempRootDir() { + try { + Path dir = Files.createTempDirectory("jadx-instance-"); + dir.toFile().deleteOnExit(); + return dir; + } catch (Exception e) { + throw new JadxRuntimeException("Failed to create temp root directory", e); + } + } + + public static Path createTempDir(String prefix) { + try { + Path dir = Files.createTempDirectory(TEMP_ROOT_DIR, prefix); + dir.toFile().deleteOnExit(); + return dir; + } catch (Exception e) { + throw new JadxRuntimeException("Failed to create temp directory with suffix: " + prefix, e); + } + } + public static Path createTempFile(String suffix) { try { - Path path = Files.createTempFile("jadx-tmp-", suffix); + Path path = Files.createTempFile(TEMP_ROOT_DIR, "jadx-tmp-", suffix); path.toFile().deleteOnExit(); return path; - } catch (IOException e) { - throw new JadxRuntimeException("Failed to create temp file with suffix: " + suffix); + } catch (Exception e) { + throw new JadxRuntimeException("Failed to create temp file with suffix: " + suffix, e); } } diff --git a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java index 89f60e83f..c890a2305 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java @@ -3,7 +3,6 @@ package jadx.core.utils.files; import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -14,7 +13,6 @@ import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.Nullable; import org.jf.smali.Smali; import org.jf.smali.SmaliOptions; @@ -150,9 +148,7 @@ public class InputFile { } } else if (entryName.equals("instant-run.zip") && ext.equals(".dex")) { Path jarFile = FileUtils.createTempFile("instant-run.zip"); - try (OutputStream fos = Files.newOutputStream(jarFile)) { - IOUtils.copy(inputStream, fos); - } + Files.copy(inputStream, jarFile, StandardCopyOption.REPLACE_EXISTING); InputFile tempFile = new InputFile(jarFile.toFile()); tempFile.loadFromZip(ext); List dexFiles = tempFile.getDexFiles(); diff --git a/jadx-core/src/main/java/jadx/core/utils/files/JavaToDex.java b/jadx-core/src/main/java/jadx/core/utils/files/JavaToDex.java index 4f59c4983..71a81a2cb 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/JavaToDex.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/JavaToDex.java @@ -41,7 +41,7 @@ public class JavaToDex { try (ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream errOut = new ByteArrayOutputStream()) { DxContext context = new DxContext(out, errOut); - Path dir = Files.createTempDirectory("jadx"); + Path dir = FileUtils.createTempDir(jar.getFileName().toString()); DxArgs args = new DxArgs( context, dir.toAbsolutePath().toString(), diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java b/jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java index dd3c129c0..ec2389b76 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ResourcesSaver.java @@ -1,10 +1,9 @@ package jadx.core.xmlgen; import java.io.File; -import java.io.FileOutputStream; import java.nio.file.Files; +import java.nio.file.StandardCopyOption; -import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -91,8 +90,8 @@ public class ResourcesSaver implements Runnable { private void saveResourceFile(ResourceFile resFile, File outFile) throws JadxException { ResourcesLoader.decodeStream(resFile, (size, is) -> { - try (FileOutputStream fileStream = new FileOutputStream(outFile)) { - IOUtils.copy(is, fileStream); + try { + Files.copy(is, outFile.toPath(), StandardCopyOption.REPLACE_EXISTING); } catch (Exception e) { throw new JadxRuntimeException("Resource file save error", e); } diff --git a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java index 95348db69..77a4c69ce 100644 --- a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java +++ b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Collections; import java.util.List; import java.util.Map; @@ -34,6 +36,7 @@ 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.files.FileUtils; import jadx.core.xmlgen.ResourceStorage; import jadx.core.xmlgen.entry.ResourceEntry; import jadx.tests.api.compiler.DynamicCompiler; @@ -361,30 +364,19 @@ public abstract class IntegrationTest extends TestUtils { } protected File createTempFile(String suffix) { - File temp = null; try { - temp = File.createTempFile("jadx-tmp-", System.nanoTime() + suffix); + Path temp; if (deleteTmpFiles) { - temp.deleteOnExit(); + temp = FileUtils.createTempFile(suffix); } else { - System.out.println("Temporary file path: " + temp.getAbsolutePath()); + // don't delete on exit + temp = Files.createTempFile("jadx", suffix); + System.out.println("Temporary file saved: " + temp.toAbsolutePath()); } - } catch (IOException e) { - fail(e.getMessage()); + return temp.toFile(); + } catch (Exception e) { + throw new AssertionError(e.getMessage()); } - return temp; - } - - private static File createTempDir(String prefix) throws IOException { - File baseDir = new File(System.getProperty("java.io.tmpdir")); - String baseName = prefix + '-' + System.nanoTime(); - for (int counter = 1; counter < 1000; counter++) { - File tempDir = new File(baseDir, baseName + counter); - if (tempDir.mkdir()) { - return tempDir; - } - } - throw new IOException("Failed to create temp directory"); } private List compileClass(Class cls) throws IOException { @@ -404,9 +396,8 @@ public abstract class IntegrationTest extends TestUtils { assertThat("Test source file not found: " + javaFileName, file.exists(), is(true)); List compileFileList = Collections.singletonList(file); - File outTmp = createTempDir("jadx-tmp-classes"); - outTmp.deleteOnExit(); - List files = StaticCompiler.compile(compileFileList, outTmp, withDebugInfo, useEclipseCompiler); + Path outTmp = FileUtils.createTempDir("jadx-tmp-classes"); + List files = StaticCompiler.compile(compileFileList, outTmp.toFile(), withDebugInfo, useEclipseCompiler); files.forEach(File::deleteOnExit); // remove classes which are parents for test class String clsName = clsFullName.substring(clsFullName.lastIndexOf('.') + 1);