From b7b449eaaf0f3bb031769256288150c5e764b0e3 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 13 Dec 2017 13:16:48 -0500 Subject: [PATCH] We are ignoring typeIdOffset - missing sample that experiences this - needs tests - samples requested: https://github.com/iBotPeaches/Apktool/issues/1728 - refs: https://github.com/iBotPeaches/platform_frameworks_base/commit/f90f2f8dc36e7243b85e0b6a7fd5a590893c827e --- .../brut/androlib/res/decoder/ARSCDecoder.java | 17 ++++++++++++++++- .../brut/androlib/res/decoder/StringBlock.java | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index d83d525e..ebaacb1c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -77,6 +77,7 @@ public class ARSCDecoder { nextChunk(); for (int i = 0; i < packageCount; i++) { + mTypeIdOffset = 0; packages[i] = readTablePackage(); } return packages; @@ -103,6 +104,17 @@ public class ARSCDecoder { /* keyStrings */mIn.skipInt(); /* lastPublicKey */mIn.skipInt(); + // TypeIdOffset was added platform_frameworks_base/@f90f2f8dc36e7243b85e0b6a7fd5a590893c827e + // which is only in split/new applications. + int splitHeaderSize = (2 + 2 + 4 + 4 + (2 * 128) + (4 * 5)); // short, short, int, int, char[128], int * 4 + if (mHeader.headerSize == splitHeaderSize) { + mTypeIdOffset = mIn.readInt(); + } + + if (mTypeIdOffset > 0) { + LOGGER.warning("Please report this application to Apktool for a fix: https://github.com/iBotPeaches/Apktool/issues/1728"); + } + mTypeNames = StringBlock.read(mIn); mSpecNames = StringBlock.read(mIn); @@ -157,6 +169,7 @@ public class ARSCDecoder { // skip "TYPE 8 chunks" and/or padding data at the end of this chunk if (mCountIn.getCount() < mHeader.endPosition) { + LOGGER.warning("Unknown data detected. Skipping: " + (mHeader.endPosition - mCountIn.getCount()) + " byte(s)"); mCountIn.skip(mHeader.endPosition - mCountIn.getCount()); } @@ -186,7 +199,7 @@ public class ARSCDecoder { private ResType readTableType() throws IOException, AndrolibException { checkChunkType(Header.TYPE_TYPE); - int typeId = mIn.readUnsignedByte(); + int typeId = mIn.readUnsignedByte() - mTypeIdOffset; if (mResTypeSpecs.containsKey(typeId)) { mResId = (0xff000000 & mResId) | mResTypeSpecs.get(typeId).getId() << 16; mTypeSpec = mResTypeSpecs.get(typeId); @@ -205,6 +218,7 @@ public class ARSCDecoder { // For some APKs there is a disconnect between the reported size of Configs // If we find a mismatch skip those bytes. if (position != mCountIn.getCount()) { + LOGGER.warning("Invalid data detected. Skipping: " + (position - mCountIn.getCount()) + " byte(s)"); mIn.skipBytes(position - mCountIn.getCount()); } @@ -544,6 +558,7 @@ public class ARSCDecoder { private ResTypeSpec mTypeSpec; private ResType mType; private int mResId; + private int mTypeIdOffset = 0; private boolean[] mMissingResSpecs; private HashMap mResTypeSpecs = new HashMap<>(); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java index c1656d27..4bfeb190 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StringBlock.java @@ -41,7 +41,7 @@ public class StringBlock { * be at the chunk type. */ public static StringBlock read(ExtDataInput reader) throws IOException { - reader.skipCheckChunkTypeInt(CHUNK_STRINGPOOL_TYPE, CHUNK_NULL_TYPE); + reader.skipCheckInt(CHUNK_STRINGPOOL_TYPE); int chunkSize = reader.readInt(); // ResStringPool_header