18405133a40e68eeaeff38b64af23426662852618Ben Gruver/* 28405133a40e68eeaeff38b64af23426662852618Ben Gruver * Copyright 2012, Google Inc. 38405133a40e68eeaeff38b64af23426662852618Ben Gruver * All rights reserved. 48405133a40e68eeaeff38b64af23426662852618Ben Gruver * 58405133a40e68eeaeff38b64af23426662852618Ben Gruver * Redistribution and use in source and binary forms, with or without 68405133a40e68eeaeff38b64af23426662852618Ben Gruver * modification, are permitted provided that the following conditions are 78405133a40e68eeaeff38b64af23426662852618Ben Gruver * met: 88405133a40e68eeaeff38b64af23426662852618Ben Gruver * 98405133a40e68eeaeff38b64af23426662852618Ben Gruver * * Redistributions of source code must retain the above copyright 108405133a40e68eeaeff38b64af23426662852618Ben Gruver * notice, this list of conditions and the following disclaimer. 118405133a40e68eeaeff38b64af23426662852618Ben Gruver * * Redistributions in binary form must reproduce the above 128405133a40e68eeaeff38b64af23426662852618Ben Gruver * copyright notice, this list of conditions and the following disclaimer 138405133a40e68eeaeff38b64af23426662852618Ben Gruver * in the documentation and/or other materials provided with the 148405133a40e68eeaeff38b64af23426662852618Ben Gruver * distribution. 158405133a40e68eeaeff38b64af23426662852618Ben Gruver * * Neither the name of Google Inc. nor the names of its 168405133a40e68eeaeff38b64af23426662852618Ben Gruver * contributors may be used to endorse or promote products derived from 178405133a40e68eeaeff38b64af23426662852618Ben Gruver * this software without specific prior written permission. 188405133a40e68eeaeff38b64af23426662852618Ben Gruver * 198405133a40e68eeaeff38b64af23426662852618Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 208405133a40e68eeaeff38b64af23426662852618Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 218405133a40e68eeaeff38b64af23426662852618Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 228405133a40e68eeaeff38b64af23426662852618Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 238405133a40e68eeaeff38b64af23426662852618Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 248405133a40e68eeaeff38b64af23426662852618Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 258405133a40e68eeaeff38b64af23426662852618Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 268405133a40e68eeaeff38b64af23426662852618Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 278405133a40e68eeaeff38b64af23426662852618Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 288405133a40e68eeaeff38b64af23426662852618Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 298405133a40e68eeaeff38b64af23426662852618Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 308405133a40e68eeaeff38b64af23426662852618Ben Gruver */ 318405133a40e68eeaeff38b64af23426662852618Ben Gruver 328405133a40e68eeaeff38b64af23426662852618Ben Gruverpackage org.jf.dexlib2.dexbacked; 338405133a40e68eeaeff38b64af23426662852618Ben Gruver 34d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruverimport com.google.common.io.ByteStreams; 3583f77f51aa888998486c0c9ad693047480b060b0Ben Gruverimport org.jf.dexlib2.Opcodes; 3690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.ReferenceType; 371771f92aaf6e2d95c4504174803117712a9800bbBen Gruverimport org.jf.dexlib2.dexbacked.raw.*; 3890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference; 3990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.dexbacked.reference.DexBackedMethodReference; 4090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.dexbacked.reference.DexBackedStringReference; 4190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.dexbacked.reference.DexBackedTypeReference; 4222c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.dexlib2.dexbacked.util.FixedSizeSet; 438405133a40e68eeaeff38b64af23426662852618Ben Gruverimport org.jf.dexlib2.iface.DexFile; 4490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport org.jf.dexlib2.iface.reference.Reference; 454eefe294e4c664577982283cc64c415819a30c1eBen Gruverimport org.jf.dexlib2.util.DexUtil; 4684c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruverimport org.jf.util.ExceptionWithContext; 478405133a40e68eeaeff38b64af23426662852618Ben Gruver 488405133a40e68eeaeff38b64af23426662852618Ben Gruverimport javax.annotation.Nonnull; 4984c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruverimport javax.annotation.Nullable; 50d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruverimport java.io.IOException; 51d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruverimport java.io.InputStream; 5290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport java.util.AbstractList; 5390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverimport java.util.List; 5422c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport java.util.Set; 558405133a40e68eeaeff38b64af23426662852618Ben Gruver 5612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruverpublic class DexBackedDexFile extends BaseDexBuffer implements DexFile { 57e202aeede5fb5fcc8de22601157b212eabb5f1c6Ben Gruver @Nonnull private final Opcodes opcodes; 5883f77f51aa888998486c0c9ad693047480b060b0Ben Gruver 5912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int stringCount; 6012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int stringStartOffset; 6112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int typeCount; 6212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int typeStartOffset; 6312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int protoCount; 6412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int protoStartOffset; 6512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int fieldCount; 6612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int fieldStartOffset; 6712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int methodCount; 6812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int methodStartOffset; 6912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int classCount; 7012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver private final int classStartOffset; 7112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver 7231ad2bc1002784161b318627f32b4df8bcb862e0Ben Gruver protected DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf, int offset, boolean verifyMagic) { 738920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver super(buf, offset); 7484c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 7583f77f51aa888998486c0c9ad693047480b060b0Ben Gruver this.opcodes = opcodes; 7683f77f51aa888998486c0c9ad693047480b060b0Ben Gruver 77d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver if (verifyMagic) { 784eefe294e4c664577982283cc64c415819a30c1eBen Gruver DexUtil.verifyDexHeader(buf, offset); 79d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 80d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 8112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver stringCount = readSmallUint(HeaderItem.STRING_COUNT_OFFSET); 8212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver stringStartOffset = readSmallUint(HeaderItem.STRING_START_OFFSET); 8312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver typeCount = readSmallUint(HeaderItem.TYPE_COUNT_OFFSET); 8412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver typeStartOffset = readSmallUint(HeaderItem.TYPE_START_OFFSET); 8512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver protoCount = readSmallUint(HeaderItem.PROTO_COUNT_OFFSET); 8612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver protoStartOffset = readSmallUint(HeaderItem.PROTO_START_OFFSET); 8712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver fieldCount = readSmallUint(HeaderItem.FIELD_COUNT_OFFSET); 8812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver fieldStartOffset = readSmallUint(HeaderItem.FIELD_START_OFFSET); 8912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver methodCount = readSmallUint(HeaderItem.METHOD_COUNT_OFFSET); 9012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver methodStartOffset = readSmallUint(HeaderItem.METHOD_START_OFFSET); 9112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver classCount = readSmallUint(HeaderItem.CLASS_COUNT_OFFSET); 9212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver classStartOffset = readSmallUint(HeaderItem.CLASS_START_OFFSET); 9312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 9484c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 9583f77f51aa888998486c0c9ad693047480b060b0Ben Gruver public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull BaseDexBuffer buf) { 9641a5b4953cd4797a79c1f8d39a8f644d80c72707Ben Gruver this(opcodes, buf.buf, buf.baseOffset); 97d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 98d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 9983f77f51aa888998486c0c9ad693047480b060b0Ben Gruver public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf, int offset) { 10083f77f51aa888998486c0c9ad693047480b060b0Ben Gruver this(opcodes, buf, offset, false); 101d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 102d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 10383f77f51aa888998486c0c9ad693047480b060b0Ben Gruver public DexBackedDexFile(@Nonnull Opcodes opcodes, @Nonnull byte[] buf) { 10483f77f51aa888998486c0c9ad693047480b060b0Ben Gruver this(opcodes, buf, 0, true); 105d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 106d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 10722a280710104cc6c51cbbfedcca08b4b1f481d5dBen Gruver @Nonnull 10883f77f51aa888998486c0c9ad693047480b060b0Ben Gruver public static DexBackedDexFile fromInputStream(@Nonnull Opcodes opcodes, @Nonnull InputStream is) 10983f77f51aa888998486c0c9ad693047480b060b0Ben Gruver throws IOException { 1104eefe294e4c664577982283cc64c415819a30c1eBen Gruver DexUtil.verifyDexHeader(is); 111d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 112d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver byte[] buf = ByteStreams.toByteArray(is); 11383f77f51aa888998486c0c9ad693047480b060b0Ben Gruver return new DexBackedDexFile(opcodes, buf, 0, false); 11483f77f51aa888998486c0c9ad693047480b060b0Ben Gruver } 11583f77f51aa888998486c0c9ad693047480b060b0Ben Gruver 116e202aeede5fb5fcc8de22601157b212eabb5f1c6Ben Gruver @Override @Nonnull public Opcodes getOpcodes() { 11783f77f51aa888998486c0c9ad693047480b060b0Ben Gruver return opcodes; 118d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 119d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 1208920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver // Will only be true for a dalvik-style odex file 121d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public boolean isOdexFile() { 122d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver return false; 123d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 124d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 1258920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver // Will be true for both a dalvik-style odex file, and an art-style odex file embedded in an oat file 1268920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver public boolean hasOdexOpcodes() { 1278920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver return false; 1288920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver } 1298920228819d4cd1cb016ba577b9c65a0cd798fd4Ben Gruver 13012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nonnull 13112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Override 13212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public Set<? extends DexBackedClassDef> getClasses() { 13312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return new FixedSizeSet<DexBackedClassDef>() { 13412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nonnull 13512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Override 13612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public DexBackedClassDef readItem(int index) { 13712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return new DexBackedClassDef(DexBackedDexFile.this, getClassDefItemOffset(index)); 1388405133a40e68eeaeff38b64af23426662852618Ben Gruver } 13912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver 14012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Override 14112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int size() { 14212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return classCount; 14384c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 14412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver }; 14512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 1468405133a40e68eeaeff38b64af23426662852618Ben Gruver 14712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getStringIdItemOffset(int stringIndex) { 14812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (stringIndex < 0 || stringIndex >= stringCount) { 149f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver throw new InvalidItemIndex(stringIndex, "String index out of bounds: %d", stringIndex); 15084c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 15112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return stringStartOffset + stringIndex*StringIdItem.ITEM_SIZE; 15212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 15384c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 15412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getTypeIdItemOffset(int typeIndex) { 15512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (typeIndex < 0 || typeIndex >= typeCount) { 156f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver throw new InvalidItemIndex(typeIndex, "Type index out of bounds: %d", typeIndex); 15784c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 15812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return typeStartOffset + typeIndex*TypeIdItem.ITEM_SIZE; 15912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 16084c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 16112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getFieldIdItemOffset(int fieldIndex) { 16212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (fieldIndex < 0 || fieldIndex >= fieldCount) { 163f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver throw new InvalidItemIndex(fieldIndex, "Field index out of bounds: %d", fieldIndex); 16484c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 16512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return fieldStartOffset + fieldIndex*FieldIdItem.ITEM_SIZE; 16612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 16784c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 16812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getMethodIdItemOffset(int methodIndex) { 16912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (methodIndex < 0 || methodIndex >= methodCount) { 170d3ba85b2ee46d14b13ccc17da6f261003f3a78dfBen Gruver throw new InvalidItemIndex(methodIndex, "Method index out of bounds: %d", methodIndex); 17184c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 17212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return methodStartOffset + methodIndex*MethodIdItem.ITEM_SIZE; 17312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 17484c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 17512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getProtoIdItemOffset(int protoIndex) { 17612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (protoIndex < 0 || protoIndex >= protoCount) { 177f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver throw new InvalidItemIndex(protoIndex, "Proto index out of bounds: %d", protoIndex); 17884c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 17912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return protoStartOffset + protoIndex*ProtoIdItem.ITEM_SIZE; 18012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 18184c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 18212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getClassDefItemOffset(int classIndex) { 18312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (classIndex < 0 || classIndex >= classCount) { 184f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver throw new InvalidItemIndex(classIndex, "Class index out of bounds: %d", classIndex); 18584c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 18612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return classStartOffset + classIndex*ClassDefItem.ITEM_SIZE; 18712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 18884c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 18912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public int getClassCount() { 19012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return classCount; 19112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 19284c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 193d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver public int getStringCount() { 194d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver return stringCount; 195d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver } 196d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver 197d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver public int getTypeCount() { 198d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver return typeCount; 199d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver } 200d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver 201d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver public int getProtoCount() { 202d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver return protoCount; 203d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver } 204d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver 205d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver public int getFieldCount() { 206d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver return fieldCount; 207d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver } 208d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver 209d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver public int getMethodCount() { 210d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver return methodCount; 211d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver } 212d15e31526fe157bb4baaa0b4bb3b27b739d1a2beBen Gruver 21312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nonnull 21412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public String getString(int stringIndex) { 21512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver int stringOffset = getStringIdItemOffset(stringIndex); 21612659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver int stringDataOffset = readSmallUint(stringOffset); 21712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver DexReader reader = readerAt(stringDataOffset); 21812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver int utf16Length = reader.readSmallUleb128(); 21912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return reader.readString(utf16Length); 22012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 22184c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 22212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nullable 22312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public String getOptionalString(int stringIndex) { 22412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (stringIndex == -1) { 22512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return null; 22684c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 22712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return getString(stringIndex); 22812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 22912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver 23012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nonnull 23112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public String getType(int typeIndex) { 23212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver int typeOffset = getTypeIdItemOffset(typeIndex); 23312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver int stringIndex = readSmallUint(typeOffset); 23412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return getString(stringIndex); 23512659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 23684c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver 23712659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nullable 23812659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public String getOptionalType(int typeIndex) { 23912659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver if (typeIndex == -1) { 24012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return null; 24184c1762a62d7fc6638432c6c56e0422aa8cc6939Ben Gruver } 24212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return getType(typeIndex); 24312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver } 24412659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver 24590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver public List<DexBackedStringReference> getStrings() { 24690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new AbstractList<DexBackedStringReference>() { 24790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public DexBackedStringReference get(int index) { 24890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver if (index < 0 || index >= getStringCount()) { 24990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver throw new IndexOutOfBoundsException(); 25090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 25190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new DexBackedStringReference(DexBackedDexFile.this, index); 25290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 25390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 25490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public int size() { 25590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getStringCount(); 25690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 25790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver }; 25890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 25990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 26090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver public List<DexBackedTypeReference> getTypes() { 26190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new AbstractList<DexBackedTypeReference>() { 26290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public DexBackedTypeReference get(int index) { 26390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver if (index < 0 || index >= getTypeCount()) { 26490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver throw new IndexOutOfBoundsException(); 26590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 26690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new DexBackedTypeReference(DexBackedDexFile.this, index); 26790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 26890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 26990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public int size() { 27090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getTypeCount(); 27190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 27290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver }; 27390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 27490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 27590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver public List<DexBackedMethodReference> getMethods() { 27690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new AbstractList<DexBackedMethodReference>() { 27790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public DexBackedMethodReference get(int index) { 27890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver if (index < 0 || index >= getMethodCount()) { 27990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver throw new IndexOutOfBoundsException(); 28090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 28190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new DexBackedMethodReference(DexBackedDexFile.this, index); 28290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 28390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 28490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public int size() { 28590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getMethodCount(); 28690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 28790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver }; 28890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 28990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 29090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver public List<DexBackedFieldReference> getFields() { 29190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new AbstractList<DexBackedFieldReference>() { 29290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public DexBackedFieldReference get(int index) { 29390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver if (index < 0 || index >= getFieldCount()) { 29490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver throw new IndexOutOfBoundsException(); 29590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 29690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return new DexBackedFieldReference(DexBackedDexFile.this, index); 29790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 29890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 29990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver @Override public int size() { 30090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getFieldCount(); 30190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 30290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver }; 30390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 30490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 30590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver public List<? extends Reference> getReferences(int referenceType) { 30690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver switch (referenceType) { 30790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver case ReferenceType.STRING: 30890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getStrings(); 30990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver case ReferenceType.TYPE: 31090cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getTypes(); 31190cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver case ReferenceType.METHOD: 31290cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getMethods(); 31390cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver case ReferenceType.FIELD: 31490cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver return getFields(); 31590cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver default: 31690cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver throw new IllegalArgumentException(String.format("Invalid reference type: %d", referenceType)); 31790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 31890cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver } 31990cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruver 32012659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Override 32112659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver @Nonnull 32212659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver public DexReader readerAt(int offset) { 32312659ec7db2876fee690a4192d6aefe71ac27b73Ben Gruver return new DexReader(this, offset); 3248405133a40e68eeaeff38b64af23426662852618Ben Gruver } 325d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 326d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public static class NotADexFile extends RuntimeException { 327d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public NotADexFile() { 328d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 329d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 330d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public NotADexFile(Throwable cause) { 331d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver super(cause); 332d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 333d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 334d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public NotADexFile(String message) { 335d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver super(message); 336d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 337d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver 338d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver public NotADexFile(String message, Throwable cause) { 339d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver super(message, cause); 340d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 341d45a6a60921ac27a4f13360a68e02e8f5fc28454Ben Gruver } 342f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver 343f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver public static class InvalidItemIndex extends ExceptionWithContext { 344f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver private final int itemIndex; 345f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver 346f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver public InvalidItemIndex(int itemIndex) { 347f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver super(""); 348f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver this.itemIndex = itemIndex; 349f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver } 350f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver 351f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver public InvalidItemIndex(int itemIndex, String message, Object... formatArgs) { 352f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver super(message, formatArgs); 353f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver this.itemIndex = itemIndex; 354f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver } 355f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver 356f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver public int getInvalidIndex() { 357f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver return itemIndex; 358f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver } 359f7d6d5fadec6276246194a55b6aefe4815b50aceBen Gruver } 3608405133a40e68eeaeff38b64af23426662852618Ben Gruver} 361