/** * read String pool, for apk binary xml file and resource table. */ public static async Task <StringPool> readStringPool(ByteBuffer buffer, StringPoolHeader stringPoolHeader) { long beginPos = buffer.position(); long[] offsets = new long[(int)stringPoolHeader.getStringCount()]; // read strings offset if (stringPoolHeader.getStringCount() > 0) { for (int idx = 0; idx < stringPoolHeader.getStringCount(); idx++) { offsets[idx] = Buffers.readUInt(buffer); } } // read flag // the string index is sorted by the string values if true bool sorted = (stringPoolHeader.getFlags() & StringPoolHeader.SORTED_FLAG) != 0; // string use utf-8 format if true, otherwise utf-16 bool utf8 = (stringPoolHeader.getFlags() & StringPoolHeader.UTF8_FLAG) != 0; // read strings. the head and metas have 28 bytes long stringPos = beginPos + stringPoolHeader.getStringsStart() - stringPoolHeader.getHeaderSize(); buffer.position((int)stringPos); StringPoolEntry[] entries = new StringPoolEntry[offsets.Length]; for (int i = 0; i < offsets.Length; i++) { entries[i] = new StringPoolEntry(i, stringPos + offsets[i]); } string lastStr = null; long lastOffset = -1; StringPool stringPool = new StringPool((int)stringPoolHeader.getStringCount()); foreach (StringPoolEntry entry in entries) { if (entry.getOffset() == lastOffset) { stringPool.set(entry.getIdx(), lastStr); continue; } buffer.position((int)entry.getOffset()); lastOffset = entry.getOffset(); string str = await ParseUtils.readString(buffer, utf8); lastStr = str; stringPool.set(entry.getIdx(), str); } // read styles if (stringPoolHeader.getStyleCount() > 0) { // now we just skip it } buffer.position((int)(beginPos + stringPoolHeader.getBodySize())); return(stringPool); }
/** * read string pool for dex file. * dex file string pool diff a bit with binary xml file or resource table. * * @param offsets * @return * @throws IOException */ private StringPool readStrings(long[] offsets) { // read strings. // buffer some apk, the strings' offsets may not well ordered. we sort it first StringPoolEntry[] entries = new StringPoolEntry[offsets.Length]; for (int i = 0; i < offsets.Length; i++) { entries[i] = new StringPoolEntry(i, offsets[i]); } string lastStr = null; long lastOffset = -1; StringPool stringpool = new StringPool(offsets.Length); foreach (StringPoolEntry entry in entries) { if (entry.getOffset() == lastOffset) { stringpool.set(entry.getIdx(), lastStr); continue; } buffer.position((int)entry.getOffset()); lastOffset = entry.getOffset(); string str = readString(); lastStr = str; stringpool.set(entry.getIdx(), str); } return(stringpool); }