1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dexfuzz.rawdex; 18 19 import dexfuzz.Log; 20 21 import java.io.IOException; 22 23 public class HeaderItem implements RawDexObject { 24 public byte[] magic; 25 public int checksum; 26 public byte[] signature; // Verification doesn't depend on this, so we don't update it. 27 public int fileSize; 28 public int headerSize; 29 public int endianTag; 30 public int linkSize; 31 public Offset linkOff; 32 public Offset mapOff; 33 public int stringIdsSize; 34 public Offset stringIdsOff; 35 public int typeIdsSize; 36 public Offset typeIdsOff; 37 public int protoIdsSize; 38 public Offset protoIdsOff; 39 public int fieldIdsSize; 40 public Offset fieldIdsOff; 41 public int methodIdsSize; 42 public Offset methodIdsOff; 43 public int classDefsSize; 44 public Offset classDefsOff; 45 public int dataSize; 46 public Offset dataOff; 47 48 @Override read(DexRandomAccessFile file)49 public void read(DexRandomAccessFile file) throws IOException { 50 file.getOffsetTracker().getNewOffsettable(file, this); 51 magic = new byte[8]; 52 for (int i = 0; i < 8; i++) { 53 magic[i] = file.readByte(); 54 } 55 checksum = file.readUInt(); 56 signature = new byte[20]; 57 for (int i = 0; i < 20; i++) { 58 signature[i] = file.readByte(); 59 } 60 fileSize = file.readUInt(); 61 headerSize = file.readUInt(); 62 endianTag = file.readUInt(); 63 linkSize = file.readUInt(); 64 linkOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 65 mapOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 66 stringIdsSize = file.readUInt(); 67 stringIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 68 typeIdsSize = file.readUInt(); 69 typeIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 70 protoIdsSize = file.readUInt(); 71 protoIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 72 fieldIdsSize = file.readUInt(); 73 fieldIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 74 methodIdsSize = file.readUInt(); 75 methodIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 76 classDefsSize = file.readUInt(); 77 classDefsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 78 dataSize = file.readUInt(); 79 dataOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 80 if (headerSize != 0x70) { 81 Log.errorAndQuit("Invalid header size in header."); 82 } 83 if (file.getFilePointer() != headerSize) { 84 Log.errorAndQuit("Read a different amount than expected in header: " 85 + file.getFilePointer()); 86 } 87 } 88 89 @Override write(DexRandomAccessFile file)90 public void write(DexRandomAccessFile file) throws IOException { 91 file.getOffsetTracker().updatePositionOfNextOffsettable(file); 92 for (int i = 0; i < 8; i++) { 93 file.writeByte(magic[i]); 94 } 95 // Will be recalculated later! 96 file.writeUInt(checksum); 97 for (int i = 0; i < 20; i++) { 98 file.writeByte(signature[i]); 99 } 100 // Will be recalculated later! 101 file.writeUInt(fileSize); 102 file.writeUInt(headerSize); 103 file.writeUInt(endianTag); 104 file.writeUInt(linkSize); 105 file.getOffsetTracker().tryToWriteOffset(linkOff, file, false /* ULEB128 */); 106 file.getOffsetTracker().tryToWriteOffset(mapOff, file, false /* ULEB128 */); 107 file.writeUInt(stringIdsSize); 108 file.getOffsetTracker().tryToWriteOffset(stringIdsOff, file, false /* ULEB128 */); 109 file.writeUInt(typeIdsSize); 110 file.getOffsetTracker().tryToWriteOffset(typeIdsOff, file, false /* ULEB128 */); 111 file.writeUInt(protoIdsSize); 112 file.getOffsetTracker().tryToWriteOffset(protoIdsOff, file, false /* ULEB128 */); 113 file.writeUInt(fieldIdsSize); 114 file.getOffsetTracker().tryToWriteOffset(fieldIdsOff, file, false /* ULEB128 */); 115 file.writeUInt(methodIdsSize); 116 file.getOffsetTracker().tryToWriteOffset(methodIdsOff, file, false /* ULEB128 */); 117 file.writeUInt(classDefsSize); 118 file.getOffsetTracker().tryToWriteOffset(classDefsOff, file, false /* ULEB128 */); 119 // will be recalculated later 120 file.writeUInt(dataSize); 121 file.getOffsetTracker().tryToWriteOffset(dataOff, file, false /* ULEB128 */); 122 } 123 124 @Override incrementIndex(IndexUpdateKind kind, int insertedIdx)125 public void incrementIndex(IndexUpdateKind kind, int insertedIdx) { 126 // Do nothing 127 } 128 } 129