• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.dexlib2.dexbacked.raw;
33 
34 import com.google.common.base.Joiner;
35 import org.jf.dexlib2.AccessFlags;
36 import org.jf.dexlib2.dexbacked.DexBackedDexFile;
37 import org.jf.dexlib2.dexbacked.raw.util.DexAnnotator;
38 import org.jf.dexlib2.util.AnnotatedBytes;
39 
40 import javax.annotation.Nonnull;
41 import javax.annotation.Nullable;
42 
43 public class ClassDefItem {
44     public static final int ITEM_SIZE = 32;
45 
46     public static final int CLASS_OFFSET = 0;
47     public static final int ACCESS_FLAGS_OFFSET = 4;
48     public static final int SUPERCLASS_OFFSET = 8;
49     public static final int INTERFACES_OFFSET = 12;
50     public static final int SOURCE_FILE_OFFSET = 16;
51     public static final int ANNOTATIONS_OFFSET = 20;
52     public static final int CLASS_DATA_OFFSET = 24;
53     public static final int STATIC_VALUES_OFFSET = 28;
54 
55     @Nonnull
makeAnnotator(@onnull DexAnnotator annotator, @Nonnull MapItem mapItem)56     public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
57         return new SectionAnnotator(annotator, mapItem) {
58             private SectionAnnotator classDataAnnotator = null;
59 
60             @Override public void annotateSection(@Nonnull AnnotatedBytes out) {
61                 classDataAnnotator = annotator.getAnnotator(ItemType.CLASS_DATA_ITEM);
62                 super.annotateSection(out);
63             }
64 
65             @Nonnull @Override public String getItemName() {
66                 return "class_def_item";
67             }
68 
69             @Override
70             protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
71                 int classIndex = dexFile.readSmallUint(out.getCursor());
72                 out.annotate(4, "class_idx = %s", TypeIdItem.getReferenceAnnotation(dexFile, classIndex));
73 
74                 int accessFlags = dexFile.readInt(out.getCursor());
75                 out.annotate(4, "access_flags = 0x%x: %s", accessFlags,
76                         Joiner.on('|').join(AccessFlags.getAccessFlagsForClass(accessFlags)));
77 
78                 int superclassIndex = dexFile.readOptionalUint(out.getCursor());
79                 out.annotate(4, "superclass_idx = %s",
80                         TypeIdItem.getOptionalReferenceAnnotation(dexFile, superclassIndex));
81 
82                 int interfacesOffset = dexFile.readSmallUint(out.getCursor());
83                 out.annotate(4, "interfaces_off = %s", TypeListItem.getReferenceAnnotation(dexFile, interfacesOffset));
84 
85                 int sourceFileIdx = dexFile.readOptionalUint(out.getCursor());
86                 out.annotate(4, "source_file_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile,
87                         sourceFileIdx));
88 
89                 int annotationsOffset = dexFile.readSmallUint(out.getCursor());
90                 if (annotationsOffset == 0) {
91                     out.annotate(4, "annotations_off = annotations_directory_item[NO_OFFSET]");
92                 } else {
93                     out.annotate(4, "annotations_off = annotations_directory_item[0x%x]", annotationsOffset);
94                 }
95 
96                 int classDataOffset = dexFile.readSmallUint(out.getCursor());
97                 if (classDataOffset == 0) {
98                     out.annotate(4, "class_data_off = class_data_item[NO_OFFSET]");
99                 } else {
100                     out.annotate(4, "class_data_off = class_data_item[0x%x]", classDataOffset);
101                     addClassDataIdentity(classDataOffset, dexFile.getType(classIndex));
102                 }
103 
104                 int staticValuesOffset = dexFile.readSmallUint(out.getCursor());
105                 if (staticValuesOffset == 0) {
106                     out.annotate(4, "static_values_off = encoded_array_item[NO_OFFSET]");
107                 } else {
108                     out.annotate(4, "static_values_off = encoded_array_item[0x%x]", staticValuesOffset);
109                 }
110             }
111 
112             private void addClassDataIdentity(int classDataOffset, String classType) {
113                 if (classDataAnnotator != null) {
114                     classDataAnnotator.setItemIdentity(classDataOffset, classType);
115                 }
116             }
117         };
118     }
119 
120     @Nonnull
asString(@onnull DexBackedDexFile dexFile, int classIndex)121     public static String asString(@Nonnull DexBackedDexFile dexFile, int classIndex) {
122         int offset = dexFile.getClassDefItemOffset(classIndex);
123         int typeIndex = dexFile.readSmallUint(offset + CLASS_OFFSET);
124         return dexFile.getType(typeIndex);
125     }
126 
getClasses(@onnull RawDexFile dexFile)127     public static String[] getClasses(@Nonnull RawDexFile dexFile) {
128         MapItem mapItem = dexFile.getMapItemForSection(ItemType.CLASS_DEF_ITEM);
129         if (mapItem == null) {
130             return new String[0];
131         }
132 
133         int classCount = mapItem.getItemCount();
134         String[] ret = new String[classCount];
135         for (int i=0; i<classCount; i++) {
136             ret[i] = asString(dexFile, i);
137         }
138         return ret;
139     }
140 }
141