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.program.mutators; 18959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 19959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Log; 20959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.MutationStats; 21959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.Options; 22959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.program.MutatableCode; 23959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport dexfuzz.program.Mutation; 24959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 25959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.util.List; 26959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyleimport java.util.Random; 27959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 28959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle/** 29959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The base class for all classes that can mutate methods. 30959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 31959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kylepublic abstract class CodeMutator { 32959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 33959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The RNG, passed in by the Program that initialised us. 34959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 35959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected Random rng; 36959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 37959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 38959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Used to track which mutations happen. 39959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 40959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected MutationStats stats; 41959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 42959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 43959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Used to track mutations that have been applied so far. 44959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 45959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected List<Mutation> mutations; 46959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 47959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 48959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * The chance, out of 100, that this mutator actually mutates the the program 49959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * when asked to by the Program. The default is 50% chance, but each mutator that 50959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * extends CodeMutator should its own default. 51959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 52959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected int likelihood = 50; 53959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 54959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 55959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * This constructor is only intended for use in MutationRecorder... 56959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 57959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public CodeMutator() { 58959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 59959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 60959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 61959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 62959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Constructor that all subclasses must call... 63959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 64959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * @param rng The RNG that the Program created. 65959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 66959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public CodeMutator(Random rng, MutationStats stats, List<Mutation> mutations) { 67959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle this.rng = rng; 68959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle this.stats = stats; 69959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle this.mutations = mutations; 70959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 71959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle String name = this.getClass().getSimpleName().toLowerCase(); 72959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 73959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (Options.mutationLikelihoods.containsKey(name)) { 74959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle likelihood = Options.mutationLikelihoods.get(name); 75959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.info("Set mutation likelihood to " + likelihood 76959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle + "% for " + this.getClass().getSimpleName()); 77959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 78959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 79959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 80959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 81959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * When the Program picks a particular mutator to mutate the code, it calls 82959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * this function, that determines if the mutator will actually mutate the code. 83959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * If so, it then calls the mutationFunction() method, that every subclass CodeMutator 84959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * is expected to implement to perform its mutation. 85959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 86959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * @return If mutation took place. 87959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 88959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public boolean attemptToMutate(MutatableCode mutatableCode) { 89959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle if (shouldMutate(mutatableCode)) { 90959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle generateAndApplyMutation(mutatableCode); 91959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return true; 92959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 93959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.info("Skipping mutation."); 94959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return false; 95959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 96959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 97959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public void forceMutate(Mutation mutation) { 98959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Log.info("Forcing mutation."); 99959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle applyMutation(mutation); 100959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 101959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 102959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public boolean canBeTriggered() { 103959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return (likelihood > 0); 104959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 105959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 106959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 107959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * Randomly determine if the mutator will actually mutate a method, based on its 108959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * provided likelihood of mutation. 109959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * 110959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * @return If the method should be mutated. 111959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 112959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private boolean shouldMutate(MutatableCode mutatableCode) { 113959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return ((rng.nextInt(100) < likelihood) && canMutate(mutatableCode)); 114959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 115959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 116959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle private void generateAndApplyMutation(MutatableCode mutatableCode) { 117959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle Mutation mutation = generateMutation(mutatableCode); 118959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle // Always save the mutation. 119959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle mutations.add(mutation); 120959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle applyMutation(mutation); 121959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 122959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 123959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle /** 124959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * A CodeMutator must override this method if there is any reason why could not mutate 125959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle * a particular method, and return false in that case. 126959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle */ 127959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected boolean canMutate(MutatableCode mutatableCode) { 128959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle return true; 129959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle } 130959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 131959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected abstract Mutation generateMutation(MutatableCode mutatableCode); 132959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 133959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle protected abstract void applyMutation(Mutation uncastMutation); 134959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle 135959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle public abstract Mutation getNewMutation(); 136959ffdf65f280ee90b7944a8dd610564e7f99e69Stephen Kyle} 137