Exemple #1
0
def convert_to_iterators(expr, vars, pad=0):
    """Solve all children in expr and return a list of iterators.

    Each iterator is expanded or repeated so they are all the same
    length.
    """
    max_length = 0
    iterators = []
    # Expand each child into a list.
    for child in expr.children:
        val = solve(child, vars).value
        if repeated.isrepeating(val) and not number.isnumber(val):
            val = convert_to_list(expr, val)
            if len(val) > max_length:
                max_length = len(val)

        # This is a scalar - at least of length 1.
        else:
            max_length = max(max_length, 1)

        iterators.append(val)

    # Pad all iterator lists to be the same length.
    for i, item in enumerate(iterators):
        # Repeat scalar values.
        if not isinstance(item, list):
            iterators[i] = [item] * max_length

        # Extend short lists to the required length
        elif len(item) < max_length:
            item.extend([pad] * (max_length - len(item)))

    return iterators
Exemple #2
0
def solve_quotient(expr, vars):
    iterators = convert_to_iterators(expr, vars, pad=0)

    # Add each element individually.
    result = []
    for elements in zip(*iterators):
        total = None
        for element in elements:
            if number.isnumber(element):
                if total is None:
                    total = element
                else:
                    # Division by 0.
                    if eq.eq(element, 0):
                        total = None
                        break

                    total = number.quotient(total, element)

            # If we encounter a non-number we swallow the error and
            # return None. This could happen for example if one of the
            # columns in the select returns NoneObject() or something
            # which is not a number.
            else:
                total = None
                break

        result.append(total)

    return Result(result, ())
Exemple #3
0
def solve_sum(expr, vars):
    """Handle numerical operators.

    We can mix scalars and repeated elements freely. The result is
    always repeated. Scalars are turned into repeated lists of the
    scalar while repeated values are turned into lists padded with the
    pad element to the longest list we operate on.

    Examples:
       # Scalars are expanded to repeat themselves.
       [1, 2] + 4 -> [1, 2] + [4, 4] -> [5, 6]

       # Lists are padded
       [1, 2] + [1, 2, 3] -> [1, 2, 0] + [1, 2, 3] -> [2, 4, 3]

       # Subselects are expanded if they contain a single column.
       select hex(offset), hexdump from dump(
           offset: (-0x20 + (
               select _EPROCESS.obj_offset from pslist(proc_regex: "svchost"))),
           rows: 5 )
    """
    iterators = convert_to_iterators(expr, vars, pad=0)

    # Add each element individually.
    result = []
    for elements in zip(*iterators):
        total = 0
        for element in elements:
            if number.isnumber(element):
                total = number.sum(element, total)

            # If we encounter a non-number we swallow the error and
            # return None. This could happen for example if one of the
            # columns in the select returns NoneObject() or something
            # which is not a number.
            else:
                total = None
                break

        result.append(total)

    return Result(result, ())