Python idc.get_item_size() Examples

The following are 16 code examples of idc.get_item_size(). These examples are extracted from open source projects. 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 Project: GhIDA   Author: Cisco-Talos   File: idaxml.py    License: Apache License 2.0 6 votes vote down vote up
def get_data_value(self, addr):
        """
        Returns the data item value at an address based on its size.

        Args:
            addr: Integer representing a program address.
        """
        size = idc.get_item_size(addr) * self.cbsize
        if size == 1:
            return ida_bytes.get_byte(addr)
        if size == 2:
            return ida_bytes.get_16bit(addr)
        if size == 4:
            return ida_bytes.get_32bit(addr)
        if size == 8:
            return ida_bytes.get_64bit(addr)
        return 0 
Example #2
Source Project: GhIDA   Author: Cisco-Talos   File: idaxml.py    License: Apache License 2.0 6 votes vote down vote up
def import_codeblock(self, code_block):
        """
        Processes a CODE_BLOCK element by disassembling the address range.

        Args:
            code_block: XML element containing codeblock start and end
                addresses.
        """
        if self.options.CodeBlocks.checked == False:
            return
        start = self.get_address(code_block, START)
        end = self.get_address(code_block, END)
        ida_bytes.del_items(start, 3, end - start + 1)
        addr = start
        while (addr <= end):
            length = ida_ua.create_insn(addr)
            addr += ida_bytes.get_item_size(addr) * self.get_cbsize()
        self.update_counter(CODE_BLOCK) 
Example #3
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 6 votes vote down vote up
def _stop_looking_for_xrefs(ea):
  """This is a heuristic to decide whether or not we should stop looking for
  cross-references. It is relevant to IDA structs, where IDA will treat structs
  and everything in them as one single 'thing', and so all xrefs embedded within
  a struct will actually be associated with the first EA of the struct. So
  if we're in a struct or something like it, and the item size is bigger than
  the address size, then we will assume it's actually in a struct."""
  
  if is_external_segment(ea):
    return False

  if is_code(ea):
    return False

  addr_size = get_address_size_in_bytes()
  item_size = idc.get_item_size(ea)
  return item_size > addr_size 
Example #4
Source Project: mcsema   Author: lifting-bits   File: get_cfg.py    License: Apache License 2.0 6 votes vote down vote up
def recover_external_variables(M):
  """Reover the named external variables (e.g. `stdout`) that are referenced
  within this binary."""
  global EXTERNAL_VARS_TO_RECOVER, WEAK_SYMS

  for ea, name in EXTERNAL_VARS_TO_RECOVER.items():
    EV = M.external_vars.add()
    EV.ea = ea
    EV.name = name.format('utf-8')
    EV.is_weak = idaapi.is_weak_name(ea) or (name in WEAK_SYMS)
    EV.is_thread_local = is_tls(ea)
    if name in EMAP_DATA:
      EV.size = EMAP_DATA[name]
    else:
      EV.size = idc.get_item_size(ea)
    if EV.is_thread_local:
      DEBUG("Recovering extern TLS variable {} at {:x} [size: {}]".format(name, ea, EV.size))
    else:
      DEBUG("Recovering extern variable {} at {:x} [size: {}]".format(name, ea, EV.size)) 
Example #5
Source Project: ActionScript3   Author: KasperskyLab   File: klfdb.py    License: 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 #6
Source Project: mcsema   Author: lifting-bits   File: exception.py    License: Apache License 2.0 5 votes vote down vote up
def make_array(ea, size):
  if ea != idc.BADADDR and ea != 0:
    flags = idc.get_full_flags(ea)
    if not idc.isByte(flags) or idc.get_item_size(ea) != 1:
      idc.del_items(ea, idc.DOUNK_SIMPLE, 1)
      idc.MakeByte(ea)
    idc.MakeArray(ea, size) 
Example #7
Source Project: mcsema   Author: lifting-bits   File: get_cfg.py    License: Apache License 2.0 5 votes vote down vote up
def recover_region(M, region_name, region_ea, region_end_ea, exported_vars):
  """Recover the data and cross-references from a segment. The data of a
  segment is stored verbatim within the protobuf, and accompanied by a
  series of variable and cross-reference entries."""

  seg_name = idc.get_segm_name(region_ea)

  DEBUG("Recovering region {} [{:x}, {:x}) in segment {}".format(
      region_name, region_ea, region_end_ea, seg_name))

  seg = idaapi.getseg(region_ea)

  # An item spans two regions. This may mean that there's a reference into
  # the middle of an item. This happens with strings.
  item_size = idc.get_item_size(region_end_ea - 1)
  if 1 < item_size:
    DEBUG("  ERROR: Segment should probably include {} more bytes".format(
        item_size - 1))

  S = M.segments.add()
  S.ea = region_ea
  S.data = read_bytes_slowly(region_ea, region_end_ea)
  S.read_only = (seg.perm & idaapi.SEGPERM_WRITE) == 0
  S.is_external = is_external_segment_by_flags(region_ea)
  S.is_thread_local = is_tls_segment(region_ea)
  S.name = seg_name.format('utf-8')
  S.is_exported = region_ea in exported_vars

  if region_name != seg_name:
    S.variable_name = region_name.format('utf-8')

  DEBUG_PUSH()
  recover_region_cross_references(M, S, region_ea, region_end_ea)
  recover_region_variables(M, S, region_ea, region_end_ea, exported_vars)
  DEBUG_POP() 
Example #8
Source Project: LazyIDA   Author: L4ys   File: LazyIDA.py    License: MIT License 5 votes vote down vote up
def finish_populating_widget_popup(self, form, popup):
        form_type = idaapi.get_widget_type(form)

        if form_type == idaapi.BWN_DISASM or form_type == idaapi.BWN_DUMP:
            t0, t1, view = idaapi.twinpos_t(), idaapi.twinpos_t(), idaapi.get_current_viewer()
            if idaapi.read_selection(view, t0, t1) or idc.get_item_size(idc.get_screen_ea()) > 1:
                idaapi.attach_action_to_popup(form, popup, ACTION_XORDATA, None)
                idaapi.attach_action_to_popup(form, popup, ACTION_FILLNOP, None)
                for action in ACTION_CONVERT:
                    idaapi.attach_action_to_popup(form, popup, action, "Convert/")

        if form_type == idaapi.BWN_DISASM and (ARCH, BITS) in [(idaapi.PLFM_386, 32),
                                                               (idaapi.PLFM_386, 64),
                                                               (idaapi.PLFM_ARM, 32),]:
            idaapi.attach_action_to_popup(form, popup, ACTION_SCANVUL, None) 
Example #9
Source Project: ActionScript3   Author: KasperskyLab   File: klfdb.py    License: GNU General Public License v3.0 5 votes vote down vote up
def get_func_end(self, start):

		if (idc.add_func(start)):
			return idc.find_func_end(start)

		ea = start
		while (idc.get_wide_byte(ea) != 0xCC):
			idc.create_insn(ea)
			ea += idc.get_item_size(ea)

			if (ea - start > self.jit_max_size):
				return 0

		return ea 
Example #10
Source Project: ActionScript3   Author: KasperskyLab   File: klfdb.py    License: 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 #11
Source Project: flare-ida   Author: fireeye   File: code_grafter.py    License: Apache License 2.0 5 votes vote down vote up
def _unpatchCalls(self, grafted_segs):
        def do_unpatch_call(va_callsite):
            size = idc.get_item_size(va_callsite)
            ida_xref.del_cref(va_callsite, fva_stub, 0)
            cmt = idc.get_cmt(va_callsite, 0)

            newcmt = cmt

            # Remove automated comments
            if newcmt.startswith(g_patched_call_cmt):
                newcmt = newcmt[newcmt.find('\n') + 1:]
                if newcmt.find('\n') == -1:
                    newcmt = ''
                else:
                    newcmt = newcmt[newcmt.find('\n') + 1:]
                if newcmt.startswith(g_cmt_pointed):
                    if newcmt.find('\n') == -1:
                        newcmt = ''
                    else:
                        newcmt = newcmt[newcmt.find('\n') + 1:]

            if newcmt != cmt:
                idc.set_cmt(va_callsite, newcmt, 0)

            if idc.get_operand_type(va_callsite, 0) == ida_ua.o_mem:
                patch_import(va_callsite, idc.BADADDR)
            elif idc.get_operand_type(va_callsite, 0) == ida_ua.o_reg:
                va_imp = self._get_imp_for_register_call(va_callsite)
                if va_imp:
                    patch_pointer_width(va_imp, idc.BADADDR)
            else:
                revert_patch(va_callsite, size)

        for fva_stub in idautils.Functions():
            for seg in grafted_segs:
                if fva_stub in seg:
                    mykutils.for_each_call_to(do_unpatch_call, fva_stub) 
Example #12
Source Project: vt-ida-plugin   Author: VirusTotal   File: disassembler.py    License: Apache License 2.0 4 votes vote down vote up
def get_opcodes(addr, strict):
    """Get current bytes of the instruction pointed at addr.

    Args:
      addr: address of the current instruction
      strict: be more restrictive when applying wildcards (True) or not (False)

    Returns:
      String: hex-encoded representation of the bytes obtained at addr
    """

    if strict:
      offsets_types = {idaapi.o_far, idaapi.o_mem, idaapi.o_imm}
    else:
      offsets_types = {idaapi.o_far, idaapi.o_mem}

    pattern = ''
    mnem = idautils.DecodeInstruction(addr)

    if mnem is not None:
      op1_type = mnem.Op1.type
      op2_type = mnem.Op2.type

      logging.debug(
          '[VTGREP] Instruction: %s  [%d, %d, %d]',
          idc.generate_disasm_line(addr, 0),
          mnem.itype,
          op1_type,
          op2_type
          )

      inst_len = idc.get_item_size(addr)
      drefs = [x for x in idautils.DataRefsFrom(addr)]

      # Checks if any operand constains a memory address
      if (drefs and
          ((op1_type == idaapi.o_imm) or (op2_type == idaapi.o_imm)) or
          op1_type in offsets_types or op2_type in offsets_types):
        pattern = Disassembler.wildcard_instruction(addr)
      # Checks if the instruction is a CALL (near or far) or
      # if it's a JMP (excluding near jumps)
      else:
        if ((mnem.itype == idaapi.NN_call) or
            (mnem.itype == idaapi.NN_jmp and op1_type != idaapi.o_near)):
          pattern = Disassembler.wildcard_instruction(addr)
        # In any other case, concatenate the raw bytes to the current string
        else:
          pattern = binascii.hexlify(idc.get_bytes(addr, inst_len))
          pattern = pattern.decode('utf-8')
      return pattern
    else: return 0 
Example #13
Source Project: GhIDA   Author: Cisco-Talos   File: idaxml.py    License: Apache License 2.0 4 votes vote down vote up
def export_data(self):
        """
        Exports the data items in the database as <DEFINED_DATA> elements.
        """
        addr = self.min_ea
        if idc.is_data(idc.get_full_flags(addr)) == False:
            addr = ida_bytes.next_that(addr, self.max_ea, idc.is_data)
        if (addr == BADADDR):
            return
        timer = time.clock()
        self.update_status(DATA)
        self.start_element(DATA, True)
        while (addr != BADADDR):
            f = idc.get_full_flags(addr)
            if ida_bytes.is_align(f) == True:
                addr = ida_bytes.next_that(addr, self.max_ea, idc.is_data)
                continue
            dtype = self.get_datatype(addr)
            size = idc.get_item_size(addr)
            ti = ida_nalt.opinfo_t()
            msize = ida_bytes.get_data_elsize(addr, f, ti)
            if ida_bytes.is_struct(f) == True:
                s = idc.get_struc_id(dtype)
                msize = idc.get_struc_size(s)
                if msize == 0:
                    msize = 1
            if idc.is_strlit(f) == False and size != msize:
                dtype = "%s[%d]" % (dtype, size / msize)
            self.start_element(DEFINED_DATA)
            self.write_address_attribute(ADDRESS, addr)
            self.write_attribute(DATATYPE, dtype)
            self.write_numeric_attribute(SIZE, size * self.cbsize)
            # TODO consider using GetTrueNameEx and Demangle
            demangled = ida_name.get_demangled_name(addr,
                                                    DEMANGLED_TYPEINFO, self.inf.demnames, idc.GN_STRICT)
            outbuf = ''
            # TODO: How to handle print_type for data mangled names?
            #outbuf = idaapi.print_type(addr, False)
            if demangled == "'string'":
                demangled == None
            has_typeinfo = ((demangled != None and len(demangled) > 0) or
                            (outbuf != None and len(outbuf) > 0))
            # TODO export_data: add DISPLAY_SETTINGS
            self.close_tag(has_typeinfo)
            if has_typeinfo == True:
                if demangled != None and len(demangled) > 0:
                    self.export_typeinfo_cmt(demangled)
                elif len(outbuf) > 0:
                    self.export_typeinfo_cmt(outbuf)
                self.end_element(DEFINED_DATA)
            addr = ida_bytes.next_that(addr, self.max_ea, idc.is_data)
        self.end_element(DATA)
        self.display_cpu_time(timer) 
Example #14
Source Project: flare-ida   Author: fireeye   File: mykutils.py    License: Apache License 2.0 4 votes vote down vote up
def _emit_fnbytes(emit_instr_cb, header, footer, indent, fva=None, warn=True):
    """Emit function bytes in a format defined by the callback and
    headers/footers provided.

    Warns if any instruction operands are not consistent with
    position-independent code, in which case the user may need to templatize
    the position-dependent portions.
    """
    fva = fva or idc.here()
    fva = idc.get_func_attr(fva, idc.FUNCATTR_START)
    va_end = idc.get_func_attr(fva, idc.FUNCATTR_END)

    # Operand types observed in position-independent code:
    optypes_position_independent = set([
        ida_ua.o_reg,       # 1: General Register (al,ax,es,ds...)
        ida_ua.o_phrase,    # 3: Base + Index
        ida_ua.o_displ,     # 4: Base + Index + Displacement
        ida_ua.o_imm,       # 5: Immediate
        ida_ua.o_near,      # 7: Immediate Near Address
    ])

    # Notably missing because I want to note and handle these if/as they are
    # encountered:
    # ida_ua.o_idpspec0 = 8: FPP register
    # ida_ua.o_idpspec1 = 9: 386 control register
    # ida_ua.o_idpspec2 = 10: 386 debug register
    # ida_ua.o_idpspec3 = 11: 386 trace register

    va = fva
    nm = idc.get_name(fva)
    optypes_found = set()
    s = header.format(name=nm)
    while va not in (va_end, idc.BADADDR):
        size = idc.get_item_size(va)
        the_bytes = idc.get_bytes(va, size)

        for i in range(0, 8):
            optype = idc.get_operand_type(va, i)
            if optype:
                optypes_found.add(optype)

        s += indent + emit_instr_cb(va, the_bytes, size)
        va = idc.next_head(va)
    s += footer

    position_dependent = optypes_found - optypes_position_independent
    if position_dependent:
        msg = ('This code may have position-dependent operands (optype %s)' %
               (', '.join([str(o) for o in position_dependent])))
        if warn:
            Warning(msg)
        else:
            logger.warn(msg)

    return s 
Example #15
Source Project: flare-ida   Author: fireeye   File: code_grafter.py    License: 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 #16
Source Project: flare-ida   Author: fireeye   File: code_grafter.py    License: 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