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 Kyle/** 20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Tracks the original and updated positions of a RawDexObject when it is 21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * parsed in from a DEX file, and written out to a mutated DEX file. 22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic class Offsettable { 24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The position of this Offsettable's item when it was read in. 26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private int originalPosition; 28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Set as we write out any Offsettable, so the Offset knows what its 31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * new value should be. 32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private int newPosition; 34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The actual Item this Offsettable contains. 37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private RawDexObject item; 39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Set either when getOriginalPosition() is called by the OffsetTracker 42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * to put the location in the offsettable map, so when Offsets are being 43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * associated, they know which Offsettable to point at. 44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Or when an Offsettable is created that is marked as new, so we don't 45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * need to know its original position, because an Offset will be directly 46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * associated with it. 47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private boolean originalPositionKnown; 49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Set when we calculate the new position of this Offsettable as the file is 52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * being output. 53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private boolean updated; 55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Only the OffsetTracker should be able to create a new Offsettable. 58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public Offsettable(RawDexObject item, boolean isNew) { 60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle this.item = item; 61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (isNew) { 62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // We no longer care about the original position of the Offsettable, because 63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // we are at the stage where we manually point Offsets at Offsettables, and 64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // don't need to use the OffsetTracker's offsettable map. 65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // So just lie and say we know it now. 66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle originalPositionKnown = true; 67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public RawDexObject getItem() { 71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return item; 72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Gets the offset from the beginning of the file to the RawDexObject this Offsettable 76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * contains, when the file was originally read. 77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Called when we're associating Offsets with Offsettables using the OffsetTracker's 78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * offsettable map. 79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int getOriginalPosition() { 81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (!originalPositionKnown) { 82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle throw new Error("Cannot get the original position of an Offsettable when not yet set."); 83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return originalPosition; 85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void setOriginalPosition(int pos) { 88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle originalPosition = pos; 89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle originalPositionKnown = true; 90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Get the new position of this Offsettable, once it's been written out to the output file. 94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public int getNewPosition() { 96959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (!updated) { 97959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle throw new Error("Cannot request new position before it has been set!"); 98959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 99959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return newPosition; 100959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 101959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 102959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 103959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Record the new position of this Offsettable, as it is written out to the output file. 104959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 105959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void setNewPosition(int pos) { 106959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (!updated) { 107959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle newPosition = pos; 108959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle updated = true; 109959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } else { 110959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle throw new Error("Cannot update an Offsettable twice!"); 111959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 112959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 113959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 114959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public boolean readyForFinalOffsetToBeWritten() { 115959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return (originalPositionKnown && updated); 116959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 117959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle} 118