From a83ca1f85b240a79c045b2aa27785ef114c17ed0 Mon Sep 17 00:00:00 2001 From: Skylot Date: Wed, 10 Jun 2020 20:43:39 +0300 Subject: [PATCH] fix: don't use FileChannel on ZipFs to avoid creation of temp files (#950) --- .../jadx/plugins/input/dex/DexFileLoader.java | 40 +++++++++---------- .../jadx/plugins/input/dex/DexReader.java | 24 ++--------- .../plugins/input/dex/sections/DexConsts.java | 2 + 3 files changed, 23 insertions(+), 43 deletions(-) diff --git a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java index 925d250b9..72050f370 100644 --- a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java +++ b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexFileLoader.java @@ -1,8 +1,7 @@ package jadx.plugins.input.dex; import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; +import java.io.InputStream; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; @@ -12,7 +11,6 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardOpenOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -35,11 +33,15 @@ public class DexFileLoader { } private static List loadDexFromPath(Path path, int depth) { - try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) { - if (isDex(fileChannel)) { - return Collections.singletonList(new DexReader(path, fileChannel)); + try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) { + byte[] magic = new byte[DexConsts.MAX_MAGIC_SIZE]; + if (inputStream.read(magic) != magic.length) { + return Collections.emptyList(); } - if (depth == 0 && isZip(fileChannel)) { + if (isStartWithBytes(magic, DexConsts.DEX_FILE_MAGIC)) { + return Collections.singletonList(new DexReader(path)); + } + if (depth == 0 && isStartWithBytes(magic, DexConsts.ZIP_FILE_MAGIC)) { return collectDexFromZip(path, depth); } } catch (Exception e) { @@ -64,22 +66,16 @@ public class DexFileLoader { return result; } - private static boolean isDex(FileChannel fileChannel) { - return isStartWithBytes(fileChannel, DexConsts.DEX_FILE_MAGIC); - } - - private static boolean isZip(FileChannel fileChannel) { - return isStartWithBytes(fileChannel, DexConsts.ZIP_FILE_MAGIC); - } - - private static boolean isStartWithBytes(FileChannel fileChannel, byte[] startBytes) { - try { - fileChannel.position(0); - ByteBuffer buf = ByteBuffer.allocate(startBytes.length); - fileChannel.read(buf); - return Arrays.equals(startBytes, buf.array()); - } catch (Exception e) { + private static boolean isStartWithBytes(byte[] fileMagic, byte[] expectedBytes) { + int len = expectedBytes.length; + if (fileMagic.length < len) { return false; } + for (int i = 0; i < len; i++) { + if (fileMagic[i] != expectedBytes[i]) { + return false; + } + } + return true; } } diff --git a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java index 4ae196da0..14105047a 100644 --- a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java +++ b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/DexReader.java @@ -3,8 +3,8 @@ package jadx.plugins.input.dex; import java.io.Closeable; import java.io.IOException; import java.nio.ByteBuffer; -import java.nio.channels.FileChannel; import java.nio.file.FileSystem; +import java.nio.file.Files; import java.nio.file.Path; import java.util.function.Consumer; @@ -17,32 +17,15 @@ import jadx.plugins.input.dex.sections.annotations.AnnotationsParser; public class DexReader implements Closeable { private final Path path; - private final FileChannel fileChannel; private final ByteBuffer buf; private final DexHeader header; - public DexReader(Path path, FileChannel fileChannel) throws IOException { + public DexReader(Path path) throws IOException { this.path = path; - this.fileChannel = fileChannel; - this.buf = loadIntoByteBuffer(fileChannel); + this.buf = ByteBuffer.wrap(Files.readAllBytes(path)); this.header = new DexHeader(new SectionReader(this, 0)); } - private static ByteBuffer loadIntoByteBuffer(FileChannel fileChannel) throws IOException { - long size = fileChannel.size(); - if (size > Integer.MAX_VALUE) { - throw new IOException("File too big"); - } - int readSize = (int) size; - ByteBuffer buf = ByteBuffer.allocate(readSize); - fileChannel.position(0); - int read = fileChannel.read(buf); - if (read != readSize) { - throw new IOException("Failed to read whole file into buffer. Read: " + read + ", expected: " + readSize); - } - return buf; - } - public String getDexVersion() { return this.header.getVersion(); } @@ -86,7 +69,6 @@ public class DexReader implements Closeable { @Override public void close() throws IOException { - this.fileChannel.close(); } @Override diff --git a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexConsts.java b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexConsts.java index 7323574fb..f249a4662 100644 --- a/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexConsts.java +++ b/jadx-plugins/jadx-dex-input/src/main/java/jadx/plugins/input/dex/sections/DexConsts.java @@ -6,6 +6,8 @@ public class DexConsts { public static final byte[] ZIP_FILE_MAGIC = { 0x50, 0x4B, 0x03, 0x04 }; + public static final int MAX_MAGIC_SIZE = 4; + public static final int ENDIAN_CONSTANT = 0x12345678; public static final int NO_INDEX = -1;