Skip to content

Commit

Permalink
append each input with its generation method
Browse files Browse the repository at this point in the history
  • Loading branch information
DonggeLiu committed Apr 2, 2020
1 parent 176ac1e commit 31f1b6e
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions Legion.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def mutate(self):
return results
return self.random_fuzzing()

def app_fuzzing(self) -> List[bytes]:
def app_fuzzing(self) -> List[Tuple[bytes, str]]:
def byte_len() -> int:
"""
The number of bytes in the input
Expand All @@ -388,6 +388,9 @@ def byte_len() -> int:
self.fully_explored = True
return results

# Denotes the generation method for each input
# S: constraint solving; F: fuzzing; R: random generation
method = "S"
while len(results) < MAX_SAMPLES:
try:
val = next(self.samples)
Expand All @@ -396,9 +399,11 @@ def byte_len() -> int:
break
if val is None and len(results) < MIN_SAMPLES:
# requires constraint solving but not enough results
method = "S"
continue
result = val.to_bytes(byte_len(), 'big')
result = (val.to_bytes(byte_len(), 'big'), method)
results.append(result)
method = "F"
except StopIteration:
# NOTE: Insufficient results from APPFuzzing:
# Case 1: break in the outside while:
Expand Down Expand Up @@ -440,7 +445,7 @@ def byte_len() -> int:
return results

@staticmethod
def random_fuzzing() -> List[bytes]:
def random_fuzzing() -> List[Tuple[bytes, str]]:
def random_bytes():
LOGGER.debug("Generating random {} bytes".format(MAX_BYTES))
# input_bytes = b''
Expand All @@ -449,7 +454,7 @@ def random_bytes():
# return input_bytes
# Or return end of file char?
return os.urandom(MAX_BYTES)
return [random_bytes() for _ in range(MIN_SAMPLES)]
return [(random_bytes(), "R") for _ in range(MIN_SAMPLES)]

def add_child(self, key: str or int, new_child: 'TreeNode') -> None:
debug_assertion((key == 'Simulation') ^ (key == new_child.addr))
Expand Down Expand Up @@ -1006,12 +1011,12 @@ def simulation(node: TreeNode = None) -> List[List[int]]:

global FOUND_BUG, MSGS, INPUTS, TIMES
mutants = node.mutate() if node else \
[bytes("".join(mutant), 'utf-8')
[(bytes("".join(mutant), 'utf-8'), "D")
# Note: Need to make sure the first binary execution must complete successfully
# Otherwise (e.g. timeout) the root address will be wrong
for mutant in SEEDS] if SEEDS else ([b'\x00'*MAX_BYTES]
+ [b'\x01\x00\x00\x00'*(MAX_BYTES//4)]
+ [b'\x0a'] + TreeNode.random_fuzzing())
for mutant in SEEDS] if SEEDS else ([(b'\x00'*MAX_BYTES, "D")]
+ [(b'\x01\x00\x00\x00'*(MAX_BYTES//4), "D")]
+ [(b'\x0a', "D")] + TreeNode.random_fuzzing())
# for mutant in SEEDS] if SEEDS else [b'\x0a']
# for mutant in SEEDS] if SEEDS else TreeNode.random_fuzzing()

Expand All @@ -1032,7 +1037,7 @@ def simulation(node: TreeNode = None) -> List[List[int]]:
return traces


def binary_execute_parallel(input_bytes: bytes):
def binary_execute_parallel(input_bytes: Tuple[bytes, str]):
"""
Execute the binary with an input in bytes
:param input_bytes: the input to feed the binary
Expand All @@ -1052,7 +1057,7 @@ def execute():
# 0: no timeout; 1: instrumented binary timeout; 2: uninstrumented binary timeout
timeout = False
try:
msg = instr.communicate(input_bytes, timeout=CONEX_TIMEOUT)
msg = instr.communicate(input_bytes[0], timeout=CONEX_TIMEOUT)
ret = instr.returncode
instr.terminate()
del instr
Expand All @@ -1069,7 +1074,7 @@ def execute():
try:
uninstr = sp.Popen(UNINSTR_BIN, stdin=sp.PIPE, stdout=sp.PIPE,
stderr=sp.PIPE, close_fds=True)
msg = uninstr.communicate(input_bytes, timeout=CONEX_TIMEOUT)
msg = uninstr.communicate(input_bytes[0], timeout=CONEX_TIMEOUT)
ret = uninstr.returncode
LOGGER.info("Uninstrumented binary execution completed")
uninstr.terminate()
Expand All @@ -1088,16 +1093,15 @@ def execute():
debug_assertion(bool(report))

report_msg, return_code, time_out = report

completed = report != (None, None)
completed = report != (None, None, True)
traced = completed and report_msg[1]
found_bug = False

if (SAVE_TESTCASES or SAVE_TESTINPUTS) and completed:
curr_time = time.time() - TIME_START
if SAVE_TESTCASES and (not time_out or SAVE_TESTCASES_TIMEOUT):
stdout = report_msg[0].decode('utf-8')
save_tests_to_file(curr_time, stdout, ("-T" if time_out else "-C"))
save_tests_to_file(curr_time, stdout, ("-T" if time_out else "-C")+("-"+input_bytes[1]))
if SAVE_TESTINPUTS:
save_input_to_file(curr_time, input_bytes)

Expand Down

0 comments on commit 31f1b6e

Please sign in to comment.