diff options
| -rw-r--r-- | tools/dexfuzz/README | 1 | ||||
| -rw-r--r-- | tools/dexfuzz/src/dexfuzz/DexFuzz.java | 4 | ||||
| -rw-r--r-- | tools/dexfuzz/src/dexfuzz/program/Program.java | 2 | ||||
| -rw-r--r-- | tools/dexfuzz/src/dexfuzz/program/mutators/RegisterClobber.java | 101 |
4 files changed, 106 insertions, 2 deletions
diff --git a/tools/dexfuzz/README b/tools/dexfuzz/README index 271ac2bd85..a635fe9928 100644 --- a/tools/dexfuzz/README +++ b/tools/dexfuzz/README @@ -145,6 +145,7 @@ OppositeBranchChanger 40 PoolIndexChanger 30 RandomBranchChanger 30 RandomInstructionGenerator 30 +RegisterClobber 40 SwitchBranchShifter 30 TryBlockShifter 40 ValuePrinter 40 diff --git a/tools/dexfuzz/src/dexfuzz/DexFuzz.java b/tools/dexfuzz/src/dexfuzz/DexFuzz.java index d7a5325cb5..d37bd34016 100644 --- a/tools/dexfuzz/src/dexfuzz/DexFuzz.java +++ b/tools/dexfuzz/src/dexfuzz/DexFuzz.java @@ -33,9 +33,9 @@ import dexfuzz.listeners.UpdatingConsoleListener; * Entrypoint class for dexfuzz. */ public class DexFuzz { - // Last version update 1.4: added array length mutator. + // Last version update 1.5: added register clobber mutator. private static int majorVersion = 1; - private static int minorVersion = 4; + private static int minorVersion = 5; private static int seedChangeVersion = 0; /** diff --git a/tools/dexfuzz/src/dexfuzz/program/Program.java b/tools/dexfuzz/src/dexfuzz/program/Program.java index b0a06fc749..bb2f4c059d 100644 --- a/tools/dexfuzz/src/dexfuzz/program/Program.java +++ b/tools/dexfuzz/src/dexfuzz/program/Program.java @@ -38,6 +38,7 @@ import dexfuzz.program.mutators.OppositeBranchChanger; import dexfuzz.program.mutators.PoolIndexChanger; import dexfuzz.program.mutators.RandomBranchChanger; import dexfuzz.program.mutators.RandomInstructionGenerator; +import dexfuzz.program.mutators.RegisterClobber; import dexfuzz.program.mutators.SwitchBranchShifter; import dexfuzz.program.mutators.TryBlockShifter; import dexfuzz.program.mutators.ValuePrinter; @@ -209,6 +210,7 @@ public class Program { registerMutator(new PoolIndexChanger(rng, mutationStats, mutations)); registerMutator(new RandomBranchChanger(rng, mutationStats, mutations)); registerMutator(new RandomInstructionGenerator(rng, mutationStats, mutations)); + registerMutator(new RegisterClobber(rng, mutationStats, mutations)); registerMutator(new SwitchBranchShifter(rng, mutationStats, mutations)); registerMutator(new TryBlockShifter(rng, mutationStats, mutations)); registerMutator(new ValuePrinter(rng, mutationStats, mutations)); diff --git a/tools/dexfuzz/src/dexfuzz/program/mutators/RegisterClobber.java b/tools/dexfuzz/src/dexfuzz/program/mutators/RegisterClobber.java new file mode 100644 index 0000000000..11da1d4d39 --- /dev/null +++ b/tools/dexfuzz/src/dexfuzz/program/mutators/RegisterClobber.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2017 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.program.MInsn; +import dexfuzz.program.MutatableCode; +import dexfuzz.program.Mutation; +import dexfuzz.rawdex.Instruction; +import dexfuzz.rawdex.Opcode; + +import java.util.List; +import java.util.Random; + +public class RegisterClobber extends CodeMutator{ + + /** + * Every CodeMutator has an AssociatedMutation, representing the + * mutation that this CodeMutator can perform, to allow separate + * generateMutation() and applyMutation() phases, allowing serialization. + */ + public static class AssociatedMutation extends Mutation{ + + int regClobberIdx; + + @Override + public String getString() { + return Integer.toString(regClobberIdx); + } + + @Override + public void parseString(String[] elements) { + Integer.parseInt(elements[2]); + } + } + + // The following two methods are here for the benefit of MutationSerializer, + // so it can create a CodeMutator and get the correct associated Mutation, as it + // reads in mutations from a dump of mutations. + @Override + public Mutation getNewMutation() { + return new AssociatedMutation(); + } + + public RegisterClobber() {} + + public RegisterClobber(Random rng, MutationStats stats, List<Mutation> mutations) { + super(rng, stats, mutations); + likelihood = 40; + } + + @Override + protected boolean canMutate(MutatableCode mutatableCode) { + return mutatableCode.registersSize > 0; + } + + @Override + protected Mutation generateMutation(MutatableCode mutatableCode) { + int insertionIdx = rng.nextInt(mutatableCode.getInstructionCount()); + + AssociatedMutation mutation = new AssociatedMutation(); + mutation.setup(this.getClass(), mutatableCode); + mutation.regClobberIdx = insertionIdx; + return mutation; + } + + @Override + protected void applyMutation(Mutation uncastMutation) { + AssociatedMutation mutation = (AssociatedMutation) uncastMutation; + MutatableCode mutatableCode = mutation.mutatableCode; + + int totalRegUsed = mutatableCode.registersSize; + for (int i = 0; i < totalRegUsed; i++) { + MInsn newInsn = new MInsn(); + newInsn.insn = new Instruction(); + newInsn.insn.info = Instruction.getOpcodeInfo(Opcode.CONST_16); + newInsn.insn.vregA = i; + newInsn.insn.vregB = 0; + mutatableCode.insertInstructionAt(newInsn, mutation.regClobberIdx + i); + } + + Log.info("Assigned zero to the registers from 0 to " + (totalRegUsed - 1) + + " at index " + mutation.regClobberIdx); + stats.incrementStat("Clobbered the registers"); + } +}
\ No newline at end of file |