1cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver/* 2cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * Copyright 2013, Google Inc. 3cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * All rights reserved. 4cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * 5cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * Redistribution and use in source and binary forms, with or without 6cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * modification, are permitted provided that the following conditions are 7cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * met: 8cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * 9cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * * Redistributions of source code must retain the above copyright 10cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * notice, this list of conditions and the following disclaimer. 11cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * * Redistributions in binary form must reproduce the above 12cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * copyright notice, this list of conditions and the following disclaimer 13cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * in the documentation and/or other materials provided with the 14cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * distribution. 15cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * * Neither the name of Google Inc. nor the names of its 16cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * contributors may be used to endorse or promote products derived from 17cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * this software without specific prior written permission. 18cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * 19cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver */ 31cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 32cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverpackage org.jf.dexlib2.dexbacked.raw; 33cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 34cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport com.google.common.base.Joiner; 35cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport org.jf.dexlib2.AccessFlags; 36cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport org.jf.dexlib2.dexbacked.DexReader; 378f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruverimport org.jf.dexlib2.dexbacked.raw.util.DexAnnotator; 38cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport org.jf.dexlib2.util.AnnotatedBytes; 39cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 40cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport javax.annotation.Nonnull; 41cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverimport javax.annotation.Nullable; 42cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 43cd12f13ffc2e67e674d82060076a450051b0371bBen Gruverpublic class ClassDataItem { 448f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull 458f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) { 468f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return new SectionAnnotator(annotator, mapItem) { 478f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private SectionAnnotator codeItemAnnotator = null; 48cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 498f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Override public void annotateSection(@Nonnull AnnotatedBytes out) { 508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver codeItemAnnotator = annotator.getAnnotator(ItemType.CODE_ITEM); 518f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver super.annotateSection(out); 52cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver } 53cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 54cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 558f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull @Override public String getItemName() { 568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return "class_data_item"; 57cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver } 58cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver 59cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver @Override 608f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) { 618f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver DexReader reader = dexFile.readerAt(out.getCursor()); 626d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 636d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver int staticFieldsSize = reader.readSmallUleb128(); 648f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize); 658f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 666d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver int instanceFieldsSize = reader.readSmallUleb128(); 678f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "instance_fields_size = %d", instanceFieldsSize); 688f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 696d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver int directMethodsSize = reader.readSmallUleb128(); 708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "direct_methods_size = %d", directMethodsSize); 718f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 726d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver int virtualMethodsSize = reader.readSmallUleb128(); 738f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "virtual_methods_size = %d", virtualMethodsSize); 746d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 758f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int previousIndex = 0; 768f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (staticFieldsSize > 0) { 778f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "static_fields:"); 788f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 798f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver for (int i=0; i<staticFieldsSize; i++) { 808f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "static_field[%d]", i); 818f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 828f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex); 838f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 848f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 858f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 866d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 876d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 888f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (instanceFieldsSize > 0) { 898f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "instance_fields:"); 908f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 918f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = 0; 928f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver for (int i=0; i<instanceFieldsSize; i++) { 938f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "instance_field[%d]", i); 948f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 958f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex); 968f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 978f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 988f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 996d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 1006d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1018f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (directMethodsSize > 0) { 1028f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "direct_methods:"); 1038f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 1048f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = 0; 1058f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver for (int i=0; i<directMethodsSize; i++) { 1068f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "direct_method[%d]", i); 1078f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 1088f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex); 1098f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 1108f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1118f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 1126d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 1136d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1148f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (virtualMethodsSize > 0) { 1158f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "virtual_methods:"); 1168f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 1178f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = 0; 1188f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver for (int i=0; i<virtualMethodsSize; i++) { 1198f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotate(0, "virtual_method[%d]", i); 1208f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.indent(); 1218f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex); 1228f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 1238f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1248f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.deindent(); 1256d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 1266d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 1276d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1288f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private int annotateEncodedField(@Nonnull AnnotatedBytes out, @Nonnull RawDexFile dexFile, 1298f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull DexReader reader, int previousIndex) { 13045b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver // large values may be used for the index delta, which cause the cumulative index to overflow upon 13145b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver // addition, effectively allowing out of order entries. 13245b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver int indexDelta = reader.readLargeUleb128(); 1338f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int fieldIndex = previousIndex + indexDelta; 1348f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "field_idx_diff = %d: %s", indexDelta, 1358f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex)); 1366d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1378f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int accessFlags = reader.readSmallUleb128(); 1388f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, 1398f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver Joiner.on('|').join(AccessFlags.getAccessFlagsForField(accessFlags))); 1406d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1418f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return fieldIndex; 1428f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1436d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver 1448f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private int annotateEncodedMethod(@Nonnull AnnotatedBytes out, @Nonnull RawDexFile dexFile, 1458f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver @Nonnull DexReader reader, int previousIndex) { 14645b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver // large values may be used for the index delta, which cause the cumulative index to overflow upon 14745b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver // addition, effectively allowing out of order entries. 14845b8a4dae8176ad7a8cfb0ee0bc79354ac8c60b6Ben Gruver int indexDelta = reader.readLargeUleb128(); 1498f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int methodIndex = previousIndex + indexDelta; 1508f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "method_idx_diff = %d: %s", indexDelta, 1518f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver MethodIdItem.getReferenceAnnotation(dexFile, methodIndex)); 1528f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 1538f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int accessFlags = reader.readSmallUleb128(); 1548f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, 1558f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver Joiner.on('|').join(AccessFlags.getAccessFlagsForMethod(accessFlags))); 1568f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 1578f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver int codeOffset = reader.readSmallUleb128(); 1588f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (codeOffset == 0) { 159a2b3cfe5f2c453ee649417ad7c5fc6072ca92588Ben Gruver out.annotateTo(reader.getOffset(), "code_off = code_item[NO_OFFSET]"); 1608f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } else { 1618f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver out.annotateTo(reader.getOffset(), "code_off = code_item[0x%x]", codeOffset); 1628f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver addCodeItemIdentity(codeOffset, MethodIdItem.asString(dexFile, methodIndex)); 1638f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1648f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 1658f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver return methodIndex; 1668f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1678f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver 1688f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver private void addCodeItemIdentity(int codeItemOffset, String methodString) { 1698f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver if (codeItemAnnotator != null) { 1708f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver codeItemAnnotator.setItemIdentity(codeItemOffset, methodString); 1718f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1728f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver } 1738f8b67f65ec3390e92cce7d710e5b1eaabd4e248Ben Gruver }; 1746d607ebe1d7bccd4fdf220f0275207cb452501bdBen Gruver } 175cd12f13ffc2e67e674d82060076a450051b0371bBen Gruver} 176