def rename(self, name=None): """ Renames (and comments) the string variable in IDA. :param str name: New name to given encoded string. (defaults to decoded_string) """ name = name or self.display_name if not name: append_debug( 'Unable to rename encoded string due to no decoded string: {!r}'.format(self), log_token='[!]') # Set name and comment in stack variable. comment = '"{}"'.format(name[:self._MAX_COMMENT_LENGTH]) if len(name) > self._MAX_COMMENT_LENGTH: comment += ' (truncated)' if self.frame_id and self.stack_offset: idc.SetMemberComment(self.frame_id, self.stack_offset, comment, repeatable=1) var_name = re.sub('[^_$?@0-9A-Za-z]', '_', name[:self._MAX_NAME_LENGTH]) # Replace invalid characters if not var_name: raise ValueError('Unable to calculate var_name for : {!r}'.format(self)) var_name = 'a' + var_name.capitalize() idc.SetMemberName(self.frame_id, self.stack_offset, var_name) # Add a comment where the string is being used. if self.string_reference: idc.MakeRptCmt(self.string_reference, comment)
def yatest_create_struct_in_stack_vars_with_renaming(self): """ test creation of struct from stack vars used to find a bug (structure is correctly applied on var if renamed) """ # create structure ident, sida = self.get_function_sid_without_del( True, local_size=complex_struc3_size, count_from_first_var=True) self.assertNotEqual(sida, -1) sidb = idc.AddStrucEx(0, 'create_struct_in_stack_vars_with_renaming', 0) self.assertNotEqual(sidb, -1) size = self.create_complex2(sidb, complex_struc3) self.assertEqual(complex_struc3_size, size) # set first var prototype offset = idc.GetFirstMember(sida) member_id = idc.GetMemberId(sida, offset) self.assertNotEqual(member_id, -1) self.assertTrue( idc.SetType(member_id, "create_struct_in_stack_vars_with_renaming* x;")) self.assertEqual("create_struct_in_stack_vars_with_renaming *", idc.GetType(idc.GetMemberId(sida, offset))) idc.SetMemberName(sida, offset, "var1") yaunit.save("create_struct_in_stack_vars_with_renaming", sida) yaunit.save("create_struct_in_stack_vars_with_renaming_offset", offset)
def fixFields(self, size=None): flds = self.fields() umap = {} prev = -2 lst = -2 for y in flds: if not flds[y]['name']: if prev == y - 1: umap[lst] += 1 else: lst = y umap[lst] = 1 prev = y print "nfields", umap if len(umap) > 0: for x in umap: self.mkarr(x, umap[x]) flds = self.fields(True) for y in flds: x = flds[y] if not x['name'].startswith('field_'): continue nm = 'field_{:X}'.format(x['offset']) if x['name'] == nm: continue idc.SetMemberName(self.id, x['offset'], nm) x['name'] = nm self._fields[y] = x
def yatest_function_local_vars(self): addr = yaunit.get_next_function(yaunit.has_locals) frame = idaapi.get_frame(addr) offset = 0 frame_size = idaapi.get_struc_size(frame.id) while offset < frame_size: if idc.SetMemberName(frame.id, offset, 'local_var'): break offset += 1 yaunit.save('function_with_local_vars', addr)
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 + ';')
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 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
def set_name(self, value): return idc.SetMemberName(self.parent.sid, self.struct_offset, value)