diff --git a/fuzzer/Fuzzer.java b/fuzzer/Fuzzer.java index 57bf6b592b6bb4b7e688fde270c2b7da6c959dc5..1645354276ea61f70f061835551307209cf59536 100644 --- a/fuzzer/Fuzzer.java +++ b/fuzzer/Fuzzer.java @@ -4,6 +4,9 @@ import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; import java.util.Random; import java.util.Scanner; @@ -44,6 +47,12 @@ public class Fuzzer { private static int[] counts = {0,0,0,0,0,0,0,0,0,0,0,0}; // Instruction Added Probability Array private static int[] addProb = {0,0,0,0,0,0,0,0,0,0,0,0}; + // Pathway Prob Map, E.g. key = [PUSH, POP, STORE] - value = 2, this value is added to base prob + private static HashMap<List<Instruction>, Integer> pathwayProb = new HashMap<List<Instruction>, Integer>(); + // Current stack of instructions + private static ArrayList<Instruction> instructionStack = new ArrayList<Instruction>(); + // Max stack of instructions before resetting stack + private static final int MAX_STACK = 2; public static void main(String[] args) throws IOException { System.out.println(Instruction.getBNF()); @@ -113,13 +122,13 @@ public class Fuzzer { switch (runCount){ case 0: // Test with stack full - return generateInput(true, INSTRUCTION_MAX, MAX_STACK_SIZE, false, false); + return generateInput(true, INSTRUCTION_MAX, MAX_STACK_SIZE, true, false); case 1: // Test with stack full - return generateInput(true, INSTRUCTION_MAX, MAX_STACK_SIZE - 1, false, false); + return generateInput(true, INSTRUCTION_MAX, MAX_STACK_SIZE - 1, true, false); case 3: // Run static tests and empty stack - return getStaticTests() + generateInput(true, INSTRUCTION_MAX, 0, false, false); + return getStaticTests() + generateInput(true, INSTRUCTION_MAX, 0, true, false); case 4: // Test with dynamic probability return generateInput(true, INSTRUCTION_MAX, 0, true, false); @@ -128,7 +137,7 @@ public class Fuzzer { return generateInput(true, INSTRUCTION_MAX, 0, true, true); } // Run from random stack - return generateInput(true, INSTRUCTION_MAX, 0, false, false); + return generateInput(true, INSTRUCTION_MAX, 0, true, false); } /* @@ -167,6 +176,37 @@ public class Fuzzer { return result.toString(); } + private static void incrementStackAndCount(Instruction newInstruction) { + // Instruction values + Instruction allInstructions[] = Instruction.values(); + // Add base prob to stack with every other instruction + for (Instruction inst: allInstructions) { + if (!inst.equals(newInstruction)) { + List<Instruction> tempStack = new ArrayList<Instruction>(instructionStack); + tempStack.add(inst); + if (pathwayProb.containsKey(tempStack)) { + int oldProb = pathwayProb.get(tempStack); + pathwayProb.replace(tempStack, oldProb + inst.getProbability()); + } else { + pathwayProb.put(tempStack, inst.getProbability()); + } + } + } + // Add instruction to stack + instructionStack.add(newInstruction); + // Check if size is bigger than max stack, then reset stack + if (instructionStack.size() >= MAX_STACK) { + instructionStack.clear(); + } + System.out.println("stack: " + Arrays.toString(instructionStack.toArray())); + for (List<Instruction> list: pathwayProb.keySet()) { + String key = list.toString(); + String value = pathwayProb.get(list).toString(); + System.out.println("map: " + key + " " + value); + } + + } + /*** * Generates a line of input for the program * @@ -187,11 +227,11 @@ public class Fuzzer { if (correct) { while (counter < numInstructions) { - Instruction newInstr = Instruction.getRandomInstruction(stackSize, addProb); + Instruction newInstr = Instruction.getRandomInstruction(stackSize, instructionStack, pathwayProb); stackSize = stackSize + newInstr.getStackChange(); result.append(completeInstruction(true, newInstr, false)); if (dynamicProb) { - addCountProb(newInstr); + incrementStackAndCount(newInstr); } counter += 1; } @@ -199,16 +239,16 @@ public class Fuzzer { while (counter < numInstructions) { Instruction newInstr; if (rand.nextInt(100) < LINE_ERROR_PERCENTAGE){ - newInstr = Instruction.getRandomInstruction(2, addProb); + newInstr = Instruction.getRandomInstruction(2, instructionStack, pathwayProb); result.append(completeInstruction(false, newInstr, longVarNames)); if (dynamicProb) { - addCountProb(newInstr); + incrementStackAndCount(newInstr); } } else { - newInstr = Instruction.getRandomInstruction(stackSize, addProb); + newInstr = Instruction.getRandomInstruction(stackSize, instructionStack, pathwayProb); result.append(completeInstruction(true, newInstr, false)); if (dynamicProb) { - addCountProb(newInstr); + incrementStackAndCount(newInstr); } } stackSize = stackSize + newInstr.getStackChange(); diff --git a/fuzzer/Instruction.java b/fuzzer/Instruction.java index f4be61a027e6d723d66ab79510f9ddf43bf4d56d..fffc4f009bbbed11bb8541c26e14ea9ea203b6e8 100644 --- a/fuzzer/Instruction.java +++ b/fuzzer/Instruction.java @@ -82,9 +82,10 @@ public enum Instruction { // Returns a random instruction based on the stack size to prevent repeated // requests - public static Instruction getRandomInstruction(int max, int[] addProb) { + public static Instruction getRandomInstruction(int max, List<Instruction> instructionStack, + Map<List<Instruction>, Integer> pathwayProb) { // Check if cumlative probabilities have been calculated - checkProbability(addProb); + checkProbability(instructionStack, pathwayProb); ArrayList<Instruction> instructions; ArrayList<Integer> instCumlProbs; @@ -120,26 +121,35 @@ public enum Instruction { // Called before doing probability calculations to check if the clumulative // probabilities have been calculated - private static void checkProbability(int[] addProb) { + private static void checkProbability(List<Instruction> instructionStack, + Map<List<Instruction>, Integer> pathwayProb) { // Check if cumlative probabilities have been calculated. If not, do so. if (Instruction.ALL_MAX_CUML_PROB == 0) { Integer cumProb = 0; for (Instruction instruction : ALL_INSTRUCTIONS) { - cumProb += instruction.probability + addProb[instruction.ordinal()]; + // Temporary stack where we add this loop's instruction + List<Instruction> tempStack = new ArrayList<Instruction>(instructionStack); + tempStack.add(instruction); + // If the probability has increased, find it and add to base prob, otherwise 0 + int probToAdd = 0; + if (pathwayProb.containsKey(tempStack)) { + probToAdd = pathwayProb.get(tempStack); + } + cumProb += instruction.probability + probToAdd; ALL_CUML_PROB.add(cumProb); } ALL_MAX_CUML_PROB = cumProb; cumProb = 0; for (Instruction instruction : MAX_ZERO_INSTRUCTIONS) { - cumProb += instruction.probability + addProb[instruction.ordinal()]; + cumProb += instruction.probability; ZERO_CUML_PROB.add(cumProb); } ZERO_MAX_CUML_PROB = cumProb; cumProb = 0; for (Instruction instruction : MAX_ONE_INSTRUCTIONS) { - cumProb += instruction.probability + addProb[instruction.ordinal()]; + cumProb += instruction.probability; ONE_CUML_PROB.add(cumProb); } ONE_MAX_CUML_PROB = cumProb;