Beispiel #1
0
def convert_reg(reg_name, width):
    """Convert given register name to the register name for the provided width (eg: conver_reg(eax, 8) -> rax)"""
    reg_idx = ida_idp.str2reg(reg_name)
    if reg_idx > 15:  # R15 is index 15.  8-bit registers have indexes above 15 but are 0 indexed, so sub 16
        reg_idx -= 16

    return ida_idp.get_reg_name(reg_idx, width)
Beispiel #2
0
def is_lea_r8_mem_inst(inst):
    if inst.get_canon_mnem() == 'lea':
        if inst.Op1.type == ida_ua.o_reg:
            if inst.Op1.reg == ida_idp.str2reg('r8'):
                if inst.Op2.type == ida_ua.o_mem:
                    return True
    return False
Beispiel #3
0
def is_locate_protocol_param(xref):
    """
    Returns True if the xref is the 'Protocol' parameter of this function :
    typedef EFI_STATUS LocateProtocol (
        IN  EFI_GUID *Protocol,
        IN  VOID     *Registration OPTIONAL,
        OUT VOID     **Interface
    );
    """
    inst = idautils.DecodeInstruction(xref)

    if inst is None:
        return False

    # Must be 'lea rcx, gSmtGuid'
    if inst.get_canon_mnem() != 'lea' or inst.Op1.type != ida_ua.o_reg or \
       inst.Op1.reg != ida_idp.str2reg('rcx'):
        return False

    # Look up to 5 instructions ahead to find:
    # call    [rax+EFI_BOOT_SERVICES.LocateProtocol]
    for addr in get_func_items_from_xref(xref)[:5]:
        inst = idautils.DecodeInstruction(addr)
        if inst.get_canon_mnem() == 'call':
            if inst.Op1.type == ida_ua.o_displ and \
               get_operand_struct_name(inst, 0) == 'EFI_BOOT_SERVICES' and \
               inst.Op1.addr == 0x140:
                return True
            else:
                # Bail out if we hit a call that is not LocateProtocol
                break

    return False
Beispiel #4
0
 def ev_ana_insn(self, insn):
     t_reg = ida_idp.str2reg("T")
     t = ida_segregs.get_sreg(insn.ea, t_reg)
     if t==0 and ida_bytes.get_wide_dword(insn.ea) == 0xE7F001F2:
         insn.itype = ITYPE_BUGINSN
         insn.size = 4
     elif t!=0 and ida_bytes.get_wide_word(insn.ea) == 0xde02:
         insn.itype = ITYPE_BUGINSN
         insn.size = 2
     return insn.size
Beispiel #5
0
def x86_index_reg(insn, op):
    """Get the index register (if there is one) (handle 16-bit as well for completeness)"""
    if has_sib(op):
        idx = sib_index(insn, op)
        if idx != 4:
            return idx

        return -1  # There is no index register

    if not ad16(insn):
        return -1

    if op.phrase in (0, 2):  # ([BX+SI], [BP+SI])
        return ida_idp.str2reg("RSI")

    if op.phrase in (1, 3):  # ([BX+DI], [BP+DI])
        return ida_idp.str2reg("RDI")

    if op.phrase in (4, 5, 6, 7):  # ([SI], [DI], [BP], [BX])
        return -1

    raise ValueError("Unable to parse x86 index register from instruction")
Beispiel #6
0
def x86_base_reg(insn, op):
    """Get the base register of the operand with a displacement (handle 16-bit as well for completeness)"""
    if has_sib(op):
        return sib_base(insn, op)  # base register encoded in the SIB

    if not ad16(insn):
        return op.phrase  # "phrase" contains the base register number

    if signed(op.phrase, get_bits()) == -1:
        return idautils.procregs.sp.reg  # return "*SP" register number (4)

    if op.phrase in (0, 1, 7):  # ([BX+SI], [BX+DI], [BX])
        return ida_idp.str2reg("RBX")  # All versions of *BX return 3

    if op.phrase in (2, 3, 6):  # ([BP+SI], [BP+DI], [BP])
        return ida_idp.str2reg("RBP")  # All versions of *BP return 5

    if op.phrase == 4:  # [SI]
        return ida_idp.str2reg("RSI")

    if op.phrase == 5:  # [DI]
        return ida_idp.str2reg("RDI")

    raise ValueError("Unable to parse x86 base register from instruction")
def find_params(xref):
    str_len = 0
    str_addr = 0
    curr_addr = xref.frm
    i = 0
    while (str_len == 0 or str_addr == 0) and i < 10:
        inst, _ = idautils.DecodePrecedingInstruction(curr_addr)
        if inst.get_canon_mnem() == 'mov' and inst.Op1.type == o_reg and \
           inst.Op1.reg == ida_idp.str2reg('edx') and inst.Op2.type == o_imm:
            str_addr = inst.Op2.value
        elif inst.get_canon_mnem() == 'push':
            str_len = inst.Op1.value
        i += 1

        curr_addr = inst.ea
    return str_addr, str_len
Beispiel #8
0
def find_params(xref):
    str_len = 0
    str_addr = 0
    curr_addr = xref.frm
    i = 0
    while (str_len == 0 or str_addr == 0) and i < 10:
        inst, _ = idautils.DecodePrecedingInstruction(curr_addr)
        if inst.get_canon_mnem() == 'mov' and inst.Op1.type == o_reg and \
           inst.Op1.reg == ida_idp.str2reg('edx') and inst.Op2.type == o_imm:
            str_addr = inst.Op2.value
        elif inst.get_canon_mnem() == 'push':
            str_len = inst.Op1.value
        i += 1

        curr_addr = inst.ea
    return str_addr, str_len
Beispiel #9
0
def get_ymm_mreg(xmm_mreg):
    """
    Return the YMM microcode register for a given XMM register.
    """
    xmm_reg = ida_hexrays.mreg2reg(xmm_mreg, XMM_SIZE)
    xmm_name = ida_idp.get_reg_name(xmm_reg, XMM_SIZE)
    xmm_number = int(xmm_name.split("mm")[-1])

    # compute the ymm mreg id
    ymm_reg = ida_idp.str2reg("ymm%u" % xmm_number)
    ymm_mreg = ida_hexrays.reg2mreg(ymm_reg)

    # sanity check...
    xmm_name = ida_hexrays.get_mreg_name(xmm_mreg, XMM_SIZE)
    ymm_name = ida_hexrays.get_mreg_name(ymm_mreg, YMM_SIZE)
    assert xmm_name[1:] == ymm_name[
        1:], "Reg escalation did not work... (%s, %s)" % (xmm_name, ymm_name)

    # return the ymm microcode register id
    return ymm_mreg
Beispiel #10
0
def load_file(li, neflags, format):
    flags = ida_idp.SETPROC_LOADER_NON_FATAL | ida_idp.SETPROC_LOADER
    ida_idp.set_processor_type("arm", flags)

    header = parse_header(li)
    offset = header.header_size
    while True:
        li.seek(offset)
        if li.read(1) != b'\x00':
            break
        offset += 1
    length = header.content_size - (offset - header.header_size)

    seg = ida_segment.segment_t()
    seg.start_ea = header.base_address
    seg.end_ea = seg.start_ea + length
    seg.bitness = 1
    ida_segment.add_segm_ex(seg, "ROM", "CODE", 0)

    li.file2base(offset, seg.start_ea, seg.end_ea - 1, 0)
    ida_segregs.split_sreg_range(seg.start_ea, ida_idp.str2reg("T"), 1,
                                 ida_segregs.SR_user)
    return 1