diff --git a/jadx-core/src/main/java/jadx/api/ResourceFile.java b/jadx-core/src/main/java/jadx/api/ResourceFile.java index 48da90881..03870f42b 100644 --- a/jadx-core/src/main/java/jadx/api/ResourceFile.java +++ b/jadx-core/src/main/java/jadx/api/ResourceFile.java @@ -1,9 +1,9 @@ package jadx.api; -import jadx.core.xmlgen.ResContainer; - import java.io.File; +import jadx.core.xmlgen.ResContainer; + public class ResourceFile { public static final class ZipRef { @@ -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 4f7e39f97..b173098ea 100644 --- a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java +++ b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java @@ -1,16 +1,12 @@ package jadx.api; -import jadx.api.ResourceFile.ZipRef; -import jadx.core.codegen.CodeWriter; -import jadx.core.utils.Utils; -import jadx.core.utils.exceptions.JadxException; -import jadx.core.utils.files.InputFile; -import jadx.core.xmlgen.ResContainer; -import jadx.core.xmlgen.ResTableParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; 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; @@ -19,8 +15,13 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import jadx.api.ResourceFile.ZipRef; +import jadx.core.codegen.CodeWriter; +import jadx.core.utils.Utils; +import jadx.core.utils.exceptions.JadxException; +import jadx.core.utils.files.InputFile; +import jadx.core.xmlgen.ResContainer; +import jadx.core.xmlgen.ResTableParser; import static jadx.core.utils.files.FileUtils.READ_BUFFER_SIZE; import static jadx.core.utils.files.FileUtils.close; @@ -51,30 +52,35 @@ 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; 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 (entry == null) { + throw new IOException("Zip entry not found: " + zipRef); + } + inputStream = new BufferedInputStream(zipFile.getInputStream(entry)); + size = entry.getSize(); } - 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); } @@ -133,6 +139,7 @@ public final class ResourcesLoader { } } catch (IOException e) { LOG.debug("Not a zip file: {}", file.getAbsolutePath()); + addResourceFile(list, file); } finally { if (zip != null) { try { @@ -144,6 +151,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/dex/visitors/RenameVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java index c600c4139..e0d318d06 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java @@ -10,6 +10,7 @@ import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.ClassNode; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.nodes.RootNode; @@ -18,6 +19,7 @@ import jadx.core.utils.files.InputFile; import java.io.File; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.apache.commons.io.FilenameUtils; @@ -33,13 +35,17 @@ public class RenameVisitor extends AbstractVisitor { public void init(RootNode root) { IJadxArgs args = root.getArgs(); - InputFile firstInputFile = root.getDexNodes().get(0).getDexFile().getInputFile(); + List dexNodes = root.getDexNodes(); + if (dexNodes.size() == 0) { + return; + } + InputFile firstInputFile = dexNodes.get(0).getDexFile().getInputFile(); final String firstInputFileName = firstInputFile.getFile().getAbsolutePath(); final String inputPath = FilenameUtils.getFullPathNoEndSeparator(firstInputFileName); final String inputName = FilenameUtils.getBaseName(firstInputFileName); File deobfMapFile = new File(inputPath, inputName + ".jobf"); - deobfuscator = new Deobfuscator(args, root.getDexNodes(), deobfMapFile); + deobfuscator = new Deobfuscator(args, dexNodes, deobfMapFile); boolean deobfuscationOn = args.isDeobfuscationOn(); if (deobfuscationOn) { deobfuscator.execute(); diff --git a/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java b/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java index ee4441534..48aa3d1f6 100644 --- a/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java @@ -48,7 +48,11 @@ public class AndroidResourcesUtils { } private static ClassNode makeClass(RootNode root, String clsName) { - DexNode firstDex = root.getDexNodes().get(0); + List dexNodes = root.getDexNodes(); + if (dexNodes.size() == 0) { + return null; + } + DexNode firstDex = dexNodes.get(0); ClassInfo r = ClassInfo.fromName(firstDex, clsName); return new ClassNode(firstDex, r); } 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 b0b29df8e..c97ed5575 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 @@ -68,7 +68,7 @@ public class InputFile { loadFromZip(".jar"); return; } - throw new DecodeException("Unsupported input file format: " + file); + //throw new DecodeException("Unsupported input file format: " + file); } private void addDexFile(Dex dexBuf) throws IOException { diff --git a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java index ee5e3b2a3..b796a59e7 100644 --- a/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java +++ b/jadx-gui/src/main/java/jadx/gui/treemodel/JRoot.java @@ -1,18 +1,19 @@ package jadx.gui.treemodel; -import jadx.api.ResourceFile; -import jadx.gui.JadxWrapper; -import jadx.gui.treemodel.JResource.JResType; -import jadx.gui.utils.Utils; - -import javax.swing.Icon; -import javax.swing.ImageIcon; import java.io.File; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.regex.Pattern; +import javax.swing.Icon; +import javax.swing.ImageIcon; + +import jadx.api.ResourceFile; +import jadx.gui.JadxWrapper; +import jadx.gui.treemodel.JResource.JResType; +import jadx.gui.utils.Utils; + public class JRoot extends JNode { private static final long serialVersionUID = 8888495789773527342L; @@ -45,7 +46,13 @@ public class JRoot extends JNode { JResource root = new JResource(null, "Resources", JResType.ROOT); String splitPathStr = Pattern.quote(File.separator); for (ResourceFile rf : resources) { - String[] parts = new File(rf.getName()).getPath().split(splitPathStr); + String rfName; + if (rf.getZipRef() != null) { + rfName = rf.getName(); + } else { + rfName = new File(rf.getName()).getName(); + } + String[] parts = new File(rfName).getPath().split(splitPathStr); JResource curRf = root; int count = parts.length; for (int i = 0; i < count; i++) { diff --git a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java index e4a6f8912..37795808c 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java @@ -171,7 +171,7 @@ public class MainWindow extends JFrame { public void openFile() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setAcceptAllFileFilterUsed(true); - String[] exts = {"apk", "dex", "jar", "class", "zip", "aar"}; + String[] exts = {"apk", "dex", "jar", "class", "zip", "aar", "arsc"}; String description = "supported files: " + Arrays.toString(exts).replace('[', '(').replace(']', ')'); fileChooser.setFileFilter(new FileNameExtensionFilter(description, exts)); fileChooser.setToolTipText(NLS.str("file.open"));