Пример #1
0
    def run(self, dst_addr, src_addr, limit, src_len=None):
        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString()),
            2: SimTypeLength(self.state.arch)
        }
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        memcpy = simuvex.SimProcedures['libc.so.6']['memcpy']

        src_len = src_len if src_len is not None else self.inline_call(
            strlen, src_addr)
        cpy_size = self.state.se.If(
            self.state.se.ULE(limit, src_len.ret_expr + 1), limit,
            src_len.ret_expr + 1)

        #print "==================="
        #print sorted(self.state.expr_value(src_len.ret_expr).se.any_n(20))
        #print self.state.expr_value(limit.expr).se.any_n(20)
        #print sorted(self.state.expr_value(cpy_size).se.any_n(20))
        #print "-------------------"

        self.inline_call(memcpy, dst_addr, src_addr, cpy_size)
        return dst_addr
Пример #2
0
    def run(self, scan, fmt):

        #additional code
        trace_data = ("__isoc99_sscanf", {
            "scan": (scan, scan.symbolic),
            "fmt": (fmt, fmt.symbolic)
        })
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString())
        }
        self.return_type = SimTypeInt(self.state.arch.bits, True)

        fmt_str = self._parse(1)

        _, items = fmt_str.interpret(self.arg(0),
                                     2,
                                     self.arg,
                                     region=self.state.memory)

        return items
Пример #3
0
    def run(self, dst, src):

        #additional code
        trace_data = ("strcpy", {
            "dst": (dst, dst.symbolic),
            "src": (src, src.symbolic)
        })
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString())
        }
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        strncpy = simuvex.SimProcedures['libc.so.6']['strncpy']
        src_len = self.inline_call(strlen, src)

        ret_expr = self.inline_call(strncpy,
                                    dst,
                                    src,
                                    src_len.ret_expr + 1,
                                    src_len=src_len.ret_expr).ret_expr
        return ret_expr
Пример #4
0
    def run(self, haystack_addr, needle_addr, haystack_strlen=None, needle_strlen=None):
        self.argument_types = { 0: self.ty_ptr(SimTypeString()),
                                1: self.ty_ptr(SimTypeString())}
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        strncmp = simuvex.SimProcedures['libc.so.6']['strncmp']

        haystack_strlen = self.inline_call(strlen, haystack_addr) if haystack_strlen is None else haystack_strlen
        needle_strlen = self.inline_call(strlen, needle_addr) if needle_strlen is None else needle_strlen

        # naive approach
        haystack_maxlen = haystack_strlen.max_null_index
        needle_maxlen = needle_strlen.max_null_index

        l.debug("strstr with size %d haystack and size %d needle...", haystack_maxlen, needle_maxlen)

        if needle_maxlen == 0:
            l.debug("... zero-length needle.")
            return haystack_addr
        elif haystack_maxlen == 0:
            l.debug("... zero-length haystack.")
            return self.state.se.BitVecVal(0, self.state.arch.bits)

        if self.state.se.symbolic(needle_strlen.ret_expr):
            cases = [ [ needle_strlen.ret_expr == 0, haystack_addr ] ]
            exclusions = [ needle_strlen.ret_expr != 0 ]
            remaining_symbolic = self.state.libc.max_symbolic_strstr
            for i in range(haystack_maxlen):
                l.debug("... case %d (%d symbolic checks remaining)", i, remaining_symbolic)

                # big hack!
                cmp_res = self.inline_call(strncmp, haystack_addr + i, needle_addr, needle_strlen.ret_expr, a_len=haystack_strlen, b_len=needle_strlen)
                c = self.state.se.And(*([ self.state.se.UGE(haystack_strlen.ret_expr, needle_strlen.ret_expr), cmp_res.ret_expr == 0 ] + exclusions))
                exclusions.append(cmp_res.ret_expr != 0)

                if self.state.se.symbolic(c):
                    remaining_symbolic -= 1

                #print "CASE:", c
                cases.append([ c, haystack_addr + i ])
                haystack_strlen.ret_expr = haystack_strlen.ret_expr - 1

                if remaining_symbolic == 0:
                    l.debug("... exhausted remaining symbolic checks.")
                    break

            cases.append([ self.state.se.And(*exclusions), self.state.se.BVV(0, self.state.arch.bits) ])
            l.debug("... created %d cases", len(cases))
            r = self.state.se.ite_cases(cases, 0)
            c = [ self.state.se.Or(*[c for c,_ in cases]) ]
        else:
            needle_length = self.state.se.any_int(needle_strlen.ret_expr)
            needle_str = self.state.memory.load(needle_addr, needle_length)

            r, c, i = self.state.memory.find(haystack_addr, needle_str, haystack_strlen.max_null_index, max_symbolic_bytes=self.state.libc.max_symbolic_strstr, default=0)

        self.state.add_constraints(*c)
        return r
Пример #5
0
    def run(self, dst, src):
        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                               1: self.ty_ptr(SimTypeString())}
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        strncpy = simuvex.SimProcedures['libc.so.6']['strncpy']
        src_len = self.inline_call(strlen, src)

        ret_expr = self.inline_call(strncpy, dst, src, src_len.ret_expr+1, src_len=src_len.ret_expr).ret_expr
        return ret_expr
Пример #6
0
    def run(self, scan, fmt):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                               1: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(self.state.arch.bits, True)

        fmt_str = self._parse(1)

        _, items = fmt_str.interpret(self.arg(0), 2, self.arg, region=self.state.memory)

        return items
Пример #7
0
    def run(self, a_addr, b_addr):
        self.argument_types = { 0: self.ty_ptr(SimTypeString()),
                                   1: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(32, True)

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        a_strlen = self.inline_call(strlen, a_addr)
        b_strlen = self.inline_call(strlen, b_addr)
        maxlen = self.state.se.BVV(max(a_strlen.max_null_index, b_strlen.max_null_index), self.state.arch.bits)

        strncmp = self.inline_call(simuvex.SimProcedures['libc.so.6']['strncmp'], a_addr, b_addr, maxlen, a_len=a_strlen, b_len=b_strlen)
        return strncmp.ret_expr
Пример #8
0
    def run(self, s):
        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        strncpy = simuvex.SimProcedures['libc.so.6']['strncpy']
        malloc = simuvex.SimProcedures['libc.so.6']['malloc']

        src_len = self.inline_call(strlen, s).ret_expr
        new_s = self.inline_call(malloc, src_len + 1).ret_expr

        self.inline_call(strncpy, new_s, s, src_len + 1, src_len=src_len)

        return new_s
Пример #9
0
    def run(self, fmt):

        #additional code
        trace_data = ("__isoc99_scanf", {"fmt": (fmt, fmt.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        #end of additional code

        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(self.state.arch.bits, True)

        fmt_str = self._parse(0)

        # we're reading from stdin so the region is the file's content
        f = self.state.posix.get_file(0)
        region = f.content
        start = f.pos

        (end, items) = fmt_str.interpret(start, 1, self.arg, region=region)

        # do the read, correcting the internal file position and logging the action
        self.state.posix.read_from(0, end - start)

        return items
Пример #10
0
    def run(self, s_addr, c_int, s_strlen=None):
        c = c_int[7:0]

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: SimTypeInt(32, True)
        }  # ?
        self.return_type = self.ty_ptr(SimTypeChar())  # ?

        s_strlen = self.inline_call(
            simuvex.SimProcedures['libc.so.6']['strlen'], s_addr)

        if self.state.se.symbolic(s_strlen.ret_expr):
            l.debug("symbolic strlen")
            # TODO: more constraints here to make sure we don't search too little
            max_sym = min(self.state.se.max_int(s_strlen.ret_expr),
                          self.state.libc.max_symbolic_strchr)
            a, c, i = self.state.memory.find(s_addr,
                                             c,
                                             s_strlen.max_null_index,
                                             max_symbolic_bytes=max_sym,
                                             default=0)
        else:
            l.debug("concrete strlen")
            max_search = self.state.se.any_int(s_strlen.ret_expr)
            a, c, i = self.state.memory.find(s_addr, c, max_search, default=0)

        if len(i) != 0:
            a = a.annotate(MultiwriteAnnotation())
            self.state.add_constraints(*c)

        return a
Пример #11
0
    def run(self, string):

        #additional code
        trace_data = ("puts", {"string": (string, string.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(32, True)

        write = simuvex.SimProcedures['syscalls']['write']
        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        length = self.inline_call(strlen, string).ret_expr
        self.inline_call(write, self.state.se.BVV(1, self.state.arch.bits),
                         string, length)
        self.state.posix.write(1, self.state.se.BVV(0x0a, 8), 1)

        # TODO: return values
        return self.state.se.Unconstrained('puts', self.state.arch.bits)
Пример #12
0
    def run(self, addr_in): #pylint:disable=unused-argument
        # arg types: struct....... :(
        self.return_type = self.ty_ptr(SimTypeString())

        #TODO: return an IP address string
        ret_expr = self.state.se.Unconstrained("inet_ntoa_ret", self.state.arch.bits)
        return ret_expr
Пример #13
0
    def run(self, s):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(self.state.arch, True)

        strtol = simuvex.SimProcedures['libc.so.6']['strtol']
        return strtol.strtol_inner(s, self.state, self.state.memory, 10, True)[1]
Пример #14
0
    def run(self, dst_addr, src_addr, limit, src_len=None):
        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString()),
            2: SimTypeLength(self.state.arch)
        }
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        memcpy = simuvex.SimProcedures['libc.so.6']['memcpy']

        src_len = src_len if src_len is not None else self.inline_call(
            strlen, src_addr).ret_expr
        cpy_size = self.state.se.If(self.state.se.ULE(limit, src_len + 1),
                                    limit, src_len + 1)

        self.inline_call(memcpy, dst_addr, src_addr, cpy_size)
        return dst_addr
Пример #15
0
    def run(self, p_addr, flags):
        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                               1: SimTypeInt(32, True)}
        self.return_type = SimTypeFd()

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        p_strlen = self.inline_call(strlen, p_addr)
        p_expr = self.state.memory.load(p_addr, p_strlen.max_null_index, endness='Iend_BE')
        path = self.state.se.any_str(p_expr)

        fd = self.state.posix.open(path, flags)
        return fd
Пример #16
0
    def run(self, a_addr, b_addr):

        #additional code
        trace_data = ("strcasecmp", {
            "a_addr": (a_addr, a_addr.symbolic),
            "b_addr": (b_addr, b_addr.symbolic)
        })
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString())
        }
        self.return_type = SimTypeInt(32, True)

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        a_strlen = self.inline_call(strlen, a_addr)
        b_strlen = self.inline_call(strlen, b_addr)
        maxlen = self.state.se.BVV(
            max(a_strlen.max_null_index, b_strlen.max_null_index),
            self.state.arch.bits)

        strncmp = self.inline_call(
            simuvex.SimProcedures['libc.so.6']['strncmp'],
            a_addr,
            b_addr,
            maxlen,
            a_len=a_strlen,
            b_len=b_strlen)
        return strncmp.ret_expr
Пример #17
0
    def run(self, s):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeLength(self.state.arch)

        max_symbolic_bytes = self.state.libc.buf_symbolic_bytes
        max_str_len = self.state.libc.max_str_len

        if self.state.mode == 'static':

            self.max_null_index = []

            # Make sure to convert s to ValueSet
            s_list = self.state.memory.normalize_address(
                s, convert_to_valueset=True)

            length = self.state.se.ESI(self.state.arch.bits)
            for s_ptr in s_list:

                r, c, i = self.state.memory.find(
                    s,
                    self.state.se.BVV(0, 8),
                    max_str_len,
                    max_symbolic_bytes=max_symbolic_bytes)

                self.max_null_index = max(self.max_null_index + i)

                # Convert r to the same region as s
                r_list = self.state.memory.normalize_address(
                    r,
                    convert_to_valueset=True,
                    target_region=s_ptr._model_vsa.regions.keys()[0])

                for r_ptr in r_list:
                    length = length.union(r_ptr - s_ptr)

            return length

        else:
            r, c, i = self.state.memory.find(
                s,
                self.state.se.BVV(0, 8),
                max_str_len,
                max_symbolic_bytes=max_symbolic_bytes)

            self.max_null_index = max(i)
            self.state.add_constraints(*c)

            return r - s
Пример #18
0
    def run(self, string):
        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(32, True)

        write = simuvex.SimProcedures['syscalls']['write']
        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        length = self.inline_call(strlen, string).ret_expr
        self.inline_call(write, self.state.se.BVV(1, self.state.arch.bits),
                         string, length)
        self.state.posix.write(1, self.state.se.BVV(0x0a, 8), 1)

        # TODO: return values
        return self.state.se.Unconstrained('puts', self.state.arch.bits)
Пример #19
0
    def run(self, s):

        #additional code
        trace_data = ("strdup", {"s": (s, s.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        #end of additional code

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        strncpy = simuvex.SimProcedures['libc.so.6']['strncpy']
        malloc = simuvex.SimProcedures['libc.so.6']['malloc']

        src_len = self.inline_call(strlen, s).ret_expr
        new_s = self.inline_call(malloc, src_len+1).ret_expr

        self.inline_call(strncpy, new_s, s, src_len+1, src_len=src_len)

        return new_s
Пример #20
0
    def run(self, dst_addr, src_addr, limit, src_len=None):

        #additional code
        trace_data = ("strncpy", {"dist_addr": (dist_addr, dst_addr.symbolic), "src_addr": (src_addr, src_addr.symbolic), "limit": (limit, limit.symbolic), "src_len": (src_len, src_len.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        #end of additional code

        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                               1: self.ty_ptr(SimTypeString()),
                               2: SimTypeLength(self.state.arch)}
        self.return_type = self.ty_ptr(SimTypeString())

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']
        memcpy = simuvex.SimProcedures['libc.so.6']['memcpy']

        src_len = src_len if src_len is not None else self.inline_call(strlen, src_addr).ret_expr
        cpy_size = self.state.se.If(self.state.se.ULE(limit, src_len + 1), limit, src_len + 1)

        self.inline_call(memcpy, dst_addr, src_addr, cpy_size)
        return dst_addr
Пример #21
0
    def run(self, s_addr, c_int, s_strlen=None):

        #additional code
        trace_data = ("strchr", {
            "s_addr": (s_addr, s_addr.symbolic),
            "c_int": (c_int, c_int.symbolic)
        })
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        c = c_int[7:0]

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: SimTypeInt(32, True)
        }  # ?
        self.return_type = self.ty_ptr(SimTypeChar())  # ?

        s_strlen = self.inline_call(
            simuvex.SimProcedures['libc.so.6']['strlen'], s_addr)

        if self.state.se.symbolic(s_strlen.ret_expr):
            l.debug("symbolic strlen")
            # TODO: more constraints here to make sure we don't search too little
            max_sym = min(self.state.se.max_int(s_strlen.ret_expr),
                          self.state.libc.max_symbolic_strchr)
            a, c, i = self.state.memory.find(s_addr,
                                             c,
                                             s_strlen.max_null_index,
                                             max_symbolic_bytes=max_sym,
                                             default=0)
        else:
            l.debug("concrete strlen")
            max_search = self.state.se.any_int(s_strlen.ret_expr)
            a, c, i = self.state.memory.find(s_addr, c, max_search, default=0)

        if len(i) != 0:
            a = a.annotate(MultiwriteAnnotation())
            self.state.add_constraints(*c)

        return a
Пример #22
0
    def run(self, addr_in): #pylint:disable=unused-argument

    	#additional code
        trace_data = ("inet_ntoa", {"addr_in": (addr_in, addr_in.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(trace_data)
        #end of additional code

        # arg types: struct....... :(
        self.return_type = self.ty_ptr(SimTypeString())

        #TODO: return an IP address string
        ret_expr = self.state.se.Unconstrained("inet_ntoa_ret", self.state.arch.bits)
        return ret_expr
Пример #23
0
    def run(self, s):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeLength(self.state.arch)

        max_symbolic_bytes = self.state.libc.buf_symbolic_bytes
        max_str_len = self.state.libc.max_str_len

        if self.state.mode == 'static':

            self.max_null_index = [  ]

            # Make sure to convert s to ValueSet
            s_list = self.state.memory.normalize_address(s, convert_to_valueset=True)

            length = self.state.se.ESI(self.state.arch.bits)
            for s_ptr in s_list:

                r, c, i = self.state.memory.find(s, self.state.se.BVV(0, 8), max_str_len, max_symbolic_bytes=max_symbolic_bytes)

                self.max_null_index = max(self.max_null_index + i)

                # Convert r to the same region as s
                r_list = self.state.memory.normalize_address(r, convert_to_valueset=True, target_region=s_ptr._model_vsa.regions.keys()[0])

                for r_ptr in r_list:
                    length = length.union(r_ptr - s_ptr)

            return length

        else:
            search_len = max_str_len
            r, c, i = self.state.memory.find(s, self.state.se.BVV(0, 8), search_len, max_symbolic_bytes=max_symbolic_bytes)

            # try doubling the search len and searching again
            while all(con.is_false() for con in c):
                search_len *= 2
                r, c, i = self.state.memory.find(s, self.state.se.BVV(0, 8), search_len, max_symbolic_bytes=max_symbolic_bytes)
                # stop searching after some reasonable limit
                if search_len > 0x10000:
                    raise simuvex.SimMemoryLimitError("strlen hit limit of 0x10000")

            self.max_null_index = max(i)
            self.state.add_constraints(*c)
            return r - s
Пример #24
0
    def run(self, s):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeLength(self.state.arch)

        max_symbolic_bytes = self.state.libc.buf_symbolic_bytes
        max_str_len = self.state.libc.max_str_len

        r, c, i = self.state.memory.find(s,
                                         self.state.BVV(0, 8),
                                         max_str_len,
                                         max_symbolic_bytes=max_symbolic_bytes)

        self.max_null_index = max(i)
        self.state.add_constraints(*c)
        return r - s
Пример #25
0
    def run(self, fmt):
        #pylint:disable=attribute-defined-outside-init

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(self.state.arch.bits, True)

        fmt_str = self._parse(0)

        # we're reading from stdin so the region is the file's content
        f = self.state.posix.get_file(0)
        region = f.content
        start = f.pos

        (end, items) = fmt_str.interpret(start, 1, self.arg, region=region)

        # do the read, correcting the internal file position and logging the action
        self.state.posix.read_from(0, end - start)

        return items
Пример #26
0
    def run(self, s):
        #pylint:disable=attribute-defined-outside-init

        #additional code
        trace_data = ("atoi", {"s": (s, s.symbolic)})
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        self.argument_types = {0: self.ty_ptr(SimTypeString())}
        self.return_type = SimTypeInt(self.state.arch, True)

        strtol = simuvex.SimProcedures['libc.so.6']['strtol']
        return strtol.strtol_inner(s, self.state, self.state.memory, 10,
                                   True)[1]
Пример #27
0
                def run(self, s, special_addrs=None, added_constraints=None):
                    self.argument_types = {0: self.ty_ptr(SimTypeString())}
                    self.return_type = SimTypeInt(self.state.arch, True)

                    res_symb_var = claripy.BVS('atoi_ret',
                                               self.state.arch.bits)

                    # If the argument is a special constrained variable
                    s_val = self.state.se.any_int(s)
                    if s.concrete and s_val in special_addrs:
                        print(
                            "Got a special memory addr: {:X}\n".format(s_val))
                        # Grab the operator and right operand
                        (op, r_opr) = special_addrs[s_val]

                        # Add the constraint of: (return_val `op` r_opr)
                        print("Adding claripy_op_mapping[{}]({}, {})\n".format(
                            op, res_symb_var, r_opr))
                        added_constraints.append(claripy_op_mapping[op](
                            res_symb_var, r_opr))
                    return res_symb_var
Пример #28
0
    def run(self, a_addr, b_addr, limit, a_len=None, b_len=None): #pylint:disable=arguments-differ
        # TODO: smarter types here?
        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                       1: self.ty_ptr(SimTypeString()),
                       2: SimTypeLength(self.state.arch)}
        self.return_type = SimTypeInt(32, True)

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        a_strlen = a_len if a_len is not None else self.inline_call(strlen, a_addr)
        b_strlen = b_len if b_len is not None else self.inline_call(strlen, b_addr)

        a_len = a_strlen.ret_expr
        b_len = b_strlen.ret_expr

        match_constraints = [ ]
        variables = a_len.variables | b_len.variables | limit.variables
        ret_expr = self.state.se.Unconstrained("strncmp_ret", self.state.arch.bits)

        # determine the maximum number of bytes to compare
        concrete_run = False
        #if not self.state.se.symbolic(a_len) and not self.state.se.symbolic(b_len) and not self.state.se.symbolic(limit):
        if self.state.se.single_valued(a_len) and self.state.se.single_valued(b_len) and self.state.se.single_valued(limit):
            c_a_len = self.state.se.any_int(a_len)
            c_b_len = self.state.se.any_int(b_len)
            c_limit = self.state.se.any_int(limit)

            l.debug("everything is concrete: a_len %d, b_len %d, limit %d", c_a_len, c_b_len, c_limit)

            if (c_a_len < c_limit or c_b_len < c_limit) and c_a_len != c_b_len:
                l.debug("lengths < limit and unmatched")

            concrete_run = True
            maxlen = min(c_a_len, c_b_len, c_limit)
        else:
            if self.state.se.single_valued(limit):
                c_limit = self.state.se.any_int(limit)
                maxlen = min(a_strlen.max_null_index, b_strlen.max_null_index, c_limit)
            else:
                maxlen = max(a_strlen.max_null_index, b_strlen.max_null_index)

            match_constraints.append(self.state.se.Or(a_len == b_len, self.state.se.And(self.state.se.UGE(a_len, limit), self.state.se.UGE(b_len, limit))))

        if maxlen == 0:
            # there is a corner case: if a or b are not both empty string, and limit is greater than 0, we should return
            # non-equal. Basically we only return equal when limit is 0, or a_len == b_len == 0
            if self.state.se.single_valued(limit) and self.state.se.any_int(limit) == 0:
                # limit is 0
                l.debug("returning equal for 0-limit")
                return self.state.se.BVV(0, self.state.arch.bits, variables=variables)
            elif self.state.se.single_valued(a_len) and self.state.se.single_valued(b_len) and \
                    self.state.se.any_int(a_len) == self.state.se.any_int(b_len) == 0:
                # two empty strings
                l.debug("returning equal for two empty strings")
                return self.state.se.BVV(0, self.state.arch.bits, variables=variables)
            else:
                # all other cases fall into this branch
                l.debug("returning non-equal for comparison of an empty string and a non-empty string")
                if a_strlen.max_null_index == 0:
                    return self.state.se.BVV(-1, self.state.arch.bits, variables=variables)
                else:
                    return self.state.se.BVV(1, self.state.arch.bits, variables=variables)

        # the bytes
        a_bytes = self.state.memory.load(a_addr, maxlen, endness='Iend_BE')
        b_bytes = self.state.memory.load(b_addr, maxlen, endness='Iend_BE')

        # TODO: deps

        # all possible return values in static mode
        return_values = [ ]

        for i in range(maxlen):
            l.debug("Processing byte %d", i)
            maxbit = (maxlen-i)*8
            a_byte = a_bytes[maxbit-1:maxbit-8]
            b_byte = b_bytes[maxbit-1:maxbit-8]

            if concrete_run and self.state.se.single_valued(a_byte) and self.state.se.single_valued(b_byte):
                a_conc = self.state.se.any_int(a_byte)
                b_conc = self.state.se.any_int(b_byte)
                variables |= a_byte.variables
                variables |= b_byte.variables

                if a_conc != b_conc:
                    l.debug("... found mis-matching concrete bytes 0x%x and 0x%x", a_conc, b_conc)
                    if a_conc < b_conc:
                        return self.state.se.BVV(-1, self.state.arch.bits, variables=variables)
                    else:
                        return self.state.se.BVV(1, self.state.arch.bits, variables=variables)
            else:

                if self.state.mode == 'static':
                    return_values.append(a_byte - b_byte)

                concrete_run = False

            if self.state.mode != 'static':
                byte_constraint = self.state.se.Or(a_byte == b_byte, self.state.se.ULT(a_len, i), self.state.se.ULT(limit, i))
                match_constraints.append(byte_constraint)

        if concrete_run:
            l.debug("concrete run made it to the end!")
            return self.state.se.BVV(0, self.state.arch.bits, variables=variables)

        if self.state.mode == 'static':
            ret_expr = self.state.se.ESI(8)
            for expr in return_values:
                ret_expr = ret_expr.union(expr)

            ret_expr = ret_expr.sign_extend(self.state.arch.bits - 8)

        else:
            # make the constraints

            l.debug("returning symbolic")
            match_constraint = self.state.se.And(*match_constraints)
            nomatch_constraint = self.state.se.Not(match_constraint)

            #l.debug("match constraints: %s", match_constraint)
            #l.debug("nomatch constraints: %s", nomatch_constraint)

            match_case = self.state.se.And(limit != 0, match_constraint, ret_expr == 0)
            nomatch_case = self.state.se.And(limit != 0, nomatch_constraint, ret_expr == 1)
            l0_case = self.state.se.And(limit == 0, ret_expr == 0)
            empty_case = self.state.se.And(a_strlen.ret_expr == 0, b_strlen.ret_expr == 0, ret_expr == 0)

            self.state.add_constraints(self.state.se.Or(match_case, nomatch_case, l0_case, empty_case))

        return ret_expr
Пример #29
0
    def run(self,
            str_ptr,
            delim_ptr,
            save_ptr,
            str_strlen=None,
            delim_strlen=None):

        #additional code
        trace_data = ("strtok_r", {
            "str_ptr": (str_ptr, str_ptr.symbolic),
            "delim_ptr": (delim_ptr, delim_ptr.symbolic),
            "save_ptr": (save_ptr, save_ptr.symbolic),
            "str_strlen": (str_strlen, str_strlen.symbolic),
            "delim_strlen": (delim_strlen, delim_strlen.symbolic)
        })
        try:
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        except KeyError:
            self.state.procedure_data.global_variables["trace"] = []
            self.state.procedure_data.global_variables["trace"].append(
                trace_data)
        #end of additional code

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: self.ty_ptr(SimTypeString()),
            2: self.ty_ptr(self.ty_ptr(SimTypeString()))
        }
        self.return_type = self.ty_ptr(SimTypeString())

        if self.state.libc.simple_strtok:
            malloc = simuvex.SimProcedures['libc.so.6']['malloc']
            token_ptr = self.inline_call(
                malloc, self.state.libc.strtok_token_size).ret_expr
            r = self.state.se.If(
                self.state.se.Unconstrained('strtok_case',
                                            self.state.arch.bits) == 0,
                token_ptr, self.state.se.BVV(0, self.state.arch.bits))
            self.state.libc.strtok_heap.append(token_ptr)
            return r
        else:
            strstr = simuvex.SimProcedures['libc.so.6']['strstr']
            strlen = simuvex.SimProcedures['libc.so.6']['strlen']

            l.debug("Doin' a strtok_r!")
            l.debug("... geting the saved state")

            saved_str_ptr = self.state.memory.load(
                save_ptr,
                self.state.arch.bytes,
                endness=self.state.arch.memory_endness)
            start_ptr = self.state.se.If(str_ptr == 0, saved_str_ptr, str_ptr)

            l.debug("... getting the lengths")
            str_strlen = self.inline_call(
                strlen, start_ptr) if str_strlen is None else str_strlen
            delim_strlen = self.inline_call(
                strlen, delim_ptr) if delim_strlen is None else delim_strlen

            l.debug(
                "... STRTOK SLOW PATH (symbolic-length delimiteter and/or string)"
            )
            l.debug("... calling strstr")
            where = self.inline_call(strstr,
                                     start_ptr,
                                     delim_ptr,
                                     haystack_strlen=str_strlen,
                                     needle_strlen=delim_strlen)
            write_length = self.state.se.If(where.ret_expr != 0,
                                            delim_strlen.ret_expr, 0)
            write_content = self.state.se.BVV(0,
                                              delim_strlen.max_null_index * 8)

            # do a symbolic write (we increment the limit because of the possibility that the write target is 0, in which case the length will be 0, anyways)
            l.debug("... doing the symbolic write")
            self.state.memory.store(where.ret_expr,
                                    write_content,
                                    size=write_length,
                                    strategy=["symbolic_nonzero", "any"],
                                    limit=str_strlen.max_null_index + 1)

            l.debug("... creating the return address")
            new_start = write_length + where.ret_expr
            new_state = self.state.se.If(new_start != 0, new_start, start_ptr)

            l.debug("... saving the state")
            self.state.memory.store(save_ptr,
                                    new_state,
                                    endness=self.state.arch.memory_endness)

            l.debug("... done")
            return new_start
Пример #30
0
    def run(self, a_addr, b_addr, limit, a_len=None, b_len=None): #pylint:disable=arguments-differ
        # TODO: smarter types here?
        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                       1: self.ty_ptr(SimTypeString()),
                       2: SimTypeLength(self.state.arch)}
        self.return_type = SimTypeInt(32, True)

        strlen = simuvex.SimProcedures['libc.so.6']['strlen']

        a_strlen = a_len if a_len is not None else self.inline_call(strlen, a_addr)
        b_strlen = b_len if b_len is not None else self.inline_call(strlen, b_addr)

        a_len = a_strlen.ret_expr
        b_len = b_strlen.ret_expr

        match_constraints = [ ]
        variables = a_len.variables | b_len.variables | limit.variables
        ret_expr = self.state.se.Unconstrained("strncmp_ret", self.state.arch.bits)

        # determine the maximum number of bytes to compare
        concrete_run = False
        if not self.state.se.symbolic(a_len) and not self.state.se.symbolic(b_len) and not self.state.se.symbolic(limit):
            c_a_len = self.state.se.any_int(a_len)
            c_b_len = self.state.se.any_int(b_len)
            c_limit = self.state.se.any_int(limit)

            l.debug("everything is concrete: a_len %d, b_len %d, limit %d", c_a_len, c_b_len, c_limit)

            if (c_a_len < c_limit or c_b_len < c_limit) and c_a_len != c_b_len:
                l.debug("lengths < limit and unmatched")
                return self.state.se.BVV(1, self.state.arch.bits, variables=variables)

            concrete_run = True
            maxlen = min(c_a_len, c_b_len, c_limit)
        else:
            if not self.state.se.symbolic(limit):
                c_limit = self.state.se.any_int(limit)
                maxlen = min(a_strlen.max_null_index, b_strlen.max_null_index, c_limit)
            else:
                maxlen = max(a_strlen.max_null_index, b_strlen.max_null_index)

            match_constraints.append(self.state.se.Or(a_len == b_len, self.state.se.And(self.state.se.UGE(a_len, limit), self.state.se.UGE(b_len, limit))))

        if maxlen == 0:
            l.debug("returning equal for 0-length maximum strings")
            return self.state.se.BVV(0, self.state.arch.bits, variables=variables)

        # the bytes
        a_bytes = self.state.memory.load(a_addr, maxlen, endness='Iend_BE')
        b_bytes = self.state.memory.load(b_addr, maxlen, endness='Iend_BE')

        # TODO: deps
        for i in range(maxlen):
            l.debug("Processing byte %d", i)
            maxbit = (maxlen-i)*8
            a_byte = a_bytes[maxbit-1:maxbit-8]
            b_byte = b_bytes[maxbit-1:maxbit-8]

            if concrete_run and not self.state.se.symbolic(a_byte) and not self.state.se.symbolic(b_byte):
                a_conc = self.state.se.any_int(a_byte)
                b_conc = self.state.se.any_int(b_byte)
                variables |= a_byte.variables
                variables |= b_byte.variables

                if a_conc != b_conc:
                    l.debug("... found mis-matching concrete bytes 0x%x and 0x%x", a_conc, b_conc)
                    return self.state.se.BVV(1, self.state.arch.bits, variables=variables)
            else:
                concrete_run = False

            byte_constraint = self.state.se.Or(a_byte == b_byte, self.state.se.ULT(a_len, i), self.state.se.ULT(limit, i))
            match_constraints.append(byte_constraint)

        if concrete_run:
            l.debug("concrete run made it to the end!")
            return self.state.se.BVV(0, self.state.arch.bits, variables=variables)

        # make the constraints
        l.debug("returning symbolic")
        match_constraint = self.state.se.And(*match_constraints)
        nomatch_constraint = self.state.se.Not(match_constraint)

        #l.debug("match constraints: %s", match_constraint)
        #l.debug("nomatch constraints: %s", nomatch_constraint)

        match_case = self.state.se.And(limit != 0, match_constraint, ret_expr == 0)
        nomatch_case = self.state.se.And(limit != 0, nomatch_constraint, ret_expr == 1)
        l0_case = self.state.se.And(limit == 0, ret_expr == 0)
        empty_case = self.state.se.And(a_strlen.ret_expr == 0, b_strlen.ret_expr == 0, ret_expr == 0)

        self.state.add_constraints(self.state.se.Or(match_case, nomatch_case, l0_case, empty_case))
        return ret_expr