Пример #1
0
def get_op_addrmode(ea, op, cmd):
    '''ea_t -> int -> insn_t -> op_ret'''
    # the ida module calls back into this module to deal with some MIPS-specific
    # operand handling here
    mnem = ida.get_mnem(ea)
    op = ida.mips_op_hack(cmd, op)

    if cmd[op].type == ida.o_imm:
        val = cmd[op].value
    elif cmd[op].type == ida.o_displ:
        val = cmd[op].addr
    else:
        raise utils.BugError('neither imm nor displ passed to get_op_addrmode')

    if mnem in insns.has_special_opnd:
        target = val
        return ida.resolve_opnd(target, val)
    # addiu is often used for address calculation, which IDA will resolve to a
    # name, so handle addiu's immval only if we fail to resolve it later
    elif mnem != 'addiu' and mnem in insns.has_imm:
        return ida.op_ret(ida.op_ty.value, immval(val), 0)
    else:
        target = ida.calc_target(ea, ea, op, immval(val))
        if target == ida.BADADDR and cmd[op].type == ida.o_displ:
            reg = cmd[op].reg
            if reg >= 0 and reg <= 31:
                reg = regs.gpr(reg)
            elif reg >= 32 and reg <= 63:
                reg = regs.fpr(reg)
            else:
                raise utils.BugError('bogus register %u' % reg)
            return ida.op_ret(ida.op_ty.displ,
                              ida.displ(reg=reg,
                                        displ=immval(val)),
                              0)
        else:
            opnd = ida.resolve_opnd(target, val)
            if mnem == 'addiu' and opnd.ty == ida.op_ty.value:
                # addiu is being used for regular addition; handle its third
                # operand as an immediate value
                return ida.op_ret(ida.op_ty.value, immval(opnd.val), 0)
            else:
                return opnd
Пример #2
0
def get_callee(ea, mnem, args):
    '''ea_t -> str -> formatter_args -> str'''
    # XXX we don't handle function pointers yet, but it should be easy now that
    # we handle all internal functions as having the same signature...i think
    if mnem == 'jalr':
        nn = ida.netnode('$ mips')
        fun = nn.altval(ea) - 1
        if fun == -1:
            raise FunctionPointerError(
                'unknown target for function pointer at %s'
                % ida.atoa(ea))
        return ida.name(fun)
    elif mnem == 'jal':
        return args['rs'].name
    else:
        raise utils.BugError('unhandled call insn: %s' % mnem)
Пример #3
0
def get_args_for_va_function(callee, pos_arg):
    '''str -> str -> [(reg_type, slot_type) | None]'''
    def get_convs(acc, va_arg):
        return acc + [sw[va_arg.type]]

    pos_sw = {'printf' : (1, printf_sw, printf_parse, va_wrap),
              'scanf' : (1, scanf_sw, scanf_parse, pos_wrap),
              'sscanf' : (2, scanf_sw, scanf_parse, pos_wrap)}
    try:
        (pos, sw, fn, chooser) = pos_sw[callee]
    except KeyError:
        raise utils.BugError('unrecognized callee %s' % callee)

    (_, args) = fn(pos_arg)
    convs = reduce(get_convs, args.arg, [])

    return list(get_info_for_types(
        convs, lambda x: x, chooser, pos=pos, handle_va=True))
Пример #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
Пример #5
0
 def __init__(self, reg):
     if type(self) is reg_base:
         raise utils.BugError('reg_base cannot be directly instantiated')
     self.reg = reg
Пример #6
0
def initlist(arg):
    if type(arg) is not list:
        raise utils.BugError('non-list passed')
    return c_ast.InitList(arg)
Пример #7
0
 def __init__(self, value):
     tyty = type(value)
     if tyty is not float:
         raise utils.BugError('must be float, not %s' % tyty.__name__)
     self.value = value