예제 #1
0
 def fields(self, reload=False):
     if reload or not self._fields:
         self._fields = {}
         m = 0
         while True:
             if m >= idc.GetStrucSize(self.id):
                 break
             n = idc.GetMemberName(self.id, m)
             if n == idc.BADADDR:
                 break
             sz = idc.GetMemberSize(self.id, m)
             mid = idc.GetMemberId(self.id, m)
             tp = idc.GetType(mid)
             fld = {
                 'offset': m,
                 'id': mid,
                 'name': n,
                 'size': sz,
                 'type': [tp, None]
             }
             if n != '':
                 fld['type'][1] = idc.GetMemberFlag(self.id, m)
             self._fields[m] = fld
             m = idc.GetStrucNextOff(self.id, m)
             if m == idc.BADADDR:
                 break
     return self._fields
예제 #2
0
def get_object_id_of_union_member_id(hash_provider, member_id):
    try:
        return union_member_object_ids[member_id]
    except KeyError:

        idx = idc.GetFirstStrucIdx()
        while idx != idc.BADADDR:
            struc_id = idc.GetStrucId(idx)
            if idc.IsUnion(struc_id):

                offset = idc.GetFirstMember(struc_id)

                while offset != idc.BADADDR:
                    smember_id = idc.GetMemberId(struc_id, offset)
                    if smember_id == member_id:
                        name = idc.GetMemberName(struc_id, offset)
                        if name is not None:
                            struc_name = idc.GetStrucName(struc_id)
                            logger.debug("found member id 0x%016X in union %s/%s" % (member_id, struc_name, name))
                            return hash_provider.get_struc_member_id_for_name(struc_name, offset)

                    # next member
                    offset = idc.GetStrucNextOff(struc_id, offset)
            idx = idc.GetNextStrucIdx(idx)

        logger.error("Could not find member id 0x%016X in unions" % member_id)

        return None
예제 #3
0
def get_args(f):
    local_variables = []
    arguments = []
    current = local_variables

    frame = idc.GetFrame(f)
    arg_string = ""
    if frame == None:
        return None

    start = idc.GetFirstMember(frame)
    end = idc.GetLastMember(frame)
    count = 0
    max_count = 10000
    args_str = ""
    while start <= end and count <= max_count:
        size = idc.GetMemberSize(frame, start)
        count = count + 1
        if size == None:
            start = start + 1
            continue

        name = idc.GetMemberName(frame, start)
        start += size

        if name in [" r", " s"]:
            # Skip return address and base pointer
            current = arguments
            continue
        arg_string += " " + name
        current.append(name)
    if len(arguments) == 0:
        arguments.append("void")
    return arguments
예제 #4
0
파일: checkida.py 프로젝트: tmcmil/YaCo
def walk_members(ea):
    global num_stackframes, num_default_stackframe_members
    frame = idaapi.get_frame(ea)
    if not frame:
        return
    num_stackframes += 1
    sid = frame.id
    s = idaapi.get_struc(sid)
    if s is None or s == idaapi.BADADDR:
        return
    known = set()
    base = idc.GetFrameLvarSize(ea)
    for idx in xrange(0, s.memqty):
        ea = yatools.get_struc_member_by_idx(s, idx)
        if ea in known:
            continue
        m = idaapi.get_member(frame, ea)
        if not m or idaapi.is_special_member(m.id):
            continue
        is_data = m.flag == idaapi.FF_DATA
        is_default_name = idc.GetMemberName(
            sid, ea) == get_default_struc_member_name(False, ea, base)
        size = idaapi.get_member_size(m)
        no_comment = is_nil(idaapi.get_member_cmt(m.id, 0))
        no_repeated = is_nil(idaapi.get_member_cmt(m.id, 1))
        if not s.is_union(
        ) and is_data and size == 1 and is_default_name and no_comment and no_repeated:
            num_default_stackframe_members += 1
            continue
        if m and not idaapi.is_special_member(m.id):
            known.add(ea)
            yield m
예제 #5
0
def get_struc_offset(ea, opn):
    path = idaapi.tid_array(1)
    delta = idaapi.sval_pointer()
    idaapi.get_stroff_path(ea, opn, path.cast(), delta.cast())
    struct = path[0]
    if idaapi.decode_insn(ea) == 0:
        print 'error in {0}'.format(GetDisasm(ea))
    else:
        op = idaapi.cmd.Operands[opn]
        offset = op.value
        result = []
        idaapi.get_stroff_path(ea, opn, path.cast(), delta.cast())
        struct = path[0]
        while offset:
            member_id = idc.GetMemberId(struct, offset)
            member_name = idc.GetMemberName(member_id)
            field_struct_id = idc.GetMemberStrId(struct, offset)
            if field_struct_id != idc.BADADDR:
                result.append(
                    [field_struct_id,
                     idc.GetStrucName(field_struct_id)])
            else:
                result.append([member_name, idc.GetMemberFlag(struct, offset)])
                return result
            offset -= idc.GetMemberOffset(member_name)
예제 #6
0
def getFunctionArgumentCount(ea):
    '''
    Bit of a hack, since IDA doesn't seem to have a good way to get this information.
    Gets the frame for a given function, and counts named members following the 'r'
    member.
    Note: IDA won't create a frame member for an unreferenced function arg... so you've
    been warned.
    '''
    rFound = False
    argCount = 0
    sid = idc.GetFrame(ea)
    midx = idc.GetFirstMember(sid)
    while midx != idc.BADADDR:
        name = idc.GetMemberName(sid, midx)
        if rFound and name is not None:
            argCount += 1 
            #print 'Found arg at 0x%x: "%s"' % (midx, name)
        elif name  == ' r':
            #print 'Found r at 0x%x:' % midx
            rFound = True
        else:
            #print 'Found nonarg at 0x%x: "%s"' % (midx, name)
            pass
        midx = idc.GetStrucNextOff(sid, midx)
    return argCount
예제 #7
0
 def yacheck_reference_loop(self):
     for k in range(0, 2):
         sid = idc.GetStrucIdByName('refloop' + str(k))
         self.assertNotEqual(sid, idaapi.BADADDR)
         self.assertEqual(idc.GetMemberName(sid, 0), 'refloop_field' + str(k))
         mid = idc.GetMemberId(sid, 0)
         self.assertNotEqual(mid, -1)
         self.assertEqual(idc.GetType(mid), 'refloop' + str(1 - k) + ' *')
예제 #8
0
    def yacheck_create_struct_in_stack_vars_with_renaming(self):
        sida = yaunit.load("create_struct_in_stack_vars_with_renaming")
        offset = yaunit.load("create_struct_in_stack_vars_with_renaming_offset")
        self.assertEqual("var1", idc.GetMemberName(sida, offset))

        stype = fix_ptr_type(idc.GetType(idc.GetMemberId(sida, offset)))
        self.assertEqual("create_struct_in_stack_vars_with_renaming*",
                         stype)
예제 #9
0
def build_stack_args(f):
  stackArgs = dict()
  name = idc.Name(f)
  end = idc.GetFunctionAttr(f, idc.FUNCATTR_END)
  _locals = idc.GetFunctionAttr(f, idc.FUNCATTR_FRSIZE)
  _uses_bp = 0 != (idc.GetFunctionFlags(f) & idc.FUNC_FRAME)
  frame = idc.GetFrame(f)
  if frame is None:
    return stackArgs

  func_type = idc.GetType(f)
  if (func_type is not None) and ("(" in func_type):
    args = func_type[ func_type.index('(')+1: func_type.rindex(')') ]
    args_list = [ x.strip() for x in args.split(',')]
    if "..." in args_list:
      return stackArgs

  if name in RECOVER_DEBUG_FL:
    return stackArgs

  #grab the offset of the stored frame pointer, so that
  #we can correlate offsets correctly in referent code
  # e.g., EBP+(-0x4) will match up to the -0x4 offset
  delta = idc.GetMemberOffset(frame, " s")
  if -1 == delta:
    #indicates that it wasn't found. Unsure exactly what to do
    # in that case, punting for now
    delta = 0

  offset = idc.GetFirstMember(frame)
  while -1 != _signed_from_unsigned(offset):
    memberName = idc.GetMemberName(frame, offset)
    if memberName is None:
      # gaps in stack usage are fine, but generate trash output
      # gaps also could indicate a buffer that IDA doesn't recognize
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    if (memberName == " r" or memberName == " s"):
      #the return pointer and start pointer, who cares
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    memberSize = idc.GetMemberSize(frame, offset)
    if offset >= delta:
      offset = idc.GetStrucNextOff(frame, offset)
      continue
    memberFlag = idc.GetMemberFlag(frame, offset)
    #TODO: handle the case where a struct is encountered (FF_STRU flag)
    flag_str = _get_flags_from_bits(memberFlag)
    stackArgs[offset-delta] = {"name":memberName,
                               "size":memberSize,
                               "flags":flag_str,
                               "writes":list(),
                               "referent":list(),
                               "reads":list(),
                               "safe": False}
    offset = idc.GetStrucNextOff(frame, offset)

  return stackArgs
예제 #10
0
def build_stack_variable(func_ea):
  stack_vars = dict()

  frame = idc.GetFrame(func_ea)
  if not frame:
    return stack_vars

  f_name = get_symbol_name(func_ea)
  #grab the offset of the stored frame pointer, so that
  #we can correlate offsets correctly in referent code
  # e.g., EBP+(-0x4) will match up to the -0x4 offset
  delta = idc.GetMemberOffset(frame, " s")
  if delta == -1:
    delta = 0

  if f_name not in _FUNC_UNSAFE_LIST:
    offset = idc.GetFirstMember(frame)
    while -1 != _signed_from_unsigned(offset):
      member_name = idc.GetMemberName(frame, offset)
      if member_name is None:
        offset = idc.GetStrucNextOff(frame, offset)
        continue
      if (member_name == " r" or member_name == " s"):
        offset = idc.GetStrucNextOff(frame, offset)
        continue

      member_size = idc.GetMemberSize(frame, offset)
      if offset >= delta:
        offset = idc.GetStrucNextOff(frame, offset)
        continue

      member_flag = idc.GetMemberFlag(frame, offset)
      flag_str = _get_flags_from_bits(member_flag)
      member_offset = offset-delta
      stack_vars[member_offset] = {"name": member_name,
                                  "size": member_size,
                                  "flags": flag_str,
                                  "writes": list(),
                                  "referent": list(),
                                  "reads": list(),
                                  "safe": False }

      offset = idc.GetStrucNextOff(frame, offset)
  else:
    offset = idc.GetFirstMember(frame)
    frame_size = idc.GetFunctionAttr(func_ea, idc.FUNCATTR_FRSIZE)
    flag_str = ""
    member_offset = _signed_from_unsigned(offset) - delta
    stack_vars[member_offset] = {"name": f_name,
                                 "size": frame_size,
                                 "flags": flag_str,
                                 "writes": list(),
                                 "referent": list(),
                                 "reads": list(),
                                 "safe": False }

  return stack_vars
예제 #11
0
 def yacheck_function_local_vars(self):
     addr = yaunit.load('function_with_local_vars')
     frame = idaapi.get_frame(addr)
     frame_size = idaapi.get_struc_size(frame.id)
     offset = 0
     last_name = None
     while offset < frame_size and last_name is None:
         last_name = idc.GetMemberName(frame.id, offset)
         offset += 1
     self.assertEqual(last_name, 'local_var')
예제 #12
0
def add_member_descr(structure, sid):
    """ Insert comments descripting every member of a structure 
    whose id is sid
    
    Arguments:
    structure -- structure object holding data
    sid -- structure id
    """

    if len(structure.members) == 0 or \
       idc.GetMemberQty(sid) == 0:
        return

    members_map = {}
    for member in structure.members:
        members_map[member.name] = member

    m_offset = -1
    for i in xrange(0, idc.GetMemberQty(sid)):
        # for each member of imported structure
        if i == 0:
            m_offset = idc.GetFirstMember(sid)
        else:
            m_offset = idc.GetStrucNextOff(sid, m_offset)

        if m_offset == -1 or m_offset == idaapi.BADADDR:
            break

        m_name = idc.GetMemberName(sid, m_offset)

        # None
        if not m_name:
            continue

        if m_name not in members_map:
            # A same member may have different name between msdn databases
            # and ida import structure table, ida may add some prefixes.
            if m_name[1:] in members_map:
                # start with '_'
                m_name = m_name[1:]
            elif re.match(r'^tag(.)*', m_name) and \
                m_name[3:] in members_map:
                # start with 'tag'
                m_name = m_name[3:]
            elif re.match(r'^_tag(.)*', m_name) and \
                m_name[4:] in members_map:
                # start with '_tag'
                m_name = m_name[4:]
            else:
                continue

        idc.SetMemberComment(sid, m_offset,
                             format_comment(members_map[m_name].description),
                             False)
예제 #13
0
    def get_struc_name(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = x.type
        xtype.remove_ptr_or_array()
        typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '')

        sid = idc.GetStrucIdByName(typename)
        member = idc.GetMemberName(sid, m)

        return '%s::%s' % (typename, member)
예제 #14
0
    def check_field(self, sid, ftype, strid, offset, size, name):
        if ftype is None:
            for i in range(offset, offset + size):
                self.assertIsNone(idc.GetMemberName(sid, i))
                self.assertEqual(idc.GetMemberFlag(sid, i), -1)
            return

        try:
            self.assertNotEqual(idc.GetMemberName(sid, offset - 1), name)
        except:
            pass
        for k in range(offset, offset + size):
            self.assertEqual(idc.GetMemberName(sid, k), name)
            self.assertEqual(idc.GetMemberSize(sid, k), size)
            self.assertEqual(idc.GetMemberFlag(sid, k) & idaapi.DT_TYPE, ftype & 0xFFFFFFFF)
            if strid != -1:
                st = idaapi.get_struc(sid)
                mb = idaapi.get_member(st, offset)
                op = idaapi.opinfo_t()
                idaapi.retrieve_member_info(op, mb)
                self.assertEqual(op.tid, strid)
        self.assertNotEqual(idc.GetMemberName(sid, offset + size), name)
예제 #15
0
    def get_struc_name(self):

        x = self.target.operands['x']
        m = self.target.operands['m']

        xtype = typestring(x.type.u_str())
        xtype.remove_ptr_or_array()
        typename = str(xtype)

        sid = idc.GetStrucIdByName(typename)
        member = idc.GetMemberName(sid, m)

        return '%s::%s' % (typename, member)
예제 #16
0
 def setStrucPntr(self, sid, ofs, name, tp=None):
     vnm = idc.GetMemberName(sid, ofs)
     if not vnm or vnm in (idc.BADADDR, -1):
         idc.AddStrucMember(sid, name, ofs, idc.FF_QWRD, -1, 8)
         vnm = name
     if vnm != name:
         idc.SetMemberName(sid, ofs, name)
     sz = idc.GetMemberSize(sid, ofs)
     if sz != 8:
         idc.SetMemberType(sid, ofs, idc.FF_QWRD, -1, 1)
     mid = idc.GetMemberId(sid, ofs)
     t = idc.GetType(mid) or ''
     if tp and t.replace(' ', '') != tp.replace(' ', ''):
         idc.SetType(mid, tp + ';')
예제 #17
0
def loadMembers(struc, sid):
    '''Returns list of tuples of (offset, memberName, member)'''
    #mixing idc & idaapi, kinda annoying but need low-level idaapi for a
    # type access, but cant dig into structs...
    members = []
    off = g_dll.get_struc_first_offset(struc)
    while off >= 0:
        member = g_dll.get_member(struc, ctypes.c_int(off))
        if (member == 0) or (member is None):
            pass  #not really an error, i guess
        else:
            members.append((off, idc.GetMemberName(sid, off), member))
        off = g_dll.get_struc_next_offset(struc, ctypes.c_int(off))
    members.sort(key=lambda mem: mem[0])
    return members
예제 #18
0
def struc_member_list(struc_id, is_union):
    current_idx = 0
    struc = idaapi.get_struc(struc_id)
    if struc is None or struc == idc.BADADDR:
        return []

    offsets = dict()
    for current_idx in xrange(0, struc.memqty):
        offset = _yatools_ida.get_struc_member_by_idx(struc, current_idx)
        if offset not in offsets:
            name = idc.GetMemberName(struc_id, offset)
            if name is not None:
                offsets[offset] = name

    return sorted(offsets.items())
def getStackVars(ea, base=-1):
    # type: (int, int) -> list[(str, int)]
    """
    Gets the stack variables associted with the function at ea
    If no base is specified, the offsets don't include the base calculation in them
    :param ea: the address of the function
    :param base: the stack base, must obtain to compute the offsets relative to it
    :return: a list of tuples, the stack variable name and its offset
    """
    stackVars = []
    id = idc.GetFrame(ea)

    firstMember = idc.GetFirstMember(id)
    # if the function has stack variables
    if firstMember != idaapi.BADADDR and firstMember != -1:
        # build up disasm based on stack vars
        lastMember = idc.GetLastMember(id)
        i = firstMember

        # Stack can be offset, first member might not be found at index 0, and all offsets must be adjusted by this
        foundFirstElement = False
        stackOffset = 0
        while i <= lastMember:
            name = idc.GetMemberName(id, i)
            off = idc.GetMemberOffset(
                id, name
            )  # this is the offset in the struct... which isn't always consistent!
            size = idc.GetMemberSize(id, i)
            # append if varname is found (sometimes, None is returned because the variables are not in the next index)
            if name:
                # first variable found! this is the stack of the stack variables!
                if not foundFirstElement:
                    stackOffset = i
                    foundFirstElement = True
                if base == -1:
                    # absolute offsets appended
                    stackVars.append((name, off - stackOffset))
                else:
                    # base-relative offsets appended
                    stackVars.append((name, base - off - stackOffset))
            # sometimes, for some reason, the offset for stack variables does not follow linearly
            if size:
                i += size
            else:
                # reach next var, which might not be one size unit after the last...
                while not idc.GetMemberSize(id, i) and i <= lastMember:
                    i += 1
    return stackVars
예제 #20
0
파일: hooks.py 프로젝트: Spl3en/ipad
 def struc_member_renamed(self, struct, membr):
     sid = struct.id
     mid = membr.id
     moff = membr.soff
     idx = idc.GetStrucIdx(sid)
     sname = idc.GetStrucName(sid)
     mname = idc.GetMemberName(sid, moff)
     self.ctrl._handle_action({
         'action': 'struct_member_renamed',
         'struct': idx,
         'member': mid,
         'sname': sname,
         'mname': mname,
         'off': moff
     })
     return 0
예제 #21
0
def StructMembers(sid):
    """
    Get a list of structure members information.

    @param sid: ID of the structure.

    @return: List of tuples (offset, name, size)

    @note: If 'sid' does not refer to a valid structure,
           an exception will be raised.
    """
    off = idc.GetFirstMember(sid)
    if off == idaapi.BADNODE:
        raise Exception("No structure with ID: 0x%x" % sid)
    members = idc.GetMemberQty(sid)
    for idx in range(0, members):
        yield (off, idc.GetMemberName(sid, off), idc.GetMemberSize(sid, off))
        off = idc.GetStrucNextOff(sid, off)
예제 #22
0
파일: hooks.py 프로젝트: Spl3en/ipad
 def struc_member_created(self, struct, membr):
     sid = struct.id
     mid = membr.id
     moff = membr.soff
     flag = membr.flag
     size = idc.GetMemberSize(sid, moff)
     sname = idc.GetStrucName(sid)
     mname = idc.GetMemberName(sid, moff)
     idx = idc.GetStrucIdx(sid)
     self.ctrl._handle_action({
         'action': 'struct_member_created',
         'struct': idx,
         'member': mid,
         'sname': sname,
         'mname': mname,
         'off': moff,
         'flag': flag,
         'size': size
     })
     return 0
예제 #23
0
def StructMembers(sid):
    """
    Get a list of structure members information (or stack vars if given a frame).

    @param sid: ID of the structure.

    @return: List of tuples (offset, name, size)

    @note: If 'sid' does not refer to a valid structure,
           an exception will be raised.
    @note: This will not return 'holes' in structures/stack frames;
           it only returns defined structure members.
    """
    m = idc.GetFirstMember(sid)
    if m == -1:
        raise Exception("No structure with ID: 0x%x" % sid)
    while (m != idaapi.BADADDR):
        name = idc.GetMemberName(sid, m)
        if name:
            yield (m, name, idc.GetMemberSize(sid, m))
        m = idc.GetStrucNextOff(sid, m)
예제 #24
0
    def __init__(self, sid, offs):
        self.offs = offs
        #sid = struc
        name = None
        substruct = -1
        size = 0

        if not warnBad(sid):
            #struc = idaapi.get_struc(sid)
            #member = idaapi.get_member(struc, offs)

            name = idc.GetMemberName(sid, offs)
            substruct = idc.GetMemberStrId(sid, offs)
            size = idc.GetMemberSize(sid, offs)
            #name = idaapi.get_member_name(member.id)
            #substruct = idaapi.get_sptr(member)
            #size = idaapi.get_member_size(member)

        self.name = name
        self.struc = substruct
        self.size = size
예제 #25
0
def get_member_name(sid, cur_offset):
    if idaapi.IDA_SDK_VERSION <= 699:
        mn = idc.GetMemberName(sid, cur_offset)
    else:
        mn = idc.get_member_name(sid, cur_offset)
    return mn
예제 #26
0
    def clear_struc_fields(self,
                           struc_id,
                           struc_size,
                           xref_keys,
                           is_union=False,
                           member_type=ya.OBJECT_TYPE_STRUCT_MEMBER,
                           name_offset=0):

        idc.BeginTypeUpdating(idc.UTP_STRUCT)
        last_offset = idc.GetLastMember(struc_id)

        # get existing member offsets
        field_offsets = set()
        for (xref_offset, xref_operand) in xref_keys:
            field_offsets.add(xref_offset)

        new_offsets = set()
        struc = idaapi.get_struc(struc_id)
        # create missing members first (prevent from deleting all members)
        for offset in field_offsets:
            member = idaapi.get_member(struc, offset)
            if member is not None and member.soff < offset:
                # we have a member above this member that is too big and contain this member
                # clear it!
                if DEBUG_EXPORTER:
                    logger.debug(
                        "reduce field : set_member_type(0x%08X, 0x%08X), overlapping 0x%08X",
                        struc_id, member.soff, offset)
                idaapi.set_member_type(struc, member.soff, idc.FF_BYTE, None,
                                       1)
                member = idaapi.get_member(struc, offset)

            if member is None or idaapi.get_member_name(member.id) is None:
                new_offsets.add(offset)
                member_name = YaToolIDATools.get_default_struc_member_name(
                    member_type, offset, name_offset)
                if offset == last_offset and offset == struc_size:
                    field_size = 0
                else:
                    field_size = 1
                if DEBUG_EXPORTER:
                    logger.debug(
                        "AddStrucMember(0x%08X, '%s', 0x%08X, idc.FF_BYTE, -1, 0x%08X), name_offset=%d",
                        struc_id, member_name, offset, field_size, name_offset)
                retval = idc.AddStrucMember(struc_id, member_name, offset,
                                            idc.FF_BYTE, -1, field_size)
                if retval != 0:
                    logger.error(
                        "Error %d with idc.AddStrucMember(0x%08X, '%s', 0x%08X,"
                        "idc.FF_BYTE, -1, 0x%08X), name_offset=%d", retval,
                        struc_id, member_name, offset, field_size, name_offset)
            elif DEBUG_EXPORTER:
                logger.debug("Member exists : (0x%08X, '%s', 0x%08X, 0x%08X)",
                             struc_id, idc.GetMemberName(struc_id,
                                                         offset), offset,
                             idc.GetMemberSize(struc_id, offset))

        kept_offsets = field_offsets - new_offsets
        # clear kept members
        # split the loop since we will modify the structure while iterating
        offsets = set()
        for (offset, member_name) in YaToolIDATools.struc_member_list(
                struc_id, is_union):
            offsets.add(offset)

        for offset in offsets:
            if offset in kept_offsets:
                # This member already existed and is kept
                if offset == last_offset and offset == struc_size:
                    # this is the last field, and it is a variable sized structure
                    field_size = 0
                else:
                    field_size = 1
                if member_type == ya.OBJECT_TYPE_STRUCT_MEMBER:
                    strucmember_id = self.hash_provider.get_struc_member_id(
                        struc_id, offset)
                elif member_type == ya.OBJECT_TYPE_STACKFRAME_MEMBER:
                    strucmember_id = self.hash_provider.get_stackframe_member_object_id(
                        struc_id, offset)
                else:
                    logger.error("Bad member_type : %d" % member_type)

                if strucmember_id not in self.strucmember_ids:
                    # It is not necessary to clear the member if it is presnet in the resolved_objects
                    if DEBUG_EXPORTER:
                        logger.debug(
                            "SetStrucmember(0x%08X, None, 0x%08X, idc.FF_BYTE, -1, 0x%08X, name_offset=%s)",
                            struc_id, offset, field_size, name_offset)
                    YaToolIDATools.SetStrucmember(struc_id,
                                                  None,
                                                  offset,
                                                  idc.FF_BYTE,
                                                  -1,
                                                  field_size,
                                                  member_type=member_type,
                                                  name_offset=name_offset)

                    idc.SetMemberComment(struc_id, offset, "", 0)
                    idc.SetMemberComment(struc_id, offset, "", 1)
            elif offset not in new_offsets:
                if (member_type != ya.OBJECT_TYPE_STACKFRAME_MEMBER
                        or not idaapi.is_special_member(
                            idc.GetMemberId(struc_id, offset))):
                    if DEBUG_EXPORTER:
                        logger.debug(
                            "DelStrucMember(0x%08X, 0x%08X)  (=%s:%s)",
                            struc_id, offset, idc.GetStrucName(struc_id),
                            idc.GetMemberName(struc_id, offset))
                    idc.DelStrucMember(struc_id, offset)
            else:
                # in new_offsets : just created
                pass
        idc.EndTypeUpdating(idc.UTP_STRUCT)
예제 #27
0
파일: analysis.py 프로젝트: wzr/toolbag
    def argCount(self):
        end = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_END)
        start = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_START)
        frame = idc.GetFrame(start)
        localv = idc.GetFunctionAttr(self.addr, idc.FUNCATTR_FRSIZE)
        frameSize = idc.GetFrameSize(start)  #idc.GetStrucSize(frame)

        reg_off = 0
        local_count = 0
        arg_count = 0
        sid = idc.GetFrame(self.addr)
        if sid:
            firstM = idc.GetFirstMember(sid)
            lastM = idc.GetLastMember(sid)
            arg_count = 0

            if lastM - firstM > 0x1000:
                return

            for i in xrange(firstM, lastM):
                mName = idc.GetMemberName(sid, i)
                mSize = idc.GetMemberSize(sid, i)
                mFlag = idc.GetMemberFlag(sid, i)
                off = idc.GetMemberOffset(sid, mName)
                #print "%s: %d, %x, off=%x" % (mName, mSize, mFlag, off)

                if mName == " r":
                    reg_off = off

            # XXX: just store the data, dont loop twice.
            for i in xrange(firstM, lastM):
                mName = idc.GetMemberName(sid, i)
                mSize = idc.GetMemberSize(sid, i)
                mFlag = idc.GetMemberFlag(sid, i)
                off = idc.GetMemberOffset(sid, mName)

                if off <= reg_off:
                    local_count += 1
                elif off > reg_off and reg_off != 0:
                    arg_count += 1

            if arg_count > 0:
                return arg_count / 4
            elif arg_count == 0:
                return 0

        # offset to return
        try:
            ret = idc.GetMemberOffset(frame, " r")
        except:
            if frameSize > localv:
                return (frameSize - localv) / 4
            # error getting function frame (or none exists)
            return -1

        if (ret < 0):
            if frameSize > localv:
                return (frameSize - localv) / 4
            return -1

        firstArg = ret + 4
        args = frameSize - firstArg
        numArgs = args / 4

        return numArgs
예제 #28
0
 def get_name(self):
     return idc.GetMemberName(*self.mid) or "{no_name}"
예제 #29
0
# func_frames maps from function address to a record of the function's stack
# frame size and local variables.
func_frames = {}
func_addrs = []
for seg in idautils.Segments():
    # Skip extern segment; as used by IDA for external functions.
    if idc.get_segm_attr(seg, SEGATTR_TYPE) == idc.SEG_XTRN:
        #print("skipping segment ", idc.get_segm_name(seg))
        continue
    for fn in idautils.Functions(seg, idc.get_segm_end(seg)):
        func_addr = fn
        frame = ida_frame.get_frame(func_addr)
        frame_size = ida_frame.get_frame_size(func_addr)
        var_names = []
        for i in range(frame_size):
            var_name = idc.GetMemberName(frame, i)
            # TODO: check if ' r' and ' s' (return address and saved registers) may have
            # duplicates.
            if var_name is None:
                continue
            var_names.append(var_name)
        print(var_names)
        func_frame = {"func_name": func_name, "func_type": func_type}
        func_frames[func_addr] = func_frame
        func_addrs.append(func_addr)

# TODO: check diff between ESP at function entry and each instruction.
#    fn = idaapi.get_func(0)
#    ida_frame.get_effective_spd(fn, inst_ea)
#
# TODO: check whether to use get_effective_spd or get_spd.