HeaderItem.java revision 18b069d17ee8f0fb589c31de0afbbb8240975d14
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
32package org.jf.dexlib2.dexbacked.raw;
33
34import org.jf.dexlib2.dexbacked.DexBackedDexFile;
35import org.jf.dexlib2.util.AnnotatedBytes;
36import org.jf.util.StringUtils;
37
38import javax.annotation.Nonnull;
39
40public class HeaderItem {
41    public static final int ITEM_SIZE = 0x70;
42
43    public static final byte[][] MAGIC_VALUES= new byte[][] {
44            new byte[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00},
45            new byte[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x36, 0x00}};
46
47    public static final int LITTLE_ENDIAN_TAG = 0x12345678;
48    public static final int BIG_ENDIAN_TAG = 0x78563412;
49
50    public static final int CHECKSUM_OFFSET = 8;
51
52    public static final int SIGNATURE_OFFSET = 12;
53    public static final int SIGNATURE_SIZE = 20;
54
55    public static final int ENDIAN_TAG_OFFSET = 40;
56
57    public static final int MAP_OFFSET = 52;
58
59    public static final int STRING_COUNT_OFFSET = 56;
60    public static final int STRING_START_OFFSET = 60;
61
62    public static final int TYPE_COUNT_OFFSET = 64;
63    public static final int TYPE_START_OFFSET = 68;
64
65    public static final int PROTO_COUNT_OFFSET = 72;
66    public static final int PROTO_START_OFFSET = 76;
67
68    public static final int FIELD_COUNT_OFFSET = 80;
69    public static final int FIELD_START_OFFSET = 84;
70
71    public static final int METHOD_COUNT_OFFSET = 88;
72    public static final int METHOD_START_OFFSET = 92;
73
74    public static final int CLASS_COUNT_OFFSET = 96;
75    public static final int CLASS_START_OFFSET = 100;
76
77    @Nonnull
78    public static SectionAnnotator getAnnotator() {
79        return new SectionAnnotator() {
80            @Override
81            public void annotateSection(@Nonnull AnnotatedBytes out, @Nonnull DexBackedDexFile dexFile, int length) {
82                int startOffset = out.getCursor();
83                int headerSize;
84
85                out.annotate(0, "-----------------------------");
86                out.annotate(0, "header item");
87                out.annotate(0, "-----------------------------");
88                out.annotate(0, "");
89
90                StringBuilder magicBuilder = new StringBuilder();
91                for (int i=0; i<8; i++) {
92                    magicBuilder.append((char)dexFile.readUbyte(startOffset + i));
93                }
94
95                out.annotate(8, "magic: %s", StringUtils.escapeString(magicBuilder.toString()));
96                out.annotate(4, "checksum");
97                out.annotate(20, "signature");
98                out.annotate(4, "file_size: %d", dexFile.readInt(out.getCursor()));
99
100                headerSize = dexFile.readInt(out.getCursor());
101                out.annotate(4, "header_size: %d", headerSize);
102
103                int endianTag = dexFile.readInt(out.getCursor());
104                out.annotate(4, "endian_tag: 0x%x (%s)", endianTag, getEndianText(endianTag));
105
106                out.annotate(4, "link_size: %d", dexFile.readInt(out.getCursor()));
107                out.annotate(4, "link_offset: 0x%x", dexFile.readInt(out.getCursor()));
108
109                out.annotate(4, "map_off: 0x%x", dexFile.readInt(out.getCursor()));
110
111                out.annotate(4, "string_ids_size: %d", dexFile.readInt(out.getCursor()));
112                out.annotate(4, "string_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
113
114                out.annotate(4, "type_ids_size: %d", dexFile.readInt(out.getCursor()));
115                out.annotate(4, "type_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
116
117                out.annotate(4, "proto_ids_size: %d", dexFile.readInt(out.getCursor()));
118                out.annotate(4, "proto_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
119
120                out.annotate(4, "field_ids_size: %d", dexFile.readInt(out.getCursor()));
121                out.annotate(4, "field_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
122
123                out.annotate(4, "method_ids_size: %d", dexFile.readInt(out.getCursor()));
124                out.annotate(4, "method_ids_off: 0x%x", dexFile.readInt(out.getCursor()));
125
126                out.annotate(4, "class_defs_size: %d", dexFile.readInt(out.getCursor()));
127                out.annotate(4, "class_defs_off: 0x%x", dexFile.readInt(out.getCursor()));
128
129                out.annotate(4, "data_size: %d", dexFile.readInt(out.getCursor()));
130                out.annotate(4, "data_off: 0x%x", dexFile.readInt(out.getCursor()));
131
132                if (headerSize > ITEM_SIZE) {
133                    out.annotate(headerSize - ITEM_SIZE, "header padding");
134                }
135            }
136        };
137    }
138
139    private static String getEndianText(int endianTag) {
140        if (endianTag == LITTLE_ENDIAN_TAG) {
141            return "Little Endian";
142        }
143        if (endianTag == BIG_ENDIAN_TAG) {
144            return "Big Endian";
145        }
146        return "Invalid";
147    }
148}
149