Python idc.print_operand() Examples

The following are 14 code examples of idc.print_operand(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module idc , or try the search function .
Example #1
Source File: klfdb.py    From ActionScript3 with GNU General Public License v3.0 6 votes vote down vote up
def get_stack_vars(self, start, end):

		stackvars = {}
	
		ea = start
		while (ea < end):
	
			if ("ebp" in idc.print_operand(ea, 0) and idc.get_operand_type(ea, 1) == idc.o_imm):
	
				op0 = idc.get_operand_value(ea, 0)
				op1 = idc.get_operand_value(ea, 1)
	
				if (op0 in stackvars):
					stackvars[op0]["values"].append(op1)
				else:
					stackvars[op0] = {"values": [], "hits": 0}
	
			ea += idc.get_item_size(ea)

		return stackvars 
Example #2
Source File: code_grafter.py    From flare-ida with Apache License 2.0 6 votes vote down vote up
def _get_imp_for_register_call(self, va_call, nm=None):
        if idc.print_insn_mnem(va_call) != 'call':
            msg = 'va_call must be the virtual address of a call instruction'
            raise ValueError(msg)

        reg = idc.print_operand(va_call, 0)
        va_mov = mykutils.find_instr(va_call, 'up', 'mov',
                                     [(0, 1, reg), (1, 2, None)])
        if not va_mov:
            return None

        if nm and (nm not in idc.print_operand(va_mov, 1)):
            return None

        va_imp = idc.get_operand_value(va_mov, 1)
        return va_imp 
Example #3
Source File: instruction.py    From Sark with MIT License 5 votes vote down vote up
def text(self):
        return idc.print_operand(self._ea, self.n) 
Example #4
Source File: Main.py    From Virtuailor with GNU General Public License v3.0 5 votes vote down vote up
def add_bp_to_virtual_calls(cur_addr, end):
    while cur_addr < end:
        if cur_addr == idc.BADADDR:
            break
        elif idc.print_insn_mnem(cur_addr) == 'call' or idc.print_insn_mnem(cur_addr) == 'BLR':
            if True in [idc.print_operand(cur_addr, 0).find(reg) != -1 for reg in REGISTERS]:  # idc.GetOpnd(cur_addr, 0) in REGISTERS:
                cond, bp_address = vtableAddress.write_vtable2file(cur_addr)
                if cond != '':
                    bp_vtable = AddBP.add(bp_address, cond)
        cur_addr = idc.next_head(cur_addr) 
Example #5
Source File: quicktime.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def getDispatchCode(ea):
    # get dispatch code out of an instruction
    first, second = (idc.print_operand(ea, 0), idc.get_operand_value(ea, 1))
    if first == 'eax':
        return second
    raise ValueError("Search resulted in address %08x, but instruction '%s' does fulfill requested constraints"% (ea, idc.print_insn_mnem(ea))) 
Example #6
Source File: quicktime.py    From ida-minsc with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def FindLastAssignment(ea, register):
    start,end = database.guessrange(ea)
    while ea > start:
        ea = database.prev(ea)
        m = idc.print_insn_mnem(ea)
        r = idc.print_operand(ea, 0)

        if m == 'mov' and r == register:
            return ea
        continue

    raise ValueError('FindLastAssignment(0x%x, %s) Found no matches'% (ea, register)) 
Example #7
Source File: klfdb.py    From ActionScript3 with GNU General Public License v3.0 5 votes vote down vote up
def set_jit_info(self, method_id, start):

		end = self.get_func_end(start)

		if (end < start or end - start > self.jit_max_size):
			return

		method = next((x for x in self.as3dump if x["id"] == method_id), None)

		if (method is None):
			return

		stackvars = self.get_stack_vars(start, end)
		save_eip = self.get_save_eip(method, stackvars)

		ea = start
		while (ea < end):
	
			if ("ebp" in idc.print_operand(ea, 0) and idc.get_operand_type(ea, 1) == idc.o_imm):
	
				op0 = idc.get_operand_value(ea, 0)
				op1 = idc.get_operand_value(ea, 1)
	
				if (op0 == save_eip):
					idc.set_cmt(ea, method["instructions"][op1], 0)
		
			ea += idc.get_item_size(ea) 
Example #8
Source File: vtableAddress.py    From Virtuailor with GNU General Public License v3.0 4 votes vote down vote up
def get_con2_var_or_num(i_cnt, cur_addr):
    """
    :param i_cnt: the register of the virtual call
    :param cur_addr: the current address in the memory
    :return: "success" string and the address of the vtable's location. if it fails it sends the reason and -1
    """
    start_addr = idc.get_func_attr(cur_addr, idc.FUNCATTR_START)
    virt_call_addr = cur_addr
    cur_addr = idc.prev_head(cur_addr)
    dct_arch = get_arch_dct()
    if dct_arch == -1:
        return 'Wrong Architechture', "-1", cur_addr

    while cur_addr >= start_addr:
        if idc.print_insn_mnem(cur_addr)[:3] == dct_arch["opcode"] and idc.print_operand(cur_addr, 0) == i_cnt:  # TODO lea ?
            opnd2 = idc.print_operand(cur_addr, 1)
            place = opnd2.find(dct_arch["separator"])
            if place != -1:  # if the function is not the first in the vtable
                register = opnd2[opnd2.find('[') + 1: place]
                if opnd2.find('*') == -1:
                    offset = opnd2[place + dct_arch["val_offset"]: opnd2.find(']')]
                else:
                    offset = "*"
                return register, offset, cur_addr
            else:
                offset = "0"
                if opnd2.find(']') != -1:
                    register = opnd2[opnd2.find('[') + 1: opnd2.find(']')]
                else:
                    register = opnd2
                return register, offset, cur_addr
        elif idc.print_insn_mnem(cur_addr)[:4] == "call":
            intr_func_name = idc.print_operand(cur_addr, 0)
            # In case the code has CFG -> ignores the function call before the virtual calls
            if "guard_check_icall_fptr" not in intr_func_name:
                if "nullsub" not in intr_func_name:
                    # intr_func_name = idc.Demangle(intr_func_name, idc.GetLongPrm(idc.INF_SHORT_DN))
                    print("Warning! At address 0x%08x: The vtable assignment might be in another function (Maybe %s),"
                          " could not place BP." % (virt_call_addr, intr_func_name))
                cur_addr = start_addr
        cur_addr = idc.prev_head(cur_addr)
    return "out of the function", "-1", cur_addr

    return '', 0, cur_addr 
Example #9
Source File: vtableAddress.py    From Virtuailor with GNU General Public License v3.0 4 votes vote down vote up
def write_vtable2file(start_addr):
    """
    :param start_addr: The start address of the virtual call
    :return: The break point condition and the break point address
    """
    raw_opnd = idc.print_operand(start_addr, 0)
    if raw_opnd in REGISTERS:
        reg = raw_opnd
    else:
        for reg in REGISTERS:
            if raw_opnd.find(reg) != -1:
                break
    opnd = get_con2_var_or_num(reg, start_addr)
    reg_vtable = opnd[0]
    offset = opnd[1]
    bp_address = opnd[2]
    set_bp = True
    cond = ""
    # TODO check the get_con2 return variables!!@
    try:
        # TODO If a structure was already assigned to the BP (not by Virtuailor), before running the code the code will\
        # assume it was examined by the user, the BP will not be set
        arch_dct = get_arch_dct()
        plus_indx = raw_opnd.find(arch_dct["separator"])
        if plus_indx != -1:
            call_offset = raw_opnd[plus_indx + 1:raw_opnd.find(']')]
            # if the offset is in hex
            if call_offset.find('h') != -1:
                call_offset = int(call_offset[:call_offset.find('h')], 16)
        if offset.find('h') != -1:
            offset = str(int(offset[:offset.find('h')], 16))
        elif offset.find('0x') != -1:
            offset = str(int(offset[offset.find('0x') + 2:], 16))
    except ValueError:
        # A offset structure was set, the old offset will be deleted
        set_bp = False
    finally:
        if set_bp:
            # start_addr = start_addr - idc.SegStart(start_addr)
            if reg_vtable in REGISTERS:
                cond = get_bp_condition(start_addr, reg_vtable, offset)
    return cond, bp_address 
Example #10
Source File: analyser.py    From UEFI_RETool with MIT License 4 votes vote down vote up
def set_types(self):
        """
        handle (EFI_BOOT_SERVICES *) type
        and (EFI_SYSTEM_TABLE *) for x64 images
        """
        RAX = 0
        O_REG = 1
        O_MEM = 2
        EFI_BOOT_SERVICES = 'EFI_BOOT_SERVICES *'
        EFI_SYSTEM_TABLE = 'EFI_SYSTEM_TABLE *'
        empty = True
        for service in self.gBServices:
            for address in self.gBServices[service]:
                ea = address
                num_of_attempts = 10
                for _ in range(num_of_attempts):
                    ea = idc.prev_head(ea)
                    if (idc.print_insn_mnem(ea) == 'mov'
                            and idc.get_operand_type(ea, 1) == O_MEM):
                        if (idc.get_operand_type(ea, 0) == O_REG
                                and idc.get_operand_value(ea, 0) == RAX):
                            gvar = idc.get_operand_value(ea, 1)
                            gvar_type = idc.get_type(gvar)
                            # if (EFI_SYSTEM_TABLE *)
                            if ((gvar_type != 'EFI_SYSTEM_TABLE *')
                                    and (idc.print_operand(
                                        address, 0).find('rax') == 1)):
                                if self._find_est(gvar, ea, address):
                                    # yapf: disable
                                    print('[ {0} ] Type ({type}) successfully applied'.format(
                                            '{addr:#010x}'.format(addr=gvar),
                                            type=EFI_SYSTEM_TABLE))
                                    empty = False
                                    break
                            # otherwise it (EFI_BOOT_SERVICES *)
                            if (gvar_type != 'EFI_BOOT_SERVICES *'
                                    and gvar_type != 'EFI_SYSTEM_TABLE *'):
                                if idc.SetType(gvar, EFI_BOOT_SERVICES):
                                    empty = False
                                    idc.set_name(
                                        gvar,
                                        'gBs_{addr:#x}'.format(addr=gvar))
                                    # yapf: disable
                                    print('[ {0} ] Type ({type}) successfully applied'.format(
                                            '{addr:#010x}'.format(addr=gvar),
                                            type=EFI_BOOT_SERVICES))
                            break
        if empty:
            print(' * list is empty') 
Example #11
Source File: objc2_analyzer.py    From flare-ida with Apache License 2.0 4 votes vote down vote up
def getIvarTypeFromFunc(self, eh, va):
        if va in self.ivarSetters:
            return self.ivarSetters[va]
        elif va in self.notIvarSetters:
            return UNKNOWN
        addr = va
        endVa = idc.get_func_attr(va, idc.FUNCATTR_END)
        if endVa - va < 0x20:
            ivarVa = None
            while addr <= endVa:
                srcOpnd = idc.print_operand(addr, 1)
                # if ivar is the src op for an instruction, assume this function will return it
                if eh.arch == unicorn.UC_ARCH_ARM and "_OBJC_IVAR_$_" in srcOpnd:
                    oploc = idc.get_name_ea_simple(
                        srcOpnd[srcOpnd.find("_OBJC_IVAR_$_"):srcOpnd.find(" ")])
                    if oploc != idc.BADADDR:
                        ivarVa = oploc
                        break
                elif eh.arch == unicorn.UC_ARCH_ARM64:
                    for x in idautils.XrefsFrom(addr):
                        if (idc.get_segm_name(x.to) == "__objc_ivar" and
                                idc.get_name(x.to, idc.ida_name.GN_VISIBLE)[:13] == "_OBJC_IVAR_$_"):
                            ivarVa = x.to
                            break
                elif eh.arch == unicorn.UC_ARCH_X86:
                    if "_OBJC_IVAR_$_" in srcOpnd:
                        ivarVa = idc.get_operand_value(addr, 1)
                        break

                addr = idc.next_head(addr, idc.get_inf_attr(idc.INF_MAX_EA))

            if ivarVa:
                for x in idautils.XrefsTo(ivarVa):
                    if x.frm >= self.objcConst[0] and x.frm < self.objcConst[1]:
                        typeStr = eh.getIDBString(
                            eh.derefPtr(x.frm + eh.size_pointer * 2))
                        self.ivarSetters[va] = typeStr[2:-1]
                        logging.debug("%s is an ivar getter function, returning type %s" % (
                            eh.hexString(va), typeStr[2:-1]))
                        return typeStr[2:-1]
            else:
                logging.debug(
                    "%s determined not to be an ivar getter function", eh.hexString(va))
                self.notIvarSetters.append(va)
        else:
            logging.debug(
                "%s determined not to be an ivar getter function", eh.hexString(va))
            self.notIvarSetters.append(va)
        return UNKNOWN


    # returns class or sel name from IDA name 
Example #12
Source File: mykutils.py    From flare-ida with Apache License 2.0 4 votes vote down vote up
def is_conformant_operand(va, op_spec):
    """Check that operand conforms to specification.

    Args:
        va (numbers.Integral): Virtual address of instruction to assess.
        op_spec (OpSpec): Operand specification tuple (operand position, type,
            and name)

    Returns:
        True if conformant
        False if nonconformant
    """
    spec = OpSpec(*op_spec)  # Make it convenient to pass plain tuples

    if (spec.pos is None) or ((not spec.name) and (not spec.type)):
        msg = 'Must specify an operand position and either a name or type'
        raise ValueError(msg)

    if spec.type is not None and idc.get_operand_type(va, spec.pos) != spec.type:
        return False

    if spec.name is not None:
        # For two types:
        #   o_phrase = 3 Base + Index
        #   o_displ =  4 Base + Index + Displacement
        # Use substring matching to compensate for IDA Pro's representation
        if spec.type in (ida_ua.o_phrase, ida_ua.o_displ):
            if spec.name not in idc.print_operand(va, spec.pos):
                return False

        # For these types:
        #   o_imm =  5   Immediate
        #   o_far =  6   Immediate Far Address
        #   o_near = 7   Immediate Near Address
        # Check both address and name
        elif spec.type in (ida_ua.o_imm, ida_ua.o_far, ida_ua.o_near):
            if isinstance(spec.name, basestring):
                if idc.print_operand(va, spec.pos) != spec.name:
                    return False
            elif idc.get_operand_value(va, spec.pos) != spec.name:
                return False
        else:
            if idc.print_operand(va, spec.pos) != spec.name:
                return False

    return True


###############################################################################
# Code Carving i.e. function extraction
###############################################################################
# Why:
# * To extract whole funtions for emulation, shellcode crafting, or other
#   external processing.
# * To extend Code Grafting by adding function opcodes to the library already
#   present there.
#
# Code Grafting allows you to graft static implementations of imported
# functions into your IDB for purposes of emulation in Bochs IDB mode or by
# other emulators. For instructions on adding synthetic import implementations
# to the Code Grafting library for use with your binary, see `code_grafter.py`. 
Example #13
Source File: code_grafter.py    From flare-ida with Apache License 2.0 4 votes vote down vote up
def _patchCalls(self):
        def do_patch_call(va):
            retval = False
            stub_loc = idc.get_name_ea_simple(self._stubname(nm))

            # Preserve original disassembly and format new comment
            old_target = idc.print_operand(va, 0)
            orig_cmt = idc.get_cmt(va, 0) or ''
            new_cmt = '%s\n\t%s' % (g_patched_call_cmt, idc.GetDisasm(va))

            if idc.get_operand_type(va, 0) == ida_ua.o_mem:
                retval = patch_import(va, self._stubname(nm))
                new_cmt += '\n%s %s to %s)' % (g_cmt_pointed, old_target,
                                               self._stubname(nm))
            elif idc.get_operand_type(va, 0) == ida_ua.o_reg:
                va_imp = self._get_imp_for_register_call(va, nm)
                if va_imp:
                    patch_pointer_width(va_imp, stub_loc)
                    retval = True
                else:
                    logger.warn('Could not find import to patch call at %s' %
                                (phex(va)))

            else:  # Usually optype 7 otherwise
                # Won't work if displacement exceeds 32-bit operand size
                call_offset_loc = va + idc.get_item_size(va)
                if abs(call_offset_loc - stub_loc) > 0x100000000:
                    msg = ('Call site at %s too far from %s (%s)' %
                           (phex(va), self._stubname(nm), phex(stub_loc)))
                    raise CodeGraftingDisplacementError(msg)
                retval = patch_call(va, self._stubname(nm))

            if retval:
                if orig_cmt:
                    new_cmt += '\n%s' % (orig_cmt)
                idc.set_cmt(va, new_cmt, 0)
                ida_xref.add_cref(va, stub_loc, ida_xref.fl_CN)

            return retval

        for names in self._emu_stubs.keys():
            for nm in names:
                va = idc.get_name_ea_simple(nm)
                mykutils.for_each_call_to(do_patch_call, va)

        for nm, aliases in g_allocators_aliases.items():
            for alias in aliases:
                # do_patch_call closure will turn <nm> into stub_<nm>
                mykutils.for_each_call_to(do_patch_call,
                                          idc.get_name_ea_simple(alias)) 
Example #14
Source File: code_grafter.py    From flare-ida with Apache License 2.0 4 votes vote down vote up
def patch_call(va, new_nm):
    """Patch the call at @va to target @new_nm.

    Args:
        va (numbers.Integral): Address of the call site
        new_nm (str): Name of the new call destination

    Returns:
        bool: True if successful
    """
    is_call = idc.print_insn_mnem(va) == 'call'

    if is_call:
        opno = 0
        new_asm = 'call %s' % (new_nm)
    else:
        logger.warn('Not a call instruction at %s' % (phex(va)))
        return False

    # Already done?
    if idc.print_operand(va, opno) == new_nm:
        return True

    ok, code = idautils.Assemble(va, new_asm)

    if not ok:
        logger.warn('Failed assembling %s: %s' % (phex(va), new_asm))
        return False

    orig_opcode_len = idc.get_item_size(va)
    new_code_len = len(code)

    if orig_opcode_len < new_code_len:
        logger.warn('Not enough room or wrong opcode type to patch %s: %s' %
                    (phex(va), new_asm))
        return False

    # If we actually have too much room, then add filler
    if orig_opcode_len > new_code_len:
        delta = orig_opcode_len - new_code_len
        code += '\x90' * delta

    idaapi.patch_bytes(va, code)

    return True