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)
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
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
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
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")
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
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
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
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