summaryrefslogtreecommitdiffstats
path: root/tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java')
-rw-r--r--tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java136
1 files changed, 136 insertions, 0 deletions
diff --git a/tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java b/tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java
new file mode 100644
index 0000000..be566ad
--- /dev/null
+++ b/tools/dexfuzz/src/dexfuzz/program/mutators/CodeMutator.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dexfuzz.program.mutators;
+
+import dexfuzz.Log;
+import dexfuzz.MutationStats;
+import dexfuzz.Options;
+import dexfuzz.program.MutatableCode;
+import dexfuzz.program.Mutation;
+
+import java.util.List;
+import java.util.Random;
+
+/**
+ * The base class for all classes that can mutate methods.
+ */
+public abstract class CodeMutator {
+ /**
+ * The RNG, passed in by the Program that initialised us.
+ */
+ protected Random rng;
+
+ /**
+ * Used to track which mutations happen.
+ */
+ protected MutationStats stats;
+
+ /**
+ * Used to track mutations that have been applied so far.
+ */
+ protected List<Mutation> mutations;
+
+ /**
+ * The chance, out of 100, that this mutator actually mutates the the program
+ * when asked to by the Program. The default is 50% chance, but each mutator that
+ * extends CodeMutator should its own default.
+ */
+ protected int likelihood = 50;
+
+ /**
+ * This constructor is only intended for use in MutationRecorder...
+ */
+ public CodeMutator() {
+
+ }
+
+ /**
+ * Constructor that all subclasses must call...
+ *
+ * @param rng The RNG that the Program created.
+ */
+ public CodeMutator(Random rng, MutationStats stats, List<Mutation> mutations) {
+ this.rng = rng;
+ this.stats = stats;
+ this.mutations = mutations;
+
+ String name = this.getClass().getSimpleName().toLowerCase();
+
+ if (Options.mutationLikelihoods.containsKey(name)) {
+ likelihood = Options.mutationLikelihoods.get(name);
+ Log.info("Set mutation likelihood to " + likelihood
+ + "% for " + this.getClass().getSimpleName());
+ }
+ }
+
+ /**
+ * When the Program picks a particular mutator to mutate the code, it calls
+ * this function, that determines if the mutator will actually mutate the code.
+ * If so, it then calls the mutationFunction() method, that every subclass CodeMutator
+ * is expected to implement to perform its mutation.
+ *
+ * @return If mutation took place.
+ */
+ public boolean attemptToMutate(MutatableCode mutatableCode) {
+ if (shouldMutate(mutatableCode)) {
+ generateAndApplyMutation(mutatableCode);
+ return true;
+ }
+ Log.info("Skipping mutation.");
+ return false;
+ }
+
+ public void forceMutate(Mutation mutation) {
+ Log.info("Forcing mutation.");
+ applyMutation(mutation);
+ }
+
+ public boolean canBeTriggered() {
+ return (likelihood > 0);
+ }
+
+ /**
+ * Randomly determine if the mutator will actually mutate a method, based on its
+ * provided likelihood of mutation.
+ *
+ * @return If the method should be mutated.
+ */
+ private boolean shouldMutate(MutatableCode mutatableCode) {
+ return ((rng.nextInt(100) < likelihood) && canMutate(mutatableCode));
+ }
+
+ private void generateAndApplyMutation(MutatableCode mutatableCode) {
+ Mutation mutation = generateMutation(mutatableCode);
+ // Always save the mutation.
+ mutations.add(mutation);
+ applyMutation(mutation);
+ }
+
+ /**
+ * A CodeMutator must override this method if there is any reason why could not mutate
+ * a particular method, and return false in that case.
+ */
+ protected boolean canMutate(MutatableCode mutatableCode) {
+ return true;
+ }
+
+ protected abstract Mutation generateMutation(MutatableCode mutatableCode);
+
+ protected abstract void applyMutation(Mutation uncastMutation);
+
+ public abstract Mutation getNewMutation();
+}