Beispiel #1
0
def get_op(ea, op, stkvars=None):
    '''ea_t -> int -> opt:{int : tinfo_t} -> op_ret'''
    cmd = idautils.DecodeInstruction(ea)
    cmd.Operands = get_operands(cmd)  # for mips_op_hack
    op = mips_op_hack(cmd, op)
    opd = cmd[op]

    if opd.type == idaapi.o_reg:  # gpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.gpr(opd.reg), 0)
    elif opd.type == idaapi.o_idpspec1:  # fpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.fpr(opd.reg), 0)
    elif opd.type in [idaapi.o_near, idaapi.o_mem]:
        return op_ret(op_ty.name, idc.Name(opd.addr), 0)
    elif idc.isStkvar1(idc.GetFlags(ea)):
        # IDA seems to set this flag even for operands beyond the second,
        # i.e. both of these are true for isStkvar1:
        # .text:10003A84                 sd      $a1, 0x2E0+var_58($sp)
        # .text:10003A68                 addiu   $a1, $sp, 0x2E0+var_2D8
        try:
            func = idaapi.get_func(ea)
            off = idaapi.calc_stkvar_struc_offset(func, ea, op)
            (name, ti) = stkvars[off]

            return op_ret_for_ti(ti, name, off, off)
        except KeyError:
            raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea)))
    elif opd.type in [idaapi.o_imm, idaapi.o_displ]:
        return cpu_ida.ida_current_cpu().data.get_op_addrmode(ea, op, cmd)
    else:
        raise OperandUnresolvableError('unable to get operand %u at %s' % (op, idc.atoa(ea)))
Beispiel #2
0
def get_op(ea, op, stkvars=None):
    '''ea_t -> int -> opt:{int : tinfo_t} -> op_ret'''
    cmd = idautils.DecodeInstruction(ea)
    cmd.Operands = get_operands(cmd)  # for mips_op_hack
    op = mips_op_hack(cmd, op)
    opd = cmd[op]

    if opd.type == idaapi.o_reg:  # gpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.gpr(opd.reg), 0)
    elif opd.type == idaapi.o_idpspec1:  # fpr, XXX sorta MIPS-specific
        return op_ret(op_ty.reg, regs.fpr(opd.reg), 0)
    elif opd.type in [idaapi.o_near, idaapi.o_mem]:
        return op_ret(op_ty.name, idc.Name(opd.addr), 0)
    elif idc.isStkvar1(idc.GetFlags(ea)):
        # IDA seems to set this flag even for operands beyond the second,
        # i.e. both of these are true for isStkvar1:
        # .text:10003A84                 sd      $a1, 0x2E0+var_58($sp)
        # .text:10003A68                 addiu   $a1, $sp, 0x2E0+var_2D8
        try:
            func = idaapi.get_func(ea)
            off = idaapi.calc_stkvar_struc_offset(func, ea, op)
            (name, ti) = stkvars[off]

            return op_ret_for_ti(ti, name, off, off)
        except KeyError:
            raise OperandUnresolvableError('unable to get operand %u at %s' %
                                           (op, idc.atoa(ea)))
    elif opd.type in [idaapi.o_imm, idaapi.o_displ]:
        return cpu_ida.ida_current_cpu().data.get_op_addrmode(ea, op, cmd)
    else:
        raise OperandUnresolvableError('unable to get operand %u at %s' %
                                       (op, idc.atoa(ea)))
Beispiel #3
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
Beispiel #4
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