как применить ограничения к побочным эффектам кучи в angr

#python #reverse-engineering #symbolic-execution #angr

Вопрос:

Я пытаюсь использовать angr для проверки поведения функции путем получения правильного ввода для заданного результата. Функция изменяет буфер, в этом случае она просто копирует в него входные данные, поэтому я настраиваю символьные переменные в куче, к которым применяю ограничение равенства. Затем я создаю символьную переменную для ввода в функцию. Я намеревался сделать так, чтобы angr по существу запускал функцию до тех пор, пока входные данные не будут найдены таким образом, чтобы при их копировании в буфер они удовлетворяли наложенному на них ограничению. Однако, когда он запускается, я получаю только одну заблокированную ветвь, где вывод имеет правильное значение, а ввод-нет. Я прикрепил решатель и исходный код тестовой программы ниже. Является ли это провалом моей реализации? Или такой подход к решению проблемы недействителен

решатель

 import angr import claripy import angr.sim_type as T  if __name__ == '__main__':  path = './test'  target = 'test_fn'   target_buf = 'buffer'     word = b'hello'    program = angr.Project(path)  fn = program.loader.find_symbol(target)  buf = program.loader.find_symbol(target_buf)   fn_addr = fn.rebased_addr  buf_addr = buf.rebased_addr   cc = program.factory.cc(func_ty=T.SimTypeFunction(  args=[T.parse_type('char*')],  returnty=T.parse_type('void')  ))   str_in = claripy.BVS('input', 8 * len(word))  fn_call_state = program.factory.call_state(fn_addr, angr.calling_conventions.PointerWrapper(str_in), cc=cc)  ptr_out = fn_call_state.heap.allocate(len(word))   chars = []  for i, v in enumerate(word):  ch = claripy.BVS('char_{}'.format(i), 8)  chars.append(ch)  fn_call_state.solver.add(ch == int(v))  word_sym = claripy.Concat(*chars)  fn_call_state.memory.store(buf_addr, ptr_out)  fn_call_state.memory.store(ptr_out, word_sym)   simgr = program.factory.simgr(fn_call_state, save_unsat=True)  simgr.run()  print(simgr)  for s in simgr.deadended:  print(s.solver.eval(str_in, cast_to=bytes))  print(s.solver.eval(word_sym, cast_to=bytes))   

программа тестирования

 #include lt;string.hgt; #include lt;stdlib.hgt; #include lt;stdio.hgt;  char* buffer;  void test_fn(char* input) {  strcpy(buffer, input);  return; }  int main(int argc, char** argv) {  buffer = (char*) malloc(100);  test_fn("hello"); }   

когда я запускаю решатель, я получаю вывод, подобный следующему, хотя первое значение, входное значение, изменяется, по-видимому, случайным образом. ЕСТЬ ли способ применить это ограничение, чтобы побочные эффекты программы имели приоритет? Я не понимаю, как эти две ценности могут отличаться. Является ли это ошибкой в том, как я готовлю память?

 b'x01x01x01x04x01x02' b'hellox00'