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