Beispiel #1
0
def get_data(segs, cpp_in):
    '''[str] -> str -> [c_ast]'''
    def gen(((ti, ea, declstr), node)):
        '''(tinfo_t, ea_t) -> c_ast'''
        # NOTE mutates node
        has_data = ida.seg_name(ea) != '.bss'
        ptr = ida.can_be_off32(ea)
        if ptr not in [ida.BADADDR, 0]:
            ptr_ti = ida.get_or_guess_tinfo(ptr)
            ti_node = cdecl.get_decls(declstr).decls[utils.cpp_decomp_tag][0]
            return gen(((ptr_ti, ptr, ''), ti_node))
        # XXX our data segment has no strings, but that's probably specific to
        # the one binary we're dealing with
        elif ti.is_array():
            ai = ida.array_type_data_t()
            ti.get_array_details(ai)
            item_size = ai.elem_type.get_size()
            typename = get_type_for_c_ast_constant(ai.elem_type)
            length = (ida.item_end(ea) - ida.item_head(ea)) / item_size
            if has_data is True:
                if ai.elem_type.is_char():
                    node.init = ep_ct.constant(typename, c_stringify(
                        ida.get_string(ea)))
                else:
                    items = list(get_item(ea + j * item_size, ti)
                                 for j in xrange(0, length))
                    node.init = ep_ct.initlist(
                        [ep_ct.constant(typename, str(x)) for x in items])
        else:
            if has_data is True:
                typename = get_type_for_c_ast_constant(ti)
                node.init = ep_ct.constant(typename,
                                           str(get_item(ea, ti)))
        return node
Beispiel #2
0
def get_item(ea, ti):
    '''ea_t -> tinfo_t -> c.types obj | int | str'''
    if ti.is_array():
        ai = ida.array_details(ti)
        if ai.elem_type.is_char():
            return ida.get_string(ea)
        else:
            sz = ai.elem_type.get_size()
            ret = get_one_item(ea, ai.elem_type, sz)
            return ret
    else:
        sz = ida.size_of(ti)
        return get_one_item(ea, ti, sz)
Beispiel #3
0
def get_arg_for_va_function(callee, start_ea):
    '''str -> ea_t -> str'''
    # XXX hacky; not a very general function
    # XXX imperative
    # get a relevant item needed for processing a variadic function
    sw = {
        'printf' : regs.gpr(abi.arg_regs[0]),
        'scanf' : regs.gpr(abi.arg_regs[0]),
        'sscanf' : regs.gpr(abi.arg_regs[1])
    }
    try:
        wanted_reg = sw[callee]
    except KeyError:
        raise utils.BugError('unrecognized callee %s' % callee)

    distance = 0
    fn = ida.get_func(start_ea)
    # first, look at the delay slot
    ea = ida.next_head(start_ea, fn.endEA)

    while True:
        if distance > 10:
            raise VarargsError(
                'gave up looking for needed varargs argument for %s between ' +
                '%s..%s' % (ida.atoa(ea), ida.atoa(start_ea)))

        if ea == start_ea:
            ea = ida.prev_head(ea)
            continue # skip the call insn
        elif list(ida.code_refs_from(ea, 0)) != []:
            raise VarargsError(
                'encountered branch/jump while looking for varargs argument ' +
                'between %s..%s' % (ida.atoa(ea), ida.atoa(start_ea)))

        rd = ida.get_op(ea, 0)
        if rd.val == wanted_reg:
            opvals = ida.get_opvals(ea) # XXX should try to track stkvar values
            s = ida.get_string(opvals[-1].target)
            if s is not None:
                return s

        ea = ida.prev_head(ea)
        distance += 1
Beispiel #4
0
def get_arg_for_va_function(callee, start_ea):
    """str -> ea_t -> str"""
    # XXX hacky; not a very general function
    # XXX imperative
    # get a relevant item needed for processing a variadic function
    sw = {"printf": regs.gpr(abi.arg_regs[0]), "scanf": regs.gpr(abi.arg_regs[0]), "sscanf": regs.gpr(abi.arg_regs[1])}
    try:
        wanted_reg = sw[callee]
    except KeyError:
        raise utils.BugError("unrecognized callee %s" % callee)

    distance = 0
    fn = ida.get_func(start_ea)
    # first, look at the delay slot
    ea = ida.next_head(start_ea, fn.endEA)

    while True:
        if distance > 10:
            raise VarargsError(
                "gave up looking for needed varargs argument for %s between "
                + "%s..%s" % (ida.atoa(ea), ida.atoa(start_ea))
            )

        if ea == start_ea:
            ea = ida.prev_head(ea)
            continue  # skip the call insn
        elif list(ida.code_refs_from(ea, 0)) != []:
            raise VarargsError(
                "encountered branch/jump while looking for varargs argument "
                + "between %s..%s" % (ida.atoa(ea), ida.atoa(start_ea))
            )

        rd = ida.get_op(ea, 0)
        if rd.val == wanted_reg:
            opvals = ida.get_opvals(ea)  # XXX should try to track stkvar values
            s = ida.get_string(opvals[-1].target)
            if s is not None:
                return s

        ea = ida.prev_head(ea)
        distance += 1