예제 #1
0
def get_member_from_struct(ea, sname, mname):
	"""
	get_member_from_struct: ea, sname, mname
	
	Retrieves a DWORD member named 'mname' from struct 'sname'
	starting at address 'ea'.
	"""
	
	sid = idaapi.get_struc_id(sname)
	stru = idaapi.get_struc(sid)
	member = idaapi.get_member_by_name(stru, mname)
	
	# TODO check size
	return idc.Dword(ea + member.soff)
예제 #2
0
파일: msvc.py 프로젝트: zyzhen/SusanRTTI
class RTTIClassHierarchyDescriptor(RTTIStruc):
    bases = None

    msid = get_struc_id("RTTIClassHierarchyDescriptor")
    if msid != BADADDR:
        del_struc(msid)
    msid = add_struc(0xFFFFFFFF, "RTTIClassHierarchyDescriptor", False)
    add_struc_member(msid, "signature", BADADDR, FF_DWRD | FF_DATA, -1, 4)
    add_struc_member(msid, "attribute", BADADDR, FF_DWRD | FF_DATA, -1, 4)
    add_struc_member(msid, "numBaseClasses", BADADDR, FF_DWRD | FF_DATA, -1, 4)
    add_struc_member(msid, "pBaseClassArray", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF,
                     u.mt_rva().tid, 4)
    tid = msid
    struc = get_struc(tid)
    print("Completed Registering RTTIClassHierarchyDescriptor")

    def __init__(self, ea):
        print("Processing Class Hierarchy Descriptor at 0x%x" % ea)
        do_unknown_range(ea, get_struc_size(self.tid), DOUNK_DELNAMES)
        if doStruct(ea, get_struc_size(self.tid), self.tid):
            baseClasses = get_32bit(
                ea + get_member_by_name(get_struc(
                    self.tid), "pBaseClassArray").soff) + u.x64_imagebase()
            nb_classes = get_32bit(
                ea +
                get_member_by_name(get_struc(self.tid), "numBaseClasses").soff)
            print("Baseclasses array at 0x%x" % baseClasses)
            # Skip the first base class as it is itself (could check)
            self.bases = []
            for i in range(1, nb_classes):
                baseClass = get_32bit(baseClasses + i * 4) + u.x64_imagebase()
                print("base class 0x%x" % baseClass)
                doDwrd(baseClasses + i * 4, 4)
                op_offset(baseClasses + i * 4, -1, u.REF_OFF | REFINFO_RVA, -1,
                          0, 0)
                doStruct(baseClass, RTTIBaseClassDescriptor.size,
                         RTTIBaseClassDescriptor.tid)
                typeDescriptor = get_32bit(baseClass) + u.x64_imagebase()
                self.bases.append(
                    RTTITypeDescriptor(typeDescriptor).class_name)
예제 #3
0
파일: msvc.py 프로젝트: zk2013/SusanRTTI
 def __init__(self, ea):
     name = ea + get_member_by_name(get_struc(self.tid), "name").soff
     strlen = u.get_strlen(name)
     if strlen is None:
         # not a real vtable
         return
     self.size = self.size + strlen
     mangled = get_ascii_contents(name, strlen, 0)
     if mangled is None:
         # not a real function name
         return
     print "Mangled: " + mangled
     demangled = demangle_name('??_R0' + mangled[1:], 0)
     if demangled:
         do_unknown_range(ea, self.size, DOUNK_DELNAMES)
         if doStruct(ea, self.size, self.tid):
             print "  Made td at 0x%x: %s" % (ea, demangled)
             self.class_name = demangled
             return
     print "  FAIL :("
     return
예제 #4
0
 def add_auto_comment(self, ea, text):
     if ea is not None:
         prefix = ""
         if idaapi.get_struc(ea) is not None:
             if idc.GetStrucIdx(ea) == idc.BADADDR:
                 prefix = "stackframe '%s'" % idc.GetFunctionName(
                     idaapi.get_func_by_frame(ea))
             else:
                 prefix = "structure '%s'" % idc.GetStrucName(ea)
         elif idc.GetEnumIdx(ea) != idc.BADADDR:
             prefix = "enum '%s'" % idc.GetEnumName(ea)
         else:
             foffset = idc.GetFuncOffset(ea)
             if foffset is None:
                 prefix = self.yatools.address_to_hex_string(ea)
             else:
                 prefix = "%s,%s" % (self.yatools.address_to_hex_string(ea),
                                     foffset)
         self.auto_comments.add((prefix, text))
     else:
         self.auto_comments.add(("", text))
예제 #5
0
파일: msvc.py 프로젝트: Midi12/SusanRTTI
 def __init__(self, ea):
     name = ea + get_member_by_name(get_struc(self.tid), "name").soff
     strlen = u.get_strlen(name)
     if strlen is None:
         # not a real vtable
         return
     self.size = self.size + strlen
     mangled = get_strlit_contents(name, strlen, 0)
     if mangled is None:
         # not a real function name
         return
     print("Mangled: " + mangled)
     demangled = demangle_name('??_R0' + mangled[1:], 0)
     if demangled:
         del_items(ea, self.size, DELIT_DELNAMES)
         if create_struct(ea, self.size, self.tid):
             print("  Made td at 0x%x: %s" % (ea, demangled))
             self.class_name = demangled
             return
     print("  FAIL :(")
     return
예제 #6
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)
예제 #7
0
파일: msvc.py 프로젝트: Midi12/SusanRTTI
class RTTITypeDescriptor(RTTIStruc):
    class_name = None

    msid = get_struc_id("RTTITypeDescriptor")
    if msid != BADADDR:
        del_struc(msid)
    msid = add_struc(0xFFFFFFFF, "RTTITypeDescriptor", False)
    add_struc_member(msid, "pVFTable", BADADDR, FF_DATA | u.PTR_TYPE | FF_0OFF,
                     u.mt_address().tid, u.PTR_SIZE)
    add_struc_member(msid, "spare", BADADDR, FF_DATA | u.PTR_TYPE, -1,
                     u.PTR_SIZE)
    add_struc_member(msid, "name", BADADDR, FF_DATA | FF_STRLIT,
                     u.mt_ascii().tid, 0)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print("Completed Registering RTTITypeDescriptor")

    def __init__(self, ea):
        name = ea + get_member_by_name(get_struc(self.tid), "name").soff
        strlen = u.get_strlen(name)
        if strlen is None:
            # not a real vtable
            return
        self.size = self.size + strlen
        mangled = get_strlit_contents(name, strlen, 0)
        if mangled is None:
            # not a real function name
            return
        print("Mangled: " + mangled)
        demangled = demangle_name('??_R0' + mangled[1:], 0)
        if demangled:
            del_items(ea, self.size, DELIT_DELNAMES)
            if create_struct(ea, self.size, self.tid):
                print("  Made td at 0x%x: %s" % (ea, demangled))
                self.class_name = demangled
                return
        print("  FAIL :(")
        return
예제 #8
0
def members(id):
    st = idaapi.get_struc(id)
    if not st:
        # empty structure
        return

    size = idaapi.get_struc_size(st)

    offset = 0
    for i in range(st.memqty):
        m = st.get_member(i)
        ms = idaapi.get_member_size(m)

        left,right = m.soff,m.eoff

        if offset < left:
            yield (offset,left-offset), (None,None)
            offset = left

        yield (offset,ms),(idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 1))
        offset += ms
    return
예제 #9
0
파일: hooks.py 프로젝트: silverf0x/YaCo
    def ev_rename(self, ea, new_name):
        """
        This function only records information about the element *before* it is renamed
        """
        if idaapi.is_member_id(ea):
            name = idaapi.get_member_fullname(ea)
        elif idaapi.get_struc(ea) is not None:
            name = idaapi.get_struc_name(ea)
        elif idaapi.get_enum_idx(ea) != idc.BADADDR:
            name = idaapi.get_enum_name(ea)
        elif idaapi.get_enum_idx(
                idaapi.get_enum_member_enum(ea)) != idc.BADADDR:
            # this is an enum member id
            enum_id = idaapi.get_enum_member_enum(ea)
            name = idaapi.get_enum_name(
                enum_id) + "." + idaapi.get_enum_member_name(ea)
        else:
            name = idc.Name(ea)

        hooks.current_rename_infos[ea] = name

        return 0
예제 #10
0
파일: msvc.py 프로젝트: zk2013/SusanRTTI
class RTTIBaseClassDescriptor(RTTIStruc):
    msid = get_struc_id("RTTIBaseClassDescriptor")
    if msid != BADADDR:
        del_struc(get_struc(msid))
    msid = add_struc(0xFFFFFFFF, "RTTIBaseClassDescriptor", False)
    add_struc_member(get_struc(msid), "pTypeDescriptor", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    add_struc_member(get_struc(msid), "numContainerBases", BADADDR,
                     FF_DWRD | FF_DATA, None, 4)
    add_struc_member(get_struc(msid), "PMD", BADADDR,
                     FF_DATA | FF_DWRD | FF_0OFF, u.mt_rva(), 4)
    add_struc_member(get_struc(msid), "attributes", BADADDR, FF_DWRD | FF_DATA,
                     None, 4)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print "Completed Registering RTTIBaseClassDescriptor"
예제 #11
0
class RTTITypeDescriptor(RTTIStruc):
    class_name = None

    msid = get_struc_id("RTTITypeDescriptor")
    if msid != BADADDR:
        del_struc(msid)
    msid = add_struc(0xFFFFFFFF, "RTTITypeDescriptor", False)
    add_struc_member(msid, "pVFTable", BADADDR, FF_DATA | u.PTR_TYPE | FF_0OFF,
                     -1, u.PTR_SIZE)
    add_struc_member(msid, "spare", BADADDR, FF_DATA | u.PTR_TYPE | FF_0OFF,
                     -1, u.PTR_SIZE)
    add_struc_member(msid, "name", BADADDR, FF_DATA | FF_ASCI, STRTYPE_C, 0)
    tid = msid
    struc = get_struc(tid)
    size = get_struc_size(tid)
    print "Completed Registering RTTITypeDescriptor"

    def __init__(self, ea):
        name = ea + get_member_by_name(self.struc, "name").soff
        strlen = u.get_strlen(name)
        if strlen is None:
            # not a real vtable
            return
        self.size = self.size + strlen
        mangled = get_ascii_contents(name, strlen, 0)
        if mangled is None:
            # not a real function name
            return
        print "Mangled: " + mangled
        demangled = demangle_name('??_R0' + mangled[1:], 0)
        if demangled:
            do_unknown_range(ea, self.size, DOUNK_DELNAMES)
            if doStruct(ea, self.size, self.tid):
                print "  Made td at 0x%x: %s" % (ea, demangled)
                self.class_name = demangled
                return
        print "  FAIL :("
        return
예제 #12
0
def members(id):
    """Return the ((offset,size),(name,comment)) of each member within the specified structure"""
    st = idaapi.get_struc(id)
    if not st:
        # empty structure
        return

    size = idaapi.get_struc_size(st)

    offset = 0
    for i in range(st.memqty):
        m = st.get_member(i)
        ms = idaapi.get_member_size(m)

        left, right = m.soff, m.eoff

        if offset < left:
            yield (offset, left - offset), (None, None)
            offset = left

        yield (offset, ms), (idaapi.get_member_name(m.id),
                             idaapi.get_member_cmt(m.id, 1))
        offset += ms
    return
예제 #13
0
 def __call__(self):
     sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8')))
     idaapi.del_struc_member(sptr, self.offset)
예제 #14
0
def get(id):
    return idaapi.get_struc(id)
예제 #15
0
 def __call__(self):
     sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8')))
     idaapi.set_member_name(sptr, self.offset, self.newname.encode('utf-8'))
예제 #16
0
 def __call__(self):
     sptr = idaapi.get_struc(idc.get_struc_id(self.sname.encode('utf-8')))
     idaapi.expand_struc(sptr, self.offset, self.delta)
예제 #17
0
 def run(self):
     try:
         logger.debug('Starting up')
         dlg = StructTyperWidget()
         dlg.setStructs(loadStructs())
         oldTo = idaapi.set_script_timeout(0)
         res = dlg.exec_()
         idaapi.set_script_timeout(oldTo)
         if res == QtWidgets.QDialog.Accepted:
             regPrefix = dlg.getRegPrefix()
             sid = None
             struc = None
             if dlg.ui.rb_useStackFrame.isChecked():
                 ea = idc.here()
                 if using_ida7api:
                     sid = idc.get_frame_id(ea)
                 else:
                     sid = idc.GetFrame(ea)
                 struc = idaapi.get_frame(ea)
                 logger.debug('Dialog result: accepted stack frame')
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError(
                         'Failed to get sid for stack frame at 0x%x' % ea)
                 if (struc is None) or (struc == 0) or (struc
                                                        == idc.BADADDR):
                     raise RuntimeError(
                         'Failed to get struc_t for stack frame at 0x%x' %
                         ea)
                 if using_ida7api:
                     pass
                 else:
                     #need the actual pointer value, not the swig wrapped struc_t
                     struc = long(struc.this)
             else:
                 structName = dlg.getActiveStruct()
                 if structName is None:
                     print("No struct selected. Bailing out")
                     return
                 logger.debug('Dialog result: accepted %s "%s"',
                              type(structName), structName)
                 if using_ida7api:
                     sid = idc.get_struc_id(structName)
                 else:
                     sid = idc.GetStrucIdByName(structName)
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get sid for %s' %
                                        structName)
                 tid = idaapi.get_struc_id(structName)
                 if (tid is None) or (tid == 0) or (tid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get tid_t for %s' %
                                        structName)
                 if using_ida7api:
                     struc = idaapi.get_struc(tid)
                 else:
                     struc = g_dll.get_struc(tid)
                 if (struc is None) or (struc == 0) or (struc
                                                        == idc.BADADDR):
                     raise RuntimeError('Failed to get struc_t for %s' %
                                        structName)
             foundMembers = self.processStruct(regPrefix, struc, sid)
             if dlg.ui.rb_useStackFrame.isChecked() and (foundMembers != 0):
                 #reanalyze current function if we're analyzing a stack frame & found some func pointers
                 if using_ida7api:
                     funcstart = idc.get_func_attr(idc.here(),
                                                   idc.FUNCATTR_START)
                     funcend = idc.get_func_attr(idc.here(),
                                                 idc.FUNCATTR_END)
                 else:
                     funcstart = idc.GetFunctionAttr(
                         idc.here(), idc.FUNCATTR_START)
                     funcend = idc.GetFunctionAttr(idc.here(),
                                                   idc.FUNCATTR_END)
                 if (funcstart != idc.BADADDR) and (funcend != idc.BADADDR):
                     if using_ida7api:
                         idc.plan_and_wait(funcstart, funcend)
                     else:
                         idc.AnalyzeArea(funcstart, funcend)
         elif res == QtWidgets.QDialog.Rejected:
             logger.info('Dialog result: canceled by user')
         else:
             logger.debug('Unknown result')
             raise RuntimeError('Dialog unknown result')
     except Exception, err:
         logger.exception("Exception caught: %s", str(err))
예제 #18
0
 def ptr(self):
     '''Return the structure's idaapi pointer.'''
     return idaapi.get_struc(self.id)
예제 #19
0
        def visit_expr(self, *args):
            e = args[0]
            dr = idaapi.dr_R | idaapi.XREF_USER
            ea = self.find_addr(e)

            # We wish to know what context a struct usage occurs in
            # so we can determine what kind of xref to create. Unfortunately,
            # a post-order traversal makes this difficult.

            # For assignments, we visit the left, instead
            # Note that immediate lvalues will be visited twice,
            # and will be eronneously marked with a read dref.
            # However, it is safer to overapproximate than underapproximate
            if is_assn(e.op) or is_incdec(e.op):
                e = e.x
                dr = idaapi.dr_W | idaapi.XREF_USER

            # &x
            if e.op == idaapi.cot_ref:
                e = e.x
                dr = idaapi.dr_O | idaapi.XREF_USER

            # x.m, x->m
            if e.op == idaapi.cot_memref or e.op == idaapi.cot_memptr:
                moff = e.m

                # The only way I could figure out how
                # to get the structure/member associated with its use
                typ = e.x.type

                if e.op == idaapi.cot_memptr:
                    typ.remove_ptr_or_array()

                strname = typ.dstr()
                if strname.startswith("struct "):
                    strname = strname[len("struct "):]

                stid = idaapi.get_struc_id(strname)
                struc = idaapi.get_struc(stid)
                mem = idaapi.get_member(struc, moff)

                if struc is not None:
                    self.add_dref(ea, stid, dr)
                    if mem is not None:
                        self.add_dref(ea, stid, dr, mem.id)

                else:
                    log.error(
                        "failure from %08X "
                        "on struct %s (id: 0x%X) %s",
                        ea,
                        strname,
                        stid,
                        flags_to_str(dr),
                    )

            elif idaapi.is_lvalue(e.op) and e.type.is_struct():
                strname = e.type.dstr()
                if strname.startswith("struct "):
                    strname = strname[len("struct "):]

                stid = idaapi.get_struc_id(strname)
                struc = idaapi.get_struc(stid)

                if struc is not None:
                    self.add_dref(ea, stid, dr)

            return 0
예제 #20
0
 def __call__(self):
     sptr = idaapi.get_struc(self.sid)
     idaapi.del_struc_member(sptr, self.offset)
def get_struct(name):
    sid = idaapi.get_struc_id(name)
    return idaapi.get_struc(sid)
예제 #22
0
def get_node_for_member(mem, parent):
    if idaapi.isStruct(mem.flag):
        return unset_structure_node(idaapi.get_struc(util.member_str_id(mem, parent)))
    else:
        return unset_primitive_node()
예제 #23
0
 def run(self):
     try:
         logger.debug('Starting up')
         dlg = StructTyperWidget()
         dlg.setStructs(loadStructs())
         oldTo = idaapi.set_script_timeout(0)
         res = dlg.exec_()
         idaapi.set_script_timeout(oldTo)
         if res == QtWidgets.QDialog.Accepted:
             regPrefix = dlg.getRegPrefix()
             sid = None
             struc = None
             if dlg.ui.rb_useStackFrame.isChecked():
                 ea = idc.here()
                 if using_ida7api:
                     sid = idc.get_frame_id(ea)
                 else:
                     sid = idc.GetFrame(ea)
                 struc = idaapi.get_frame(ea)
                 logger.debug('Dialog result: accepted stack frame')
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get sid for stack frame at 0x%x' % ea) 
                 if (struc is None) or (struc == 0) or (struc == idc.BADADDR):
                     raise RuntimeError('Failed to get struc_t for stack frame at 0x%x' % ea)
                 if using_ida7api:
                     pass
                 else:
                     #need the actual pointer value, not the swig wrapped struc_t
                     struc= long(struc.this)
             else:
                 structName = dlg.getActiveStruct()
                 if structName is None:
                     print("No struct selected. Bailing out")
                     return
                 logger.debug('Dialog result: accepted %s "%s"', type(structName), structName)
                 if using_ida7api:
                     sid = idc.get_struc_id(structName)
                 else:
                     sid = idc.GetStrucIdByName(structName)
                 if (sid is None) or (sid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get sid for %s' % structName) 
                 tid = idaapi.get_struc_id(structName)
                 if (tid is None) or (tid == 0) or (tid == idc.BADADDR):
                     #i should really figure out which is the correct error case
                     raise RuntimeError('Failed to get tid_t for %s' % structName)
                 if using_ida7api:
                     struc = idaapi.get_struc(tid)
                 else:
                     struc = g_dll.get_struc(tid)
                 if (struc is None) or (struc == 0) or (struc == idc.BADADDR):
                     raise RuntimeError('Failed to get struc_t for %s' % structName)
             foundMembers = self.processStruct(regPrefix, struc, sid)
             if dlg.ui.rb_useStackFrame.isChecked() and (foundMembers != 0):
                 #reanalyze current function if we're analyzing a stack frame & found some func pointers
                 if using_ida7api:
                     funcstart = idc.get_func_attr(idc.here(), idc.FUNCATTR_START)
                     funcend = idc.get_func_attr(idc.here(), idc.FUNCATTR_END)
                 else:
                     funcstart = idc.GetFunctionAttr(idc.here(), idc.FUNCATTR_START)
                     funcend = idc.GetFunctionAttr(idc.here(), idc.FUNCATTR_END)
                 if (funcstart != idc.BADADDR) and (funcend != idc.BADADDR):
                     if using_ida7api:
                         idc.plan_and_wait(funcstart, funcend)
                     else:
                         idc.AnalyzeArea(funcstart, funcend)
         elif res == QtWidgets.QDialog.Rejected:
             logger.info('Dialog result: canceled by user')
         else:
             logger.debug('Unknown result')
             raise RuntimeError('Dialog unknown result')
     except Exception, err:
         logger.exception("Exception caught: %s", str(err))
예제 #24
0
def walk_struct_members():
    for (idx, sid, name) in idautils.Structs():
        s = idaapi.get_struc(sid)
        for (offset, name, size) in idautils.StructMembers(sid):
            m = idaapi.get_member(s, offset)
            yield m.id
예제 #25
0
 def __init__(self):
     self.elts = []
     for i in range(idaapi.get_struc_qty()):
         self.elts.append(
             struct_node(idaapi.get_struc(idaapi.get_struc_by_idx(i))))
예제 #26
0
 def __init__(self):
     self.elts = []
     for i in range(idaapi.get_struc_qty()):
         self.elts.append(struct_node(idaapi.get_struc(idaapi.get_struc_by_idx(i))))
예제 #27
0
 def ptr(self):
     return idaapi.get_struc(self.id)
예제 #28
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)
예제 #29
0
 def __call__(self):
     sptr = idaapi.get_struc(self.sid)
     idaapi.expand_struc(sptr, self.offset, self.delta)
예제 #30
0
 def ptr(self):
     return idaapi.get_struc(self.id)
예제 #31
0
파일: hooks.py 프로젝트: silverf0x/YaCo
    def save_strucs(self, ida_model, memory_exporter):
        """
        Structures : export modified structures and delete those who have been deleted
        """
        for struc_id in self.structures_to_process:
            sidx = idc.GetStrucIdx(struc_id)
            if sidx is None or sidx == idc.BADADDR:
                # it is a deleted structure or a stackframe
                # in this last case we need to export the parent (function)
                eaFunc = idaapi.get_func_by_frame(struc_id)
                if eaFunc != idc.BADADDR:
                    # OK, it is a stackframe
                    ida_model.accept_struct(memory_exporter, eaFunc, struc_id)
                    ida_model.accept_ea(memory_exporter, eaFunc)
                else:
                    # it is a deleted structure
                    ida_model.delete_struct(memory_exporter, struc_id)
            else:

                ida_model.accept_struct(memory_exporter, idc.BADADDR, struc_id)

        logger.debug("Walking members")
        """
        Structure members : update modified ones, and remove deleted ones
        We iterate over members :
            -if the parent struc has been deleted, delete the member
            -otherwise, detect if the member has been updated or removed
                -updated : accept struc_member + accept_struct if not already exported!
                -removed : accept struc_member_deleted
        """
        for (struc_id, member_set) in self.strucmember_to_process.iteritems():
            ida_struc = idaapi.get_struc(struc_id)
            logger.debug("Walking struc 0x%08X" % struc_id)
            sidx = idc.GetStrucIdx(struc_id)
            is_stackframe = False
            struc_deleted = False
            if sidx is None or sidx == idc.BADADDR:
                f = idaapi.get_func_by_frame(struc_id)
                if f is not None and f != idc.BADADDR:
                    is_stackframe = True
                else:
                    struc_deleted = True

            stackframe_func_addr = idc.BADADDR
            if is_stackframe:
                eaFunc = idaapi.get_func_by_frame(struc_id)
                stackframe_func_addr = eaFunc
                ida_model.accept_function(memory_exporter, eaFunc)

            if struc_deleted:
                # The structure has been deleted : we need to delete the members
                # Note: at first sight, it is not a stackframe
                # TODO: handle function->stackframe deletion here
                for (member_id, offset) in member_set:
                    ida_model.delete_struct_member(memory_exporter,
                                                   idc.BADADDR, struc_id,
                                                   offset)
            else:
                # The structure or stackframe has been modified
                for (member_id, offset) in member_set:
                    ida_member = idaapi.get_member(ida_struc, offset)
                    if ida_member is None:
                        new_member_id = -1
                    else:
                        new_member_id = ida_member.id
                    if new_member_id == -1:
                        # the member has been deleted : delete it
                        ida_model.delete_struct_member(memory_exporter,
                                                       stackframe_func_addr,
                                                       struc_id, offset)
                    elif offset > 0 and idc.GetMemberId(
                            struc_id, offset - 1) == new_member_id:
                        # the member was deleted, and replaced by a member starting above it
                        ida_model.delete_struct_member(memory_exporter,
                                                       stackframe_func_addr,
                                                       struc_id, offset)
                    else:
                        # the member has just been modified
                        ida_model.accept_struct_member(memory_exporter,
                                                       stackframe_func_addr,
                                                       ida_member.id)
예제 #32
0
 def f_ExpandStruc(sid, off, delta, recalc):
     s = idaapi.get_struc(sid)
     return idaapi.expand_struc(s, off, delta, recalc)
예제 #33
0
    def save_strucs(self, memory_exporter):
        """
        Structures : export modified structures and delete those who have been deleted
        """
        for struc_id in self.structures_to_process:
            self.ida_model.clear_exported_struc_enum_id(struc_id)
            sidx = idc.GetStrucIdx(struc_id)
            if sidx is None or sidx == idc.BADADDR:
                # it is a deleted structure or a stackframe
                # in this last case we need to export the parent (function)
                eaFunc = idaapi.get_func_by_frame(struc_id)
                if eaFunc != idc.BADADDR:
                    # OK, it is a stackframe
                    self.ida_model.accept_struc(
                        memory_exporter, 0, struc_id, ya.OBJECT_TYPE_STACKFRAME, ya.OBJECT_TYPE_STACKFRAME_MEMBER,
                        stackframe_func_addr=eaFunc)
                    self.ida_model.accept_ea(memory_exporter, 0, eaFunc)
                else:
                    # it is a deleted structure
                    self.ida_model.accept_deleted_struc(memory_exporter, struc_id)
            else:

                self.ida_model.accept_struc(memory_exporter, 0, struc_id)

        logger.debug("Walking members")
        """
        Structure members : update modified ones, and remove deleted ones
        We iterate over members :
            -if the parent struc has been deleted, delete the member
            -otherwise, detect if the member has been updated or removed
                -updated : accept struc_member + accept_struc if not already exported!
                -removed : accept struc_member_deleted
        """
        for (struc_id, member_set) in self.strucmember_to_process.iteritems():
            ida_struc = idaapi.get_struc(struc_id)
            logger.debug("Walking struc 0x%08X" % struc_id)
            sidx = idc.GetStrucIdx(struc_id)
            is_stackframe = False
            struc_deleted = False
            if sidx is None or sidx == idc.BADADDR:
                f = idaapi.get_func_by_frame(struc_id)
                if f is not None and f != idc.BADADDR:
                    is_stackframe = True
                else:
                    struc_deleted = True

            if is_stackframe:
                strucmember_type = ya.OBJECT_TYPE_STACKFRAME_MEMBER
                struc_name = None
                struc_type = ya.OBJECT_TYPE_STACKFRAME
                eaFunc = idaapi.get_func_by_frame(struc_id)
                stackframe_func_addr = eaFunc
                func = idaapi.get_func(eaFunc)
                self.ida_model.accept_function(memory_exporter, 0, eaFunc, func)
            else:
                strucmember_type = ya.OBJECT_TYPE_STRUCT_MEMBER
                struc_type = ya.OBJECT_TYPE_STRUCT
                stackframe_func_addr = None
                if not struc_deleted:
                    struc_name = idc.GetStrucName(struc_id)

            if struc_deleted:
                # The structure has been deleted : we need to delete the members
                # Note: at first sight, it is not a stackframe
                # TODO: handle function->stackframe deletion here
                for (member_id, offset) in member_set:
                    self.ida_model.accept_deleted_strucmember(memory_exporter, struc_id, None, offset)
            else:
                # The structure or stackframe has been modified
                is_union = ida_struc.is_union()

                for (member_id, offset) in member_set:
                    ida_member = idaapi.get_member(ida_struc, offset)
                    if ida_member is None:
                        new_member_id = -1
                    else:
                        new_member_id = ida_member.id
                    logger.debug("exporting member %s at offset 0x%02X (mid=0x%016X)" %
                                 (strucmember_type, offset, member_id))
                    self.ida_model.clear_exported_struc_member_id(new_member_id)

                    if new_member_id == -1:
                        # the member has been deleted : delete it
                        self.ida_model.accept_deleted_strucmember(
                            memory_exporter, struc_id, struc_name, offset, struc_type, strucmember_type)
                    elif offset > 0 and idc.GetMemberId(struc_id, offset - 1) == new_member_id:
                        # the member was deleted, and replaced by a member starting above it
                        self.ida_model.accept_deleted_strucmember(
                            memory_exporter, struc_id, struc_name, offset, struc_type, strucmember_type)
                    elif new_member_id != member_id:
                        # the member has been deleted and later recreated
                        name = idaapi.get_member_name(new_member_id)
                        self.ida_model.accept_struc_member(
                            memory_exporter, 0, ida_struc, struc_id, is_union, offset, struc_name, name, struc_type,
                            strucmember_type, stackframe_func_addr=stackframe_func_addr)
                    else:
                        # the member has just been modified
                        name = idaapi.get_member_name(new_member_id)
                        logger.debug("exporting member %s (%s) at offset 0x%02X (mid=0x%016X)" %
                                     (strucmember_type, name, offset, member_id))
                        self.ida_model.accept_struc_member(
                            memory_exporter, 0, ida_struc, struc_id, is_union, offset, struc_name, name, struc_type,
                            strucmember_type, stackframe_func_addr=stackframe_func_addr)