angr / angr

A powerful and user-friendly binary analysis platform!
http://angr.io
BSD 2-Clause "Simplified" License
7.46k stars 1.07k forks source link

Unable to figure out how to use the tracing exploration technique. #1207

Closed vrthra closed 5 years ago

vrthra commented 5 years ago

My program is as follows

import sys
import os
import time
import angr
import random
import claripy
import tracer

class Program:
    ARG_PREFIX = 'sym_arg'
    def __init__(self, exe):
        self.exe = exe
        self.project = angr.Project(exe, load_options={'auto_load_libs': False})

    def set_input(self, arg):
        self.arg1 = self.make_symbolic_char_args(arg)
        self.initial_state = self.project.factory.entry_state(
                args=[self.exe, self.arg1],
                remove_options=angr.options.simplification
                )
        self.constrain_input_chars(self.initial_state, self.arg1a, arg)
        self.string_terminate(self.initial_state, self.arg1a, arg)
        self.simgr = self.project.factory.simgr(self.initial_state)
        # I have also tried passing in input='' in case it is the stdin input.
        self.runner = tracer.QEMURunner(binary=self.exe, input=arg, project=self.project, argv=[self.exe, arg])
        self.simgr.use_technique(angr.exploration_techniques.Tracer(trace=self.runner.trace, dump_syscall=True))
        self.simgr.explore()

    def string_terminate(self, state, symarg, inarg):
        self.initial_state.preconstrainer.preconstrain(0, symarg[len(inarg)])

    def constrain_input_chars(self, state, symarg, sarg):
        for i,a in enumerate(sarg):
            self.initial_state.preconstrainer.preconstrain(a, symarg[i])

    def make_symbolic_char_args(self, instr, symbolic=True):
        if not symbolic: return instr
        input_len = len(instr)
        largs = range(0, input_len+1)
        arg1k = ['%s_%d' % (Program.ARG_PREFIX, i) for i in largs]
        self.arg1k8 = {i:'%s_%d_%d_8' % (Program.ARG_PREFIX, i,i) for i in largs}
        self.arg1h = {k:claripy.BVS(k, 8) for k in arg1k}
        self.arg1h_ = {self.arg1h[k].args[0]:k for k in arg1k}
        self.arg1a = [self.arg1h[k] for k in arg1k]
        return reduce(lambda x,y: x.concat(y), self.arg1a)

def main(exe, arg):
    prog = Program(exe)
    prog.set_input(arg)

if __name__ == '__main__':
    assert len(sys.argv) >= 3
    main(sys.argv[1], sys.argv[2])

and I am trying to trace a simple C program with concrete inputs

int main(int argc, char* argv[]) {
  char * arg  = argv[1];
  if (arg[0] == 'h') {
    if (arg[1] == 'e') {
      if (arg[2] == 'l') {
        return 0;
      } else {
        return 1;
      }
    } else {
      return 1;
    }
  } else {
    return 1;
  }
}

However, I get the error saying that dynamic trace and symbolic trace disagreed when executed

$ ./t hel
$ python src/main.py ./t hel              
WARNING | 2018-09-19 13:04:26,082 | angr.analyses.disassembly_utils | Your version of capstone does not support MIPS instruction groups.
WARNING | 2018-09-19 13:04:26,096 | tracer.qemu_runner | Unable to import shellphish_afl, multicb tracing will be disabled
WARNING | 2018-09-19 13:04:26,135 | cle.loader | The main binary is a position-independent executable. It is being loaded with a base address of 0x400000.
ERROR   | 2018-09-19 13:04:26,470 | angr.exploration_techniques.tracer | the dynamic trace and the symbolic trace disagreed
ERROR   | 2018-09-19 13:04:26,471 | angr.exploration_techniques.tracer | [./t] dynamic [0x40000004f0], symbolic [0x4004f0]
ERROR   | 2018-09-19 13:04:26,471 | angr.exploration_techniques.tracer | TracerMisfollowError encountered
WARNING | 2018-09-19 13:04:26,471 | angr.exploration_techniques.tracer | entering no follow mode

In particular, see where the dynamic and symbolic address disagreed: It seems that the loaded memory address is off.

What am I doing wrong? Any help would be appreciated.

vrthra commented 5 years ago

For any one else facing this issue, changing the custom_base_addr was what was needed. In my case, it was accomplished by

        self.project = angr.Project(exe, load_options={'auto_load_libs': False},
                main_opts={'custom_base_addr': 0x4000000000},
                )