From 9976894091116d5a8d10a86759399fbaa3e028de Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 29 Aug 2015 15:50:42 +0300 Subject: [PATCH] core: skip decoding for plain text xml (fix #82) --- .../main/java/jadx/api/ResourcesLoader.java | 6 +++-- .../jadx/core/xmlgen/BinaryXMLParser.java | 23 +++++++++++++------ .../java/jadx/core/xmlgen/ParserStream.java | 11 +++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java index 681eea3a8..8a9dae101 100644 --- a/jadx-core/src/main/java/jadx/api/ResourcesLoader.java +++ b/jadx-core/src/main/java/jadx/api/ResourcesLoader.java @@ -53,6 +53,7 @@ public final class ResourcesLoader { } ZipFile zipFile = null; InputStream inputStream = null; + Object result = null; try { zipFile = new ZipFile(zipRef.getZipFile()); ZipEntry entry = zipFile.getEntry(zipRef.getEntryName()); @@ -60,7 +61,7 @@ public final class ResourcesLoader { throw new IOException("Zip entry not found: " + zipRef); } inputStream = new BufferedInputStream(zipFile.getInputStream(entry)); - return decoder.decode(entry.getSize(), inputStream); + result = decoder.decode(entry.getSize(), inputStream); } catch (Exception e) { throw new JadxException("Error decode: " + zipRef.getEntryName(), e); } finally { @@ -75,6 +76,7 @@ public final class ResourcesLoader { LOG.debug("Error close zip file: {}", zipRef, e); } } + return result; } static CodeWriter loadContent(final JadxDecompiler jadxRef, final ResourceFile rf) { @@ -148,7 +150,7 @@ public final class ResourcesLoader { // LOG.debug("Add resource entry: {}, size: {}", name, entry.getSize()); } - private static CodeWriter loadToCodeWriter(InputStream is) throws IOException { + public static CodeWriter loadToCodeWriter(InputStream is) throws IOException { CodeWriter cw = new CodeWriter(); ByteArrayOutputStream baos = new ByteArrayOutputStream(READ_BUFFER_SIZE); byte[] buffer = new byte[READ_BUFFER_SIZE]; diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 8adc0f159..238ce9ba4 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -1,5 +1,6 @@ package jadx.core.xmlgen; +import jadx.api.ResourcesLoader; import jadx.core.codegen.CodeWriter; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.DexNode; @@ -81,22 +82,30 @@ public class BinaryXMLParser extends CommonBinaryParser { } public synchronized CodeWriter parse(InputStream inputStream) throws IOException { + is = new ParserStream(inputStream); + if (!isBinaryXml()) { + return ResourcesLoader.loadToCodeWriter(inputStream); + } writer = new CodeWriter(); writer.add(""); - is = new ParserStream(inputStream); firstElement = true; decode(); writer.finish(); return writer; } + private boolean isBinaryXml() throws IOException { + is.mark(4); + int v = is.readInt16(); // version + int h = is.readInt16(); // header size + if (v == 0x0003 && h == 0x0008) { + return true; + } + is.reset(); + return false; + } + void decode() throws IOException { - if (is.readInt16() != 0x0003) { - die("Version is not 3"); - } - if (is.readInt16() != 0x0008) { - die("Size of header is not 8"); - } int size = is.readInt32(); while (is.getPos() < size) { int type = is.readInt16(); diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java b/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java index 3c1edb726..fc6cb2731 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/ParserStream.java @@ -132,6 +132,17 @@ public class ParserStream { checkPos(expectedOffset, error); } + public void mark(int len) throws IOException { + if (!input.markSupported()) { + throw new IOException("Mark not supported for input stream " + input.getClass()); + } + input.mark(len); + } + + public void reset() throws IOException { + input.reset(); + } + @Override public String toString() { return "pos: 0x" + Long.toHexString(readPos);