diff options
| -rw-r--r-- | tools/dexfuzz/src/dexfuzz/DexFuzz.java | 4 | ||||
| -rw-r--r-- | tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java | 28 |
2 files changed, 28 insertions, 4 deletions
diff --git a/tools/dexfuzz/src/dexfuzz/DexFuzz.java b/tools/dexfuzz/src/dexfuzz/DexFuzz.java index d37bd34016..b0ce5a857e 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.5: added register clobber mutator. + // Last version update 1.6: added temporary register to ArrayLengthChanger. private static int majorVersion = 1; - private static int minorVersion = 5; + private static int minorVersion = 6; private static int seedChangeVersion = 0; /** diff --git a/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java b/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java index aba7971b48..e640b4e2ef 100644 --- a/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java +++ b/tools/dexfuzz/src/dexfuzz/program/mutators/NewArrayLengthChanger.java @@ -28,8 +28,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; -// This mutation might change the length of an array but can also change the -// value of the register in every place it is used. public class NewArrayLengthChanger extends CodeMutator { /** * Every CodeMutator has an AssociatedMutation, representing the @@ -116,20 +114,46 @@ public class NewArrayLengthChanger extends CodeMutator { MutatableCode mutatableCode = mutation.mutatableCode; MInsn newArrayInsn = newArrayLengthInsns.get(mutation.newArrayToChangeIdx); int newArrayInsnIdx = mutatableCode.getInstructionIndex(newArrayInsn); + // If the original new-array instruction is no longer present + // in the code (as indicated by a negative index), we make a + // best effort to find any other new-array instruction to + // apply the mutation to. If that effort fails, we simply + // bail by doing nothing. + if (newArrayInsnIdx < 0) { + newArrayInsnIdx = scanNewArray(mutatableCode); + if (newArrayInsnIdx == -1) { + return; + } + } MInsn newInsn = new MInsn(); newInsn.insn = new Instruction(); newInsn.insn.info = Instruction.getOpcodeInfo(Opcode.CONST_16); + mutatableCode.allocateTemporaryVRegs(1); + newArrayInsn.insn.vregB = mutatableCode.getTemporaryVReg(0); newInsn.insn.vregA = (int) newArrayInsn.insn.vregB; // New length chosen randomly between 1 to 100. newInsn.insn.vregB = rng.nextInt(100); mutatableCode.insertInstructionAt(newInsn, newArrayInsnIdx); Log.info("Changed the length of the array to " + newInsn.insn.vregB); stats.incrementStat("Changed length of new array"); + mutatableCode.finishedUsingTemporaryVRegs(); } private boolean isNewArray(MInsn mInsn) { Opcode opcode = mInsn.insn.info.opcode; return opcode == Opcode.NEW_ARRAY; } + + // Return the index of first new-array in the method, -1 otherwise. + private int scanNewArray(MutatableCode mutatableCode) { + int idx = 0; + for (MInsn mInsn : mutatableCode.getInstructions()) { + if (isNewArray(mInsn)) { + return idx; + } + idx++; + } + return -1; + } }
\ No newline at end of file |