1959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/* 2959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Copyright (C) 2014 The Android Open Source Project 3959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 4959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Licensed under the Apache License, Version 2.0 (the "License"); 5959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * you may not use this file except in compliance with the License. 6959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * You may obtain a copy of the License at 7959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 8959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * http://www.apache.org/licenses/LICENSE-2.0 9959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 10959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Unless required by applicable law or agreed to in writing, software 11959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * distributed under the License is distributed on an "AS IS" BASIS, 12959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * See the License for the specific language governing permissions and 14959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * limitations under the License. 15959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 16959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 17959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepackage dexfuzz.rawdex; 18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Log; 20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.io.IOException; 22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic class HeaderItem implements RawDexObject { 24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public byte[] magic; 25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int checksum; 26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public byte[] signature; // Verification doesn't depend on this, so we don't update it. 27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int fileSize; 28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int headerSize; 29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int endianTag; 30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int linkSize; 31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset linkOff; 32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset mapOff; 33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int stringIdsSize; 34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset stringIdsOff; 35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int typeIdsSize; 36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset typeIdsOff; 37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int protoIdsSize; 38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset protoIdsOff; 39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int fieldIdsSize; 40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset fieldIdsOff; 41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int methodIdsSize; 42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset methodIdsOff; 43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int classDefsSize; 44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset classDefsOff; 45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int dataSize; 46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offset dataOff; 47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void read(DexRandomAccessFile file) throws IOException { 50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().getNewOffsettable(file, this); 51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle magic = new byte[8]; 52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle for (int i = 0; i < 8; i++) { 53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle magic[i] = file.readByte(); 54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle checksum = file.readUInt(); 56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle signature = new byte[20]; 57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle for (int i = 0; i < 20; i++) { 58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle signature[i] = file.readByte(); 59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle fileSize = file.readUInt(); 61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle headerSize = file.readUInt(); 62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle endianTag = file.readUInt(); 63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle linkSize = file.readUInt(); 64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle linkOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mapOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle stringIdsSize = file.readUInt(); 67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle stringIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle typeIdsSize = file.readUInt(); 69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle typeIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protoIdsSize = file.readUInt(); 71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protoIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle fieldIdsSize = file.readUInt(); 73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle fieldIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle methodIdsSize = file.readUInt(); 75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle methodIdsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle classDefsSize = file.readUInt(); 77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle classDefsOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle dataSize = file.readUInt(); 79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle dataOff = file.getOffsetTracker().getNewOffset(file.readUInt()); 80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (headerSize != 0x70) { 81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Invalid header size in header."); 82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (file.getFilePointer() != headerSize) { 84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.errorAndQuit("Read a different amount than expected in header: " 85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle + file.getFilePointer()); 86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void write(DexRandomAccessFile file) throws IOException { 91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().updatePositionOfNextOffsettable(file); 92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle for (int i = 0; i < 8; i++) { 93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeByte(magic[i]); 94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Will be recalculated later! 96959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(checksum); 97959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle for (int i = 0; i < 20; i++) { 98959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeByte(signature[i]); 99959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 100959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Will be recalculated later! 101959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(fileSize); 102959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(headerSize); 103959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(endianTag); 104959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(linkSize); 105959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(linkOff, file, false /* ULEB128 */); 106959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(mapOff, file, false /* ULEB128 */); 107959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(stringIdsSize); 108959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(stringIdsOff, file, false /* ULEB128 */); 109959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(typeIdsSize); 110959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(typeIdsOff, file, false /* ULEB128 */); 111959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(protoIdsSize); 112959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(protoIdsOff, file, false /* ULEB128 */); 113959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(fieldIdsSize); 114959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(fieldIdsOff, file, false /* ULEB128 */); 115959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(methodIdsSize); 116959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(methodIdsOff, file, false /* ULEB128 */); 117959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(classDefsSize); 118959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(classDefsOff, file, false /* ULEB128 */); 119959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // will be recalculated later 120959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.writeUInt(dataSize); 121959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle file.getOffsetTracker().tryToWriteOffset(dataOff, file, false /* ULEB128 */); 122959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 123959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 124959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle @Override 125959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void incrementIndex(IndexUpdateKind kind, int insertedIdx) { 126959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Do nothing 127959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 128959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle} 129