예제 #1
0
    def _standardize_value(arg, ty, state, alloc):
        check = ty is not None
        if isinstance(arg, s_action_object.SimActionObject):
            return SimCC._standardize_value(arg.ast, ty, state, alloc)
        elif isinstance(arg, PointerWrapper):
            if check and not isinstance(ty, s_type.SimTypePointer):
                raise TypeError(
                    "Type mismatch: expected %s, got pointer-wrapper" %
                    ty.name)

            real_value = SimCC._standardize_value(arg.value,
                                                  ty.pts_to if check else None,
                                                  state, alloc)
            return alloc(real_value, state)

        elif isinstance(arg, str):
            # TODO: when we switch to py3, distinguish between str and bytes
            # by null-terminating str but not bytes :/
            arg += '\0'
            ref = False
            if check:
                if isinstance(ty, s_type.SimTypePointer) and \
                        isinstance(ty.pts_to, s_type.SimTypeChar):
                    ref = True
                elif isinstance(ty, s_type.SimTypeFixedSizeArray) and \
                        isinstance(ty.elem_type, s_type.SimTypeChar):
                    ref = False
                    if len(arg) > ty.length:
                        raise TypeError("String %s is too long for %s" %
                                        (repr(arg), ty.name))
                    arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, s_type.SimTypeArray) and \
                        isinstance(ty.elem_type, s_type.SimTypeChar):
                    ref = True
                    if ty.length is not None:
                        if len(arg) > ty.length:
                            raise TypeError("String %s is too long for %s" %
                                            (repr(arg), ty.name))
                        arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, s_type.SimTypeString):
                    ref = False
                    if len(arg) > ty.length + 1:
                        raise TypeError("String %s is too long for %s" %
                                        (repr(arg), ty.name))
                    arg = arg.ljust(ty.length + 1, '\0')
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" %
                                    ty.name)
            val = SimCC._standardize_value(
                map(ord, arg),
                s_type.SimTypeFixedSizeArray(s_type.SimTypeChar(), len(arg)),
                state, alloc)
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, list):
            ref = False
            subty = None
            if check:
                if isinstance(ty, s_type.SimTypePointer):
                    ref = True
                    subty = ty.pts_to
                elif isinstance(ty, s_type.SimTypeFixedSizeArray):
                    ref = False
                    subty = ty.elem_type
                    if len(arg) != ty.length:
                        raise TypeError("Array %s is the wrong length for %s" %
                                        (repr(arg), ty.name))
                elif isinstance(ty, s_type.SimTypeArray):
                    ref = True
                    subty = ty.elem_type
                    if ty.length is not None:
                        if len(arg) != ty.length:
                            raise TypeError(
                                "Array %s is the wrong length for %s" %
                                (repr(arg), ty.name))
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" %
                                    ty.name)
            else:
                types = map(type, arg)
                if types[1:] != types[:-1]:
                    raise TypeError(
                        "All elements of list must be of same type")

            val = claripy.Concat(*[
                SimCC._standardize_value(sarg, subty, state, alloc)
                for sarg in arg
            ])
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, tuple):
            if check:
                if not isinstance(ty, s_type.SimStruct):
                    raise TypeError(
                        "Type mismatch: Expected %s, got tuple (i.e. struct)" %
                        ty.name)
                if len(arg) != len(ty.fields):
                    raise TypeError(
                        "Wrong number of fields in struct, expected %d got %d"
                        % (len(ty.fields), len(arg)))
                return claripy.Concat(*[
                    SimCC._standardize_value(sarg, sty, state, alloc)
                    for sarg, sty in zip(arg, ty.fields.values())
                ])
            else:
                return claripy.Concat(*[
                    SimCC._standardize_value(sarg, None, state, alloc)
                    for sarg in arg
                ])

        elif isinstance(arg, (int, long)):
            if check and isinstance(ty, s_type.SimTypeFloat):
                return SimCC._standardize_value(float(arg), ty, state, alloc)

            val = state.se.BVV(arg, ty.size if check else state.arch.bits)
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed
            return val

        elif isinstance(arg, float):
            sort = claripy.FSORT_FLOAT
            if check:
                if isinstance(ty, s_type.SimTypeDouble):
                    sort = claripy.FSORT_DOUBLE
                elif isinstance(ty, s_type.SimTypeFloat):
                    pass
                else:
                    raise TypeError("Type mismatch: expectd %s, got float" %
                                    ty.name)
            else:
                sort = claripy.FSORT_DOUBLE if state.arch.bits == 64 else claripy.FSORT_FLOAT

            val = claripy.fpToIEEEBV(claripy.FPV(arg, sort))
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed  # pylint: disable=no-member
            return val

        elif isinstance(arg, claripy.ast.Base):
            # yikes
            if state.arch.memory_endness == 'Iend_LE' and arg.length == state.arch.bits:
                arg = arg.reversed
            return arg

        else:
            raise TypeError("I don't know how to serialize %s." % repr(arg))
예제 #2
0
파일: s_cc.py 프로젝트: angr/simuvex
    def _standardize_value(arg, ty, state, alloc):
        check = ty is not None
        if isinstance(arg, s_action_object.SimActionObject):
            return SimCC._standardize_value(arg.ast, ty, state, alloc)
        elif isinstance(arg, PointerWrapper):
            if check and not isinstance(ty, s_type.SimTypePointer):
                raise TypeError("Type mismatch: expected %s, got pointer-wrapper" % ty.name)

            real_value = SimCC._standardize_value(arg.value, ty.pts_to if check else None, state, alloc)
            return alloc(real_value, state)

        elif isinstance(arg, str):
            # TODO: when we switch to py3, distinguish between str and bytes
            # by null-terminating str but not bytes :/
            arg += '\0'
            ref = False
            if check:
                if isinstance(ty, s_type.SimTypePointer) and \
                        isinstance(ty.pts_to, s_type.SimTypeChar):
                    ref = True
                elif isinstance(ty, s_type.SimTypeFixedSizeArray) and \
                        isinstance(ty.elem_type, s_type.SimTypeChar):
                    ref = False
                    if len(arg) > ty.length:
                        raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                    arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, s_type.SimTypeArray) and \
                        isinstance(ty.elem_type, s_type.SimTypeChar):
                    ref = True
                    if ty.length is not None:
                        if len(arg) > ty.length:
                            raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                        arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, s_type.SimTypeString):
                    ref = False
                    if len(arg) > ty.length + 1:
                        raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                    arg = arg.ljust(ty.length + 1, '\0')
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" % ty.name)
            val = SimCC._standardize_value(map(ord, arg), s_type.SimTypeFixedSizeArray(s_type.SimTypeChar(), len(arg)), state, alloc)
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, list):
            ref = False
            subty = None
            if check:
                if isinstance(ty, s_type.SimTypePointer):
                    ref = True
                    subty = ty.pts_to
                elif isinstance(ty, s_type.SimTypeFixedSizeArray):
                    ref = False
                    subty = ty.elem_type
                    if len(arg) != ty.length:
                        raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name))
                elif isinstance(ty, s_type.SimTypeArray):
                    ref = True
                    subty = ty.elem_type
                    if ty.length is not None:
                        if len(arg) != ty.length:
                            raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name))
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" % ty.name)
            else:
                types = map(type, arg)
                if types[1:] != types[:-1]:
                    raise TypeError("All elements of list must be of same type")

            val = claripy.Concat(*[SimCC._standardize_value(sarg, subty, state, alloc) for sarg in arg])
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, tuple):
            if check:
                if not isinstance(ty, s_type.SimStruct):
                    raise TypeError("Type mismatch: Expected %s, got tuple (i.e. struct)" % ty.name)
                if len(arg) != len(ty.fields):
                    raise TypeError("Wrong number of fields in struct, expected %d got %d" % (len(ty.fields), len(arg)))
                return claripy.Concat(*[SimCC._standardize_value(sarg, sty, state, alloc)
                                        for sarg, sty
                                        in zip(arg, ty.fields.values())])
            else:
                return claripy.Concat(*[SimCC._standardize_value(sarg, None, state, alloc) for sarg in arg])

        elif isinstance(arg, (int, long)):
            if check and isinstance(ty, s_type.SimTypeFloat):
                return SimCC._standardize_value(float(arg), ty, state, alloc)

            val = state.se.BVV(arg, ty.size if check else state.arch.bits)
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed
            return val

        elif isinstance(arg, float):
            sort = claripy.FSORT_FLOAT
            if check:
                if isinstance(ty, s_type.SimTypeDouble):
                    sort = claripy.FSORT_DOUBLE
                elif isinstance(ty, s_type.SimTypeFloat):
                    pass
                else:
                    raise TypeError("Type mismatch: expectd %s, got float" % ty.name)
            else:
                sort = claripy.FSORT_DOUBLE if state.arch.bits == 64 else claripy.FSORT_FLOAT

            val = claripy.fpToIEEEBV(claripy.FPV(arg, sort))
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed      # pylint: disable=no-member
            return val

        elif isinstance(arg, claripy.ast.Base):
            # yikes
            if state.arch.memory_endness == 'Iend_LE' and arg.length == state.arch.bits:
                arg = arg.reversed
            return arg

        else:
            raise TypeError("I don't know how to serialize %s." % repr(arg))