Select Git revision
Fuzzer.java
Forked from
Toby Murray / swen90006-a2-2018
63 commits ahead of the upstream repository.
Zhaolin Deng authored
Fuzzer.java 12.16 KiB
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
/* a stub for your team's fuzzer */
public class Fuzzer {
private static final String OUTPUT_FILE = "fuzz.s";
private static final List<String> validOpcodes = new ArrayList<String>(Arrays.asList("ADD","SUB","MUL","DIV","LDR","STR","MOV","JMP","JZ"));
private static final int maxRegistry = 32;
private static final int maxMemory = 65536;
private static final String alphabet = "1234567890-=`~!@#$%6&*()_+q wertyuiop[]QWERTYUIOP{}|asdfghjkl;ASDFGHJKL:zxcvbnm,./ZXCVBNM<>?\"\'\\";
public static void main(String[] args) throws IOException {
FileOutputStream out = null;
PrintWriter pw = null;
try {
out = new FileOutputStream(OUTPUT_FILE);
pw = new PrintWriter(out);
Random rg = new Random();
//----------Fuzzer Begins Here----------//
pw.println(generateMemoryUnderflow(rg));
//----------Fuzzer Ends Here----------
}catch (Exception e){
e.printStackTrace(System.err);
System.exit(1);
}finally{
if (pw != null){
pw.flush();
}
if (out != null){
out.close();
}
}
}
//-----------Generation Functions----------//
public static String generateMemoryOverflow(Random rg) {
String line = new String();
line.concat("MOV R0 "+maxMemory+"%n");
line.concat("MOV R1 1 %n");
if(rg.nextBoolean()) {
line.concat("LDR R0 R1 1");
} else {
line.concat("STR R0 R1 1");
}
return line;
}
public static String generateMemoryUnderflow(Random rg) {
String line = new String();
line.concat("MOV R0 "+(maxMemory*-1)+"%n");
line.concat("MOV R1 1 %n");
if(rg.nextBoolean()) {
line.concat("LDR R0 R1 -1");
} else {
line.concat("STR R0 R1 -1");
}
return line;
}
public static String generateRegOverflow(Random rg) {
String line = new String();
int invalidRegistry;
Boolean overflow = rg.nextBoolean(); if(overflow) {
invalidRegistry = 32;
}
else {
invalidRegistry = -1;
}
int goodRegA;
int goodRegB;
int pos;
int val;
switch(rg.nextInt(7)){
case(0):
goodRegA = rg.nextInt(maxRegistry);
goodRegB = rg.nextInt(maxRegistry);
line.concat("ADD ");
pos = rg.nextInt(3);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" R"+goodRegA+" R"+goodRegB);
break;
case(1):
line.concat("R"+goodRegA+" R"+invalidRegistry+" R"+goodRegB);
break;
case(2):
line.concat("R"+goodRegB+" R"+goodRegA+" R"+invalidRegistry);
break;
}
return line;
case(1):
goodRegA = rg.nextInt(maxRegistry);
goodRegB = rg.nextInt(maxRegistry);
line.concat("SUB ");
pos = rg.nextInt(3);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" R"+goodRegA+" R"+goodRegB);
break;
case(1):
line.concat("R"+goodRegA+" R"+invalidRegistry+" R"+goodRegB);
break;
case(2):
line.concat("R"+goodRegB+" R"+goodRegA+" R"+invalidRegistry);
break;
}
return line;
case(2):
goodRegA = rg.nextInt(maxRegistry);
goodRegB = rg.nextInt(maxRegistry);
line.concat("MOV R"+goodRegB+" 1%n");
line.concat("DIV ");
pos = rg.nextInt(3);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" R"+goodRegA+" R"+goodRegB);
break;
case(1):
line.concat("R"+goodRegA+" R"+invalidRegistry+" R"+goodRegB);
break;
case(2):
line.concat("R"+goodRegB+" R"+goodRegA+" R"+invalidRegistry);
break;
}
return line;
case(3):
goodRegA = rg.nextInt(maxRegistry);
goodRegB = rg.nextInt(maxRegistry);
line.concat("MUL "); pos = rg.nextInt(3);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" R"+goodRegA+" R"+goodRegB);
break;
case(1):
line.concat("R"+goodRegA+" R"+invalidRegistry+" R"+goodRegB);
break;
case(2):
line.concat("R"+goodRegB+" R"+goodRegA+" R"+invalidRegistry);
break;
}
return line;
case(4):
line.concat("LDR ");
goodRegA = rg.nextInt(maxRegistry);
pos = rg.nextInt(2);
val = rg.nextInt(maxMemory);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" "+val+"R"+goodRegA);
break;
case(1):
line.concat("R"+goodRegA+" "+val+"R"+invalidRegistry);
break;
}
return line;
case(5):
line.concat("STR ");
goodRegA = rg.nextInt(maxRegistry);
pos = rg.nextInt(2);
val = rg.nextInt(maxMemory);
switch(pos) {
case(0):
line.concat("R"+invalidRegistry+" "+val+"R"+goodRegA);
break;
case(1):
line.concat("R"+goodRegA+" "+val+"R"+invalidRegistry);
break;
}
return line;
case(6):
line.concat("MOV ");
goodRegA = rg.nextInt(maxRegistry);
val = rg.nextInt(maxMemory);
line.concat("R"+invalidRegistry+" "+val);
return line;
}
return line;
}
public static String generateOffsetOverFlow(Random rg) {
String line = new String();
Boolean positive = rg.nextBoolean();
if(!positive) {
line.concat("MOV R0 -70000");
}else {
line.concat("MOV R0 70000");
}
return line;
}
public static String generateLineOverFlow() {
String line = new String();
line.concat("RET R0");
for(int x=0;x<2000;x++) {
line.concat("a");
}
return line; }
public static String generateInstructionOverflow() {
String line = new String();
line.concat("MOV R0 0%n");
line.concat("MOV R1 1");
for(int x=0;x<70000;x++) {
line.concat("%nADD R0 R0 R1");
}
return line;
}
public static String generateDivideByZero(){
String line = new String();
line.concat("MOV R0 0%n");
line.concat("MOV R1 1%n");
line.concat("DIV R2 R1 R0%n");
line.concat("RET R2");
return line;
}
public static String generateDirtyRegistyRead() {
String line = new String();
for(int x=1;x<maxRegistry-1;x++) {
line.concat("ADD R0 R0 R"+x+"%n");
}
line.concat("RET R0");
return line;
}
public static String generateDirtyMemoryRead(Random rg) {
String line = new String();
int attempts = 20;
line.concat("MOV R0 0");
for(int x=0;x<attempts;x++) {
int value = rg.nextInt(maxMemory);
if(rg.nextBoolean()) {
value = value*-1;
}
line.concat("%nLDR R0 "+value+" R1%n");
line.concat("ADD R2 R2 R1%n");
}
return line;
}
public static String jmpOverflow(int programLength,int lineNumber,Random rg) {
String line = new String();
int val;
if(rg.nextBoolean()) {
val = -1*(lineNumber+2);
} else {
val = (programLength-lineNumber+1);
}
line.concat("JMP "+val);
return line;
}
public static String jzOverflow(int programLength,int lineNumber,Random rg) {
String line = new String();
int val;
if(rg.nextBoolean()) {
val = -1*(lineNumber+2);
} else {
val = (programLength-lineNumber+2);
}
line.concat("MOV R0 0%n");
line.concat("JZ R0 "+val);
return line; }
public static String intOverflow() {
String line = new String();
line.concat("MOV R0 65535%n");
line.concat("MUL R1 R0 R0%n");
line.concat("MUL R1 R0 R0");
return line;
}
public static String intUnderflow() {
String line = new String();
line.concat("MOV R0 -65535%n");
line.concat("MUL R1 R0 R0%n");
line.concat("MUL R1 R0 R0");
return line;
}
public static String generateInvalidOperands(Random rg) {
int regs = rg.nextInt(4);
String line = new String();
Boolean hasval = rg.nextBoolean();
int index = rg.nextInt(validOpcodes.size());
String opcode = validOpcodes.get(index);
line.concat(opcode);
for(int x=0;x<regs;x++) {
int register = rg.nextInt(maxRegistry);
line.concat(" R"+register);
}
if(hasval) {
int value=rg.nextInt(maxMemory);
line.concat(" "+value);
}
//too many arguments
return null;
}
public static String generateInvalidFunctionName(Random rg,String line) {
char[] charLine = line.toCharArray();
int change = rg.nextInt(3)+1;
for(int x=0;x<change;x++) {
int index = rg.nextInt(charLine.length);
char character = alphabet.charAt(rg.nextInt(alphabet.length()));
charLine[index] = character;
}
return charLine.toString();
}
public static String generateInstructionComment(Random rg) {
String line = new String();
line.concat(";");
String instr = generateValidReturn(rg);
line.concat(instr);
return line;
}
public static String generateValidReturn(Random rg) {
String line = new String();
line.concat("RET");
line.concat(" R"+rg.nextInt(maxRegistry));
return line;
}
public static String generateInvalidReturn(Random rg) {
int invalidRegistry;
String line = new String();
line.concat("RET");
Boolean overflow = rg.nextBoolean(); if(overflow) {
invalidRegistry = 32;
}
else {
invalidRegistry = -1;
}
line.concat(" R"+invalidRegistry);
return line;
}
public static String generateValidString(Random rg,int programLength,int lineNumber){
int index = rg.nextInt(validOpcodes.size());
String opcode = validOpcodes.get(index);
int numregs = 0;
Integer offset = null;
String line = new String();
switch(opcode){
case("ADD"):
numregs = 3;
break;
case("SUB"):
numregs = 3;
break;
case("MUL"):
numregs = 3;
break;
case("DIV"):
numregs = 3;
break;
case("LDR"):
numregs = 2;
offset = (rg.nextInt(2*maxMemory))-maxMemory;
break;
case("STR"):
//special case - form <REGISTER VALUE REGISTER>
offset = (rg.nextInt(2*maxMemory))-maxMemory;
line.concat(opcode);
line.concat(" R"+rg.nextInt(maxRegistry));
line.concat(" "+offset);
line.concat(" R"+rg.nextInt(maxRegistry));
return line;
case("MOV"):
numregs = 1;
offset = rg.nextInt();
Boolean positive = rg.nextBoolean();
if(!positive) {
offset = -offset;
}
break;
case("JMP"):
//special case - avoid looping infinitly
numregs = 0;
offset = (rg.nextInt(programLength));
offset = offset - lineNumber;
if(offset<0) {
offset = offset-1;
line.concat("JMP 2%n");
} else if(offset == 0) {
offset = offset+1;
}
break;
case("JZ"):
//special case - avoid looping infinitly
numregs = 1;
offset = (rg.nextInt(programLength));
offset = offset - lineNumber;
if(offset<0) {
offset = offset-2; line.concat("JMP 2%n");
} else if(offset == 0) {
offset = offset+1;
}
break;
}
line.concat(opcode);
int x;
for(x=0;x<numregs;x++){
line.concat(" R"+rg.nextInt(maxRegistry));
}
if(offset!=null){
line.concat(" "+offset);
}
return line;
}
}