def SetStrucmember(struc_id, member_name, offset, flag, typeid, nitems, member_type=ya.OBJECT_TYPE_STRUCT_MEMBER, name_offset=0): if member_name is None: member_name = get_default_struc_member_name(member_type, offset, name_offset) ret = idc.SetMemberName(struc_id, offset, member_name) if not ret: logger.debug("Error while naming sub strucmember (struc) : " + "%d (struc=%s, member=%s, offset=0x%08X" % (ret, idc.GetStrucName(struc_id), member_name, offset)) else: ret = idc.SetMemberType(struc_id, offset, flag, typeid, nitems) if ret == 0: logger.debug("Error while setting sub strucmember type (struc) :" + " %d (struc=%s, member=%s, offset=0x%08X, mflags=%d, nitems=%d, tid=0x%016X" % (ret, idc.GetStrucName(struc_id), member_name, offset, flag, nitems, typeid))
def fix_struc_in_prototype(self, proto, struc_ids): current_pos = 0 while proto.find("/*%", current_pos) != -1: start_comm = proto.find("/*%", current_pos) end_comm = proto.find("%*/", start_comm + 3) sharp = proto.find("#", start_comm + 3) struc_name = proto[start_comm + 3:sharp] object_id_str = proto[sharp + 1:end_comm] object_id = ya.YaToolObjectId_From_String(object_id_str) try: struc_id = struc_ids[object_id] except KeyError: logger.error( "Bad object id str for struc in prototype : %s (in '%s')" % (object_id_str, proto)) return proto new_struc_name = idc.GetStrucName(struc_id) if new_struc_name != struc_name: orig_proto = proto proto = proto.replace(struc_name, new_struc_name) logger.debug("Updated proto from '%s' to '%s'" % (orig_proto, proto)) current_pos = 0 else: current_pos = end_comm + 2 return proto
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)
def get_structures(): """ Populate dictionaries with imported structures infomation""" structure_ids = {} if idc.GetStrucQty() == 0: return None index = None for i in xrange(0, idc.GetStrucQty()): if i == 0: index = idc.GetFirstStrucIdx() else: index = idc.GetNextStrucIdx(index) if index == idaapi.BADADDR: continue sid = idc.GetStrucId(index) if sid == idaapi.BADADDR: continue name = idc.GetStrucName(sid) if not name: continue structure_ids[sid] = name return structure_ids
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
def struc_created(self, struc): self.pre_hook() if LOG_IDB_EVENTS: self.debug_event("struc_created : 0x%08X (%s)" % (struc, idc.GetStrucName(struc))) hooks.ida.struc_updated(struc) return idaapi.IDB_Hooks.struc_created(self, struc)
def struc_renamed(self, struct): sid = struct.id idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) self.ctrl._handle_action({ 'action': 'struct_renamed', 'struct': idx, 'sname': sname }) return 0
def create_struct_fields(sid=None, name=None, accesses=None, create=False, base=0): """Create an IDA struct with fields corresponding to the specified access pattern. Given a sequence of (offset, size) tuples designating the valid access points to the struct, create fields in the struct at the corresponding positions. Options: sid: The struct id, if the struct already exists. name: The name of the struct to update or create. accesses: The set of (offset, size) tuples representing the valid access points in the struct. create: If True, then the struct will be created with the specified name if it does not already exist. Default is False. base: The base offset for the struct. Offsets smaller than this are ignored, otherwise the field is created at the offset minus the base. Default is 0. Either sid or name must be specified. """ # Get the struct id. if sid is None: sid = idau.struct_open(name, create=True) if sid is None: _log(0, 'Could not open struct {}', name) return False else: name = idc.GetStrucName(sid) if name is None: _log(0, 'Invalid struct id {}', sid) return False # Now, for each (offset, size) pair, create a struct member. Right now we completely ignore the # possibility that some members will overlap (for various reasons; it's actually more common # than I initially thought, though I haven't investigated why). # TODO: In the future we should address this by either automatically generating sub-unions or # choosing the most appropriate member when permissible (e.g. (0, 8), (0, 2), (4, 4) might # create (0, 2), (2, 2), (4, 4)). I think the most reasonable default policy is to create the # biggest members that satisfy all accesses. success = True for offset, size in accesses: if offset < base: continue member = field_name(offset) ret = idau.struct_add_word(sid, member, offset - base, size) if ret != 0: if ret == idc.STRUC_ERROR_MEMBER_OFFSET: _log(2, 'Could not add {}.{} for access ({}, {})', name, member, offset, size) else: success = False _log(1, 'Could not add {}.{} for access ({}, {}): {}', name, member, offset, size, ret) return success
def Structs(): """ Get a list of structures @return: List of tuples (idx, sid, name) """ idx = idc.GetFirstStrucIdx() while idx != idaapi.BADADDR: sid = idc.GetStrucId(idx) yield (idx, sid, idc.GetStrucName(sid)) idx = idc.GetNextStrucIdx(idx)
def struc_cmt_changed(self, sid): idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) cmt = idc.GetEnumCmt(sid, 0) self.ctrl._handle_action({ 'action': 'struct_cmt_changed', 'struct': idx, 'sname': sname, 'cmt': cmt }) return 0
def struc_member_deleted(self, struct, mid, moff): sid = struct.id idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) self.ctrl._handle_action({ 'action': 'struct_member_deleted', 'struct': idx, 'sname': sname, 'member': mid, 'off': moff }) return 0
def struc_expanded(self, struct): sid = struct.id sname = idc.GetStrucName(sid) size = idc.GetStrucSize(sid) idx = idc.GetStrucIdx(sid) self.ctrl._handle_action({ 'action': 'struct_expanded', 'struct': idx, 'sname': sname, 'size': size }) return 0
def struc_created(self, struct): ### we have to maintain our own struct db ## becuse ida sux... sname = idc.GetStrucName(struct) union = idc.IsUnion(struct) idx = idc.GetStrucIdx(struct) self.ctrl._handle_action({ 'action': 'struct_created', 'struct': idx, 'sname': sname, 'union': union }) self.ctrl.db.struct_add(struct, idx) return 0
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
def __init__(self, name): if isinstance(name, (int, long)): name = str(name) self.align = 8 self.name = name self.id = idc.GetStrucIdByName(name) if self.id == idc.BADADDR: try: self.id = int(name) self.name = idc.GetStrucName(self.id) if not self.name: raise "" except Exception: raise Struct.StructNotFoundError(name) self._xrefs = None self._fields = None self._inst = None self._showFields = None
def read_struct(ea, struct=None, sid=None, members=None, asobject=False): """Read a structure from the given address. This function reads the structure at the given address and converts it into a dictionary or accessor object. Arguments: ea: The linear address of the start of the structure. Options: sid: The structure ID of the structure type to read. struct: The name of the structure type to read. members: A list of the names of the member fields to read. If members is None, then all members are read. Default is None. asobject: If True, then the struct is returned as a Python object rather than a dict. One of sid and struct must be specified. """ # Handle sid/struct. if struct is not None: sid2 = idc.GetStrucIdByName(struct) if sid2 == idc.BADADDR: raise ValueError('Invalid struc name {}'.format(struct)) if sid is not None and sid2 != sid: raise ValueError('Invalid arguments: sid={}, struct={}'.format( sid, struct)) sid = sid2 else: if sid is None: raise ValueError('Invalid arguments: sid={}, struct={}'.format( sid, struct)) if idc.GetStrucName(sid) is None: raise ValueError('Invalid struc id {}'.format(sid)) # Iterate through the members and add them to the struct. union = idc.IsUnion(sid) struct = {} for offset, name, size in idautils.StructMembers(sid): if members is not None and name not in members: continue _read_struct_member(struct, sid, union, ea, offset, name, size, asobject) if asobject: struct = objectview(struct, ea, idc.GetStrucSize(sid)) return struct
def struct_member_error(err, sid, name, offset, size): """Create and format a struct member exception. Args: err: The error value returned from struct member creation sid: The struct id name: The member name offset: Memeber offset size: Member size Returns: A ``SarkErrorAddStructMemeberFailed`` derivative exception, with an informative message. """ exception, msg = STRUCT_ERROR_MAP[err] struct_name = idc.GetStrucName(sid) return exception( ('AddStructMember(struct="{}", member="{}", offset={}, size={}) ' 'failed: {}').format(struct_name, name, offset, size, msg))
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
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 = yatools.ea_to_hex(ea) else: prefix = "%s,%s" % (yatools.ea_to_hex(ea), foffset) self.auto_comments.add((prefix, text)) else: self.auto_comments.add(("", text))
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)
def dispatch(args): ## dispatch args.... class A(): pass a = A() for name in args: setattr(a, name, args[name]) del args ### dispatch idp events if a.action == 'rename': debug('[*] renaming %s to %s @ %x', a.old_name, a.new_name, a.ea) idc.MakeNameEx(a.ea, str(a.new_name), idaapi.SN_NOWARN) return ## dispatch idb events if a.action == 'cmt_changed': if not a.cmt: a.cmt = '' _pcmt = a.cmt if len(a.cmt) < 10 else a.cmt[:10] + '...' debug('[*] cmt changed @ %X (rep:%s) - %s', a.ea, a.rep, _pcmt) if a.rep: idc.MakeRptCmt(a.ea, str(a.cmt)) else: idc.MakeComm(a.ea, str(a.cmt)) if a.action == 'struct_created': debug('[*] Struct %s created with id %x', a.sname, a.struct) print idc.AddStrucEx(-1, str(a.sname), a.union) if a.action == 'struct_deleted': sid = idc.GetStrucId(a.struct) sname = idc.GetStrucName(sid) debug('[*] Struct(%x) %s deleted', a.struct, sname) idc.DelStruc(sid) if a.action == 'struct_renamed': sid = idc.GetStrucId(a.struct) sname = idc.GetStrucName(sid) debug('[*] Struct(%d - %x) renamed from %s to %s', a.struct, sid, sname, a.sname) idc.SetStrucName(sid, str(a.sname)) if a.action == 'struct_cmt_changed': sid = idc.GetStrucId(a.struct) debug('[*] Struct(%d - %x) %s - cmt changed', a.struct, sid, a.sname) idc.SetStrucComment(sid, a.cmt, 0) if a.action == 'struct_expanded': pass if a.action == 'struct_member_created': pass if a.action == 'struct_member_deleted': pass if a.action == 'struct_member_renamed': pass if a.action == 'struct_member_changed': pass if a.action == 'struct_member_': pass if a.action == 'struct_member_created': pass if a.action == 'struct_member_created': pass # if a.action == 'struct_expanded': # debug(' return 0
def name(id, name=None): if name is None: return idc.GetStrucName(id) return idc.SetStrucName(id, name)
def get_name(self): return idc.GetStrucName(self.sid) or "{no name}"
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)
def make_struc_member(self, object_version, address, member_type=ya.OBJECT_TYPE_STRUCT_MEMBER): struc_object_id = object_version.get_parent_object_id() struc_id = 0 try: struc_id = self.struc_ids[struc_object_id] except: return is_union = struc_id in self.union_ids offset = address if is_union: last_offset = idc.GetLastMember(struc_id) if last_offset == idc.BADADDR: last_offset = -1 if last_offset < offset: for i in xrange(last_offset + 1, offset + 1): idc.AddStrucMember(struc_id, "yaco_filler_%d" % i, 0, idc.FF_BYTE | idc.FF_DATA, -1, 1) # ensure that 'offset' fields are present member_size = object_version.get_size() member_name = object_version.get_name() flags = object_version.get_object_flags() if idc.isStruct(flags): # if the sub field is a struct, it must have a single Xref field with the struct object id try: sub_struc_object_id = object_version.getXRefIdsAt(0, 0)[0] sub_struc_id = self.struc_ids[sub_struc_object_id] # logger.debug("%20s: adding sub member at offset 0x%08X, # size=0x%08X (sub=0x%.016X, size=0x%08X) with name %s" % # ( # idc.GetStrucName(struc_id), offset, member_size, sub_struc_id, # idc.GetStrucSize(sub_struc_id), object_version.get_name() # )) sub_struc_size = idc.GetStrucSize(sub_struc_id) if sub_struc_size == 0: logger.error( "%20s: adding sub member at offset 0x%08X, size=0x%08X " "(sub=0x%.016X, size=0x%08X) with name %s : sub struc size is ZERO" % (idc.GetStrucName(struc_id), offset, member_size, sub_struc_id, idc.GetStrucSize(sub_struc_id), object_version.get_name())) else: nitems = member_size / sub_struc_size YaToolIDATools.SetStrucmember(struc_id, member_name, offset, flags, sub_struc_id, nitems) except KeyError: logger.error( "Error while looking for sub struc in struc %s, offset 0x%08X (field name='%s')" % (self.hash_provider.hash_to_string(struc_object_id), offset, object_version.get_name())) traceback.print_exc() elif idc.isEnum0(flags): # an enum is applied here try: sub_enum_object_id = object_version.getXRefIdsAt(0, 0)[0] sub_enum_id = self.enum_ids[sub_enum_object_id] name_ok = idc.SetMemberName(struc_id, offset, member_name) if name_ok is not True: logger.debug( "Error while setting member name (enum) : " "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X" % (name_ok, idc.GetStrucName(struc_id), member_name, offset, flags, member_size, sub_struc_id)) else: sub_enum_size = idc.GetEnumWidth(sub_enum_id) if sub_enum_size == 0: sub_enum_size = member_size nitems = member_size / sub_enum_size ret = idc.SetMemberType(struc_id, offset, flags, sub_enum_id, nitems) if ret == 0: logger.debug( "Error while setting member type (enum) : " "(struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d, tid=0x%016X" % (ret, idc.GetStrucName(struc_id), member_name, offset, flags, member_size, sub_struc_id)) except KeyError: logger.error( "Error while looking for sub enum in struc %s, offset 0x%08X (field name='%s')" % (struc_object_id, offset, member_name)) traceback.print_exc() else: # logger.debug("%20s: adding member at offset 0x%08X, size=0x%08X with name %s" % # ( # idc.GetStrucName(struc_id), offset, member_size, object_version.get_name() # )) tid = -1 if idc.isASCII(flags): logger.debug( "object: %s : %s" % (self.hash_provider.hash_to_string( object_version.get_id()), object_version.get_name())) try: tid = object_version.get_string_type() except KeyError: tid = idc.ASCSTR_C name_ok = idc.SetMemberName(struc_id, offset, member_name) if name_ok is not True: logger.debug( "Error while setting member name :" + " (struc_id=0x%08X, struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)" % (struc_id, idc.GetStrucName(struc_id), member_name, offset, flags, member_size)) else: item_size = YaToolIDATools.get_field_size(flags, tid) nitems = member_size / item_size # IDA BUG : 4-byte chars are stored as 2 double words, thus me must # multiply nitem by 2! ret = idc.SetMemberType(struc_id, offset, flags, tid, nitems) if ret == 0: logger.debug( "Error while setting member type :" + " (struc=%s, member=%s, offset=0x%08X, mflags=%d, msize=%d)" % (idc.GetStrucName(struc_id), member_name, offset, flags, member_size)) try: repeatable_headercomment = self.sanitize_comment_to_ascii( object_version.get_header_comment(True)) idc.SetMemberComment(struc_id, offset, repeatable_headercomment, 1) except KeyError: pass try: nonrepeatable_headercomment = self.sanitize_comment_to_ascii( object_version.get_header_comment(False)) idc.SetMemberComment(struc_id, offset, nonrepeatable_headercomment, 0) except KeyError: pass member_id = idc.GetMemberId(struc_id, offset) self.set_struct_member_type(object_version, member_id) if object_version.get_type() == ya.OBJECT_TYPE_STRUCT_MEMBER: self.strucmember_ids[object_version.get_id()] = member_id