def size(string): '''Returns the size of a type described by a C declaration in `string`.''' string = string.strip() if string.lower() == 'void': return 0 elif string.startswith('class') and string.endswith('&'): res = idaapi.idc_parse_decl(idaapi.cvar.idati, 'void*;', 0) else: semicoloned = string if string.endswith(';') else "{:s};".format(string) res = idaapi.idc_parse_decl(idaapi.cvar.idati, internal.utils.string.to(semicoloned), 0) if res is None: raise internal.exceptions.DisassemblerError(u"Unable to parse the specified C declaration (\"{:s}\").".format(internal.utils.string.escape(string, '"'))) _, type, _ = res f = idaapi.get_type_size0 if idaapi.__version__ < 6.8 else idaapi.calc_type_size return f(idaapi.cvar.idati, type)
def size(string): '''returns the size of a c declaration''' string = string.strip() if string.lower() == 'void': return 0 elif string.startswith('class') and string.endswith('&'): result = idaapi.idc_parse_decl(idaapi.cvar.idati, 'void*;', 0) else: result = idaapi.idc_parse_decl( idaapi.cvar.idati, string if string.endswith(';') else string + ';', 0) if result is None: raise TypeError, 'Unable to parse C declaration : %r' % str _, type, _ = result return idaapi.get_type_size0(idaapi.cvar.idati, type)
def pack(self, start=0, stop=None): if self.collisions[start:stop].count(True): print "[Warning] Collisions detected" return final_tinfo = idaapi.tinfo_t() udt_data = idaapi.udt_type_data_t() origin = self.items[start].offset if start else 0 offset = origin for item in filter(lambda x: x.enabled, self.items[start:stop]): # Filter disabled members gap_size = item.offset - offset if gap_size: udt_data.push_back(TemporaryStructureModel.get_padding_member(offset - origin, gap_size)) if item.is_array: array_size = self.calculate_array_size(bisect.bisect_left(self.items, item)) if array_size: udt_data.push_back(item.get_udt_member(array_size, offset=origin)) offset = item.offset + item.size * array_size continue udt_data.push_back(item.get_udt_member(offset=origin)) offset = item.offset + item.size final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) cdecl = idaapi.print_tinfo(None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, final_tinfo, self.structure_name, None) cdecl = idaapi.asktext(0x10000, '#pragma pack(push, 1)\n' + cdecl, "The following new type will be created") if cdecl: structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0] previous_ordinal = idaapi.get_type_ordinal(idaapi.cvar.idati, structure_name) if previous_ordinal: reply = QtGui.QMessageBox.question( None, "HexRaysPyTools", "Structure already exist. Do you want to overwrite it?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No ) if reply == QtGui.QMessageBox.Yes: idaapi.del_numbered_type(idaapi.cvar.idati, previous_ordinal) ordinal = idaapi.idc_set_local_type(previous_ordinal, cdecl, idaapi.PT_TYP) else: return else: ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP) if ordinal: print "[Info] New type {0} was added to Local Types".format(structure_name) tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name) if tid: tinfo = idaapi.create_typedef(structure_name) ptr_tinfo = idaapi.tinfo_t() ptr_tinfo.create_ptr(tinfo) for scanned_var in self.get_unique_scanned_variables(origin): scanned_var.apply_type(ptr_tinfo) return tinfo else: print "[ERROR] Structure {0} probably already exist".format(structure_name)
def size(string): '''Returns the size of a type described by a C declaration in `string`.''' string = string.strip() if string.lower() == 'void': return 0 elif string.startswith('class') and string.endswith('&'): result = idaapi.idc_parse_decl(idaapi.cvar.idati, 'void*;', 0) else: result = idaapi.idc_parse_decl( idaapi.cvar.idati, string if string.endswith(';') else string + ';', 0) if result is None: raise internal.exceptions.DisassemblerError( "Unable to parse the specified C declaration ({!r}).".format( string)) _, type, _ = result return idaapi.get_type_size0(idaapi.cvar.idati, type)
def pack(self, start=0, stop=None): if self.collisions[start:stop].count(True): print "[Warning] Collisions detected" return final_tinfo = idaapi.tinfo_t() udt_data = idaapi.udt_type_data_t() origin = self.items[start].offset offset = origin for item in filter(lambda x: x.enabled, self.items[start:stop]): # Filter disabled members gap_size = item.offset - offset if gap_size: udt_data.push_back( TemporaryStructureModel.get_padding_member( offset - origin, gap_size)) if item.is_array: array_size = self.calculate_array_size( bisect.bisect_left(self.items, item)) if array_size: udt_data.push_back( item.get_udt_member(array_size, offset=origin)) offset = item.offset + item.size * array_size continue udt_data.push_back(item.get_udt_member(offset=origin)) offset = item.offset + item.size final_tinfo.create_udt(udt_data, idaapi.BTF_STRUCT) cdecl = idaapi.print_tinfo( None, 4, 5, idaapi.PRTYPE_MULTI | idaapi.PRTYPE_TYPE | idaapi.PRTYPE_SEMI, final_tinfo, self.structure_name, None) cdecl = idaapi.asktext(0x10000, cdecl, "The following new type will be created") if cdecl: structure_name = idaapi.idc_parse_decl(idaapi.cvar.idati, cdecl, idaapi.PT_TYP)[0] ordinal = idaapi.idc_set_local_type(-1, cdecl, idaapi.PT_TYP) if ordinal: print "[Info] New type {0} was added to Local Types".format( structure_name) tid = idaapi.import_type(idaapi.cvar.idati, -1, structure_name) if tid: tinfo = idaapi.create_typedef(structure_name) ptr_tinfo = idaapi.tinfo_t() ptr_tinfo.create_ptr(tinfo) for scanned_var in self.get_scanned_variables(origin): scanned_var.apply_type(ptr_tinfo) return tinfo else: print "[ERROR] Structure {0} probably already exist".format( structure_name) return None
def size(string): '''Returns the size of a type described by a C declaration in `string`.''' string = string.strip() if string.lower() == 'void': return 0 elif string.startswith('class') and string.endswith('&'): res = idaapi.idc_parse_decl(idaapi.cvar.idati, 'void*;', 0) else: semicoloned = string if string.endswith(';') else "{:s};".format( string) res = idaapi.idc_parse_decl(idaapi.cvar.idati, internal.utils.string.to(semicoloned), 0) if res is None: raise internal.exceptions.DisassemblerError( u"Unable to parse the specified C declaration (\"{:s}\").".format( internal.utils.string.escape(string, '"'))) _, type, _ = res f = idaapi.get_type_size0 if idaapi.__version__ < 6.8 else idaapi.calc_type_size return f(idaapi.cvar.idati, type)