From ff093aeebbeaf3c573c33fb28aaef8e61bdcc4d9 Mon Sep 17 00:00:00 2001 From: Skylot Date: Wed, 7 Jan 2015 12:45:08 +0300 Subject: [PATCH] core: fix strings pool parsing in '.arsc' file --- .../jadx/core/xmlgen/CommonBinaryParser.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/CommonBinaryParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/CommonBinaryParser.java index 0e2cc68a2..d024bc968 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/CommonBinaryParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/CommonBinaryParser.java @@ -15,6 +15,7 @@ public class CommonBinaryParser extends ParserConstants { long start = is.getPos() - 2; is.checkInt16(0x001c, "String pool header size not 0x001c"); long size = is.readUInt32(); + long chunkEnd = start + size; int stringCount = is.readInt32(); int styleCount = is.readInt32(); @@ -35,12 +36,12 @@ public class CommonBinaryParser extends ParserConstants { } } else { // UTF-16 - long stringsStartOffset = start + stringsStart; + long end = stylesStart == 0 ? chunkEnd : start + stylesStart; + byte[] strArray = is.readInt8Array((int) (end - is.getPos())); for (int i = 0; i < stringCount; i++) { - // is.checkPos(stringsStartOffset + stringsOffset[i], "Expected string start"); - // TODO: don't trust specified string length, read until \0 - // TODO: stringsOffset can be same for different indexes - strings[i] = is.readString16(); + // don't trust specified string length, read until \0 + // stringsOffset can be same for different indexes + strings[i] = extractString16(strArray, stringsOffset[i]); } } if (stylesStart != 0) { @@ -50,10 +51,26 @@ public class CommonBinaryParser extends ParserConstants { } } // skip padding zeroes - is.skip(start + size - is.getPos()); + is.skip(chunkEnd - is.getPos()); return strings; } + private static String extractString16(byte[] strArray, int offset) { + int len = strArray.length; + int start = offset + 2; + int end = start; + while (true) { + if (end + 1 >= len) { + break; + } + if (strArray[end] == 0 && strArray[end + 1] == 0) { + break; + } + end += 2; + } + return new String(strArray, start, end - start, ParserStream.STRING_CHARSET_UTF16); + } + protected void die(String message) throws IOException { throw new IOException("Decode error: " + message + ", position: 0x" + Long.toHexString(is.getPos()));