Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# brute force...
if self.format_spec_char is None:
second_str = "findme"
for char in possible_format_specifiers:
if self.format_spec_char is not None:
break
for cc in string.ascii_lowercase:
if cc in possible_formats:
continue
test_str = char + cc + "\n\x00"
test_input = [1, test_str, second_str]
test_output = [None, test_str, second_str]
stdout = second_str + "\n"
max_steps = 10
test = TestData(test_input, test_output, None, max_steps, expected_stdout=stdout)
if runner.test(func, test):
self.format_spec_char = char
self.string_spec_char = cc
break
if self.format_spec_char is None:
l.warning("format spec is none :(")
return False
return True
def do_pretests(self, func, runner):
test_input = [0, "A"*0x100, ord("X"), 40]
stdin = "a"*10 + "X" + "b"*10
max_len = 10
max_steps = max_len * 8 + 20
# prefilter
test_output = [None, "a"*10, None, None]
return_val = None
test = TestData(test_input, test_output, return_val, max_steps, stdin)
if not self.run_test(func, runner, test):
return False
# version checks
test_output = [None, "a"*10 + "\x00", None, None]
return_val = 10
test = TestData(test_input, test_output, return_val, max_steps, stdin)
null_replace_not_counted = self.run_test(func, runner, test)
test_output = [None, "a"*10 + "\x00", None, None]
return_val = 11
test = TestData(test_input, test_output, return_val, max_steps, stdin)
null_replace_counted = self.run_test(func, runner, test)
if not (null_replace_counted or null_replace_not_counted):
return False
def pre_test(self, func, runner):
# todo we don't test which order it returns the signs in
l = random.randint(1, 20)
bufb = rand_str(l)
bufa = bufb + rand_str(5)
test_input = [bufa, bufb, l]
test_output = [bufa, bufb, l]
max_steps = 10
return_val = None
test = TestData(test_input, test_output, return_val, max_steps)
s = runner.get_out_state(func, test)
if s is None or s.se.eval(s.regs.eax) != 0:
return False
bufa = "asd\x00a"
bufb = "asd\x00a"
test_input = [bufa, bufb, 5]
test_output = [bufa, bufb, 5]
test = TestData(test_input, test_output, return_val, max_steps)
x = runner.get_out_state(func, test)
if x is None:
return False
outval1 = x.se.eval(x.regs.eax)
bufa = "asd\x00c"
bufb = "asd\x00b"
if len(possible_format_specifiers) > 10:
# too many to test :(
return False
# find the format specifier
second_str = "findme"
for char in possible_format_specifiers:
if self.format_spec_char is not None:
break
for cc in possible_formats:
test_str = char + cc + "\n\x00"
test_input = [outbuf, test_str, second_str]
test_output = [second_str + "\n" + "\x00", test_str, second_str]
max_steps = 20
test = TestData(test_input, test_output, None, max_steps)
if runner.test(func, test):
self.format_spec_char = char
self.string_spec_char = cc
break
# brute force...
if self.format_spec_char is None:
second_str = "findme"
for char in possible_format_specifiers:
if self.format_spec_char is not None:
break
for cc in string.ascii_lowercase:
if cc in possible_formats:
continue
test_str = char + cc + "\n\x00"
test_input = [outbuf, test_str, second_str]
def pre_test(self, func, runner):
# make sure it prints alphanumeric stuff
length = 10
test_str = self.rand_str(length, string.ascii_letters + string.digits)
test_input = [1, test_str]
test_output = [None, test_str]
max_steps = len(test_str) * 3 + 20
stdout = test_str
test = TestData(test_input, test_output, None, max_steps, expected_stdout=stdout)
if not runner.test(func, test):
return False
# find interesting characters
test_input = [1, claripy.BVS("input", 10*8)]
test_output = [None, None]
test = TestData(test_input, test_output, None, max_steps)
s = runner.get_base_call_state(func, test)
pg = runner.project.factory.simulation_manager(s)
pg.run(n=18)
interesting_chars = set()
for p in pg.active:
for g in p.history.jump_guards:
if g.op == "__ne__" or g.op == "__eq__":
for a in g.args:
if not a.symbolic:
if len(possible_format_specifiers) > 10:
# too many to test :(
return False
# find the format specifier
second_str = "findme"
for char in possible_format_specifiers:
if self.format_spec_char is not None:
break
for cc in possible_formats:
test_str = char + cc + "\n\x00"
test_input = [test_str, second_str]
test_output = [test_str, second_str]
stdout = second_str + "\n"
max_steps = 20
test = TestData(test_input, test_output, None, max_steps, expected_stdout=stdout)
if runner.test(func, test):
self.format_spec_char = char
self.string_spec_char = cc
break
# brute force...
if self.format_spec_char is None:
second_str = "findme"
for char in possible_format_specifiers:
if self.format_spec_char is not None:
break
for cc in string.ascii_lowercase:
if cc in possible_formats:
continue
test_str = char + cc + "\n\x00"
test_input = [test_str, second_str]
test_input = ["A"*15, 15, num]
test_output = [s, None, None]
return_val = None
max_steps = 10
test = TestData(test_input, test_output, return_val, max_steps)
if not runner.test(func, test):
return False
num = random.randint(-(2 ** 26), 2 ** 26 - 1)
num = -abs(num)
s = str(num)
test_input = ["A"*15, 15, num]
test_output = [s, None, None]
return_val = None
max_steps = 10
test = TestData(test_input, test_output, return_val, max_steps)
if not runner.test(func, test):
self.is_signed = False
else:
self.is_signed = True
return True
test_input = ["A"*0x100, ord("X"), 40]
stdin = "a"*10 + "X" + "b"*10
max_len = 10
max_steps = max_len * 8 + 20
# prefilter
test_output = ["a"*10, None, None]
return_val = None
test = TestData(test_input, test_output, return_val, max_steps, stdin)
if not self.run_test(func, runner, test):
return False
# check for has return
test_output = ["a"*10, None, None]
return_val = 10
test1 = TestData(test_input, test_output, return_val, max_steps, stdin)
return_val = 11
test2 = TestData(test_input, test_output, return_val, max_steps, stdin)
if not (self.run_test(func, runner, test1) or self.run_test(func, runner, test2)):
self.has_return = False
# version checks
test_output = ["a"*10 + "\x00", None, None]
return_val = 10
test = TestData(test_input, test_output, return_val, max_steps, stdin)
null_replace_not_counted = self.run_test(func, runner, test)
test_output = ["a"*10 + "\x00", None, None]
return_val = 11
test = TestData(test_input, test_output, return_val, max_steps, stdin)
null_replace_counted = self.run_test(func, runner, test)
def gen_input_output_pair(self):
# TODO we don't check the return val, some cases I saw char * strcpy, some size_t strcpy
strlen = random.randint(1, 80)
buf = rand_str(strlen, byte_list=strcpy.non_null) + "\x00"
result_buf = rand_str(strlen+1)
test_input = [result_buf, buf]
test_output = [buf, buf]
max_steps = 20
return_val = None
test = TestData(test_input, test_output, return_val, max_steps)
return test
malloc_vals = []
state = None
for i in range(10): #pylint disable=unused-variable
state = runner.get_out_state(malloc, malloc_test, initial_state=state)
if state is None:
l.critical("malloc failed")
raise IdentifierException("malloc failed")
malloc_vals.append(state.solver.eval(state.regs.eax))
if malloc_vals[-1] < 0x10000:
return False
test_input = [malloc_vals[-1]]
test_output = [None]
return_val = None
state.memory.store(malloc_vals[-1], state.solver.BVS("some_data", 0x80*8))
free_test = TestData(test_input, test_output, return_val, max_steps)
state = runner.get_out_state(func, free_test, initial_state=state)
if state is None:
return False
if len(malloc_vals) == len(set(malloc_vals)):
return False
return True