Skip to content

Commit 5b941b9

Browse files
committed
fix: support skipping unread header sizes of ResChunk
1 parent e3e2a7e commit 5b941b9

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/arsc/ARSCHeader.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import java.io.EOFException;
2323
import java.io.IOException;
24+
import java.math.BigInteger;
25+
import java.util.logging.Logger;
2426

2527
public class ARSCHeader {
2628
public final short type;
@@ -48,6 +50,28 @@ public static ARSCHeader read(ExtDataInput in, CountingInputStream countIn) thro
4850
return new ARSCHeader(type, in.readShort(), in.readInt(), start);
4951
}
5052

53+
public void skipRemainingHeader(ExtDataInput in, CountingInputStream countIn) throws IOException {
54+
// Some applications lie about the reported size of their chunk header. Trusting the chunkSize is misleading
55+
// So compare to what we actually read in the header vs reported and skip the rest.
56+
int actualHeaderSize = countIn.getCount() - this.startPosition;
57+
int exceedingSize = this.headerSize - actualHeaderSize;
58+
if (exceedingSize > 0) {
59+
byte[] buf = new byte[exceedingSize];
60+
in.readFully(buf);
61+
BigInteger exceedingBI = new BigInteger(1, buf);
62+
63+
if (exceedingBI.equals(BigInteger.ZERO)) {
64+
LOGGER.fine(String.format("Chunk header size (%d), read (%d), but exceeding bytes are all zero.",
65+
this.headerSize, actualHeaderSize
66+
));
67+
} else {
68+
LOGGER.warning(String.format("Chunk header size (%d), read (%d). Exceeding bytes: 0x%X.",
69+
this.headerSize, actualHeaderSize, exceedingBI
70+
));
71+
}
72+
}
73+
}
74+
5175
public void skipChunk(ExtDataInput in) throws IOException {
5276
in.skipBytes(chunkSize - headerSize);
5377
}
@@ -76,4 +100,6 @@ public void skipChunk(ExtDataInput in) throws IOException {
76100
public final static short RES_XML_CDATA_TYPE = 0x0104;
77101
public final static short RES_XML_LAST_CHUNK_TYPE = 0x017f;
78102
public final static short RES_XML_RESOURCE_MAP_TYPE = 0x0180;
103+
104+
private static final Logger LOGGER = Logger.getLogger(ARSCHeader.class.getName());
79105
}

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ private ResPackage[] readResourceTable() throws IOException, AndrolibException {
120120
}
121121
break chunkLoop;
122122
}
123+
124+
// Check for chunks that are lying about their header size
125+
mHeader.skipRemainingHeader(mIn, mCountIn);
123126
}
124127

125128
if (mPkg.getResSpecCount() > 0) {

0 commit comments

Comments
 (0)