def normalize(data): """Given the specified data, this static methods normalize its representation using Netzob types. :parameter data: the data to normalize :type data: :class:`object` :return: an abstractType which value is data :rtype: :class:`netzob.Common.Models.Types.AbstractType.AbstractType` >>> from netzob.all import * >>> normalizedData = AbstractType.normalize("netzob") >>> print normalizedData.__class__ <class 'netzob.Common.Models.Types.ASCII.ASCII'> >>> print normalizedData.value bitarray('011011100110010101110100011110100110111101100010') """ if data is None: raise TypeError("Cannot normalize None data") if isinstance(data, AbstractType): return data if isinstance(data, int): from netzob.Common.Models.Types.Integer import Integer return Integer(value=data) if isinstance(data, str): try: from netzob.Common.Models.Types.ASCII import ASCII normalizedData = ASCII(value=data) except: from netzob.Common.Models.Types.Raw import Raw normalizedData = Raw(value=data) return normalizedData raise TypeError("Not a valid data ({0}), impossible to normalize it.", type(data))
def __init__(self, fields, dataType=None, name=None): if isinstance(fields, AbstractField): fields = [fields] super(InternetChecksum, self).__init__("InternetChecksum", fieldDependencies=fields, name=name) if dataType is None: dataType = Raw(nbBytes=1) self.dataType = dataType
def __init__(self, fields, dataType=None, factor=1/float(8), offset=0, name=None): if isinstance(fields, AbstractField): fields = [fields] super(Size, self).__init__("Size", fieldDependencies=fields, name=name) self.fields = fields if dataType is None: dataType = Raw(nbBytes=1) self.dataType = dataType self.factor = factor self.offset = offset
def _splitFieldFollowingAlignment(self, field, align): """Update the field definition with new fields following the specified align.""" # STEP 1 : Create a field separation based on static and dynamic fields leftAlign, rightAlign = self._splitAlignment(align) splited = self._mergeAlign(leftAlign, rightAlign) step1Fields = [] for (entryVal, entryDyn) in splited: if entryDyn: newField = Field(Raw(nbBytes=(0, len(entryVal) / 2))) else: newField = Field(Raw(TypeConverter.convert(entryVal, HexaString, Raw))) step1Fields.append(newField) for f in step1Fields: f.encodingFunctions = field.encodingFunctions.values() field.fields = step1Fields
def __init__(self, domain=None, name="Field", layer=False): """ :keyword domain: the definition domain of the field (see domain property to get more information) :type domain: a :class:`list` of :class:`object`, default is Raw(None) :keyword name: the name of the field :type name: :class:`str` :keyword layer: a flag indicating if field is a layer :type layer: :class:`bool` """ super(Field, self).__init__(name, layer) if domain is None: domain = Raw(None) self.domain = domain
def reset(self, field): """Resets the format (field hierarchy and definition domain) of the specified field. :param field: the field we want to reset :type field: :class:`netzob.Common.Models.Vocabulary.AbstractField.AbstractField` :raise Exception if something bad happens """ if field is None: raise TypeError("The field to reset must be specified and cannot be None") self._logger.debug("Reset the definition of field {0} ({1})".format(field.name, field.id)) field.clearFields() if isinstance(field, Symbol): field.fields = [Field()] if isinstance(field, Field): field.domain = Raw(None) field.regex = NetzobRegex.buildDefaultRegex()
def split(field, delimiter): """Split a field (or symbol) with a specific delimiter. The delimiter can be passed either as an ASCII, a Raw, an HexaString, or any objects that inherit from AbstractType. >>> from netzob.all import * >>> samples = ["aaaaff000000ff10", "bbff110010ff00000011", "ccccccccfffe1f000000ff12"] >>> messages = [RawMessage(data=sample) for sample in samples] >>> symbol = Symbol(messages=messages[:3]) >>> Format.splitDelimiter(symbol, ASCII("ff")) >>> print symbol Field-0 | Field-sep-6666 | Field-2 | Field-sep-6666 | Field-4 ---------- | -------------- | ------------ | -------------- | ---------- 'aaaa' | 'ff' | '000000' | 'ff' | '10' 'bb' | 'ff' | '110010' | 'ff' | '00000011' 'cccccccc' | 'ff' | 'fe1f000000' | 'ff' | '12' ---------- | -------------- | ------------ | -------------- | ---------- >>> samples = ["434d446964656e74696679230400000066726564", "5245536964656e74696679230000000000000000", "434d44696e666f2300000000", "524553696e666f230000000004000000696e666f","434d4473746174732300000000","52455373746174732300000000050000007374617473","434d4461757468656e7469667923090000006d7950617373776421","52455361757468656e74696679230000000000000000","434d44656e6372797074230a00000031323334353674657374","524553656e637279707423000000000a00000073707176777436273136","434d4464656372797074230a00000073707176777436273136","5245536465637279707423000000000a00000031323334353674657374","434d446279652300000000","524553627965230000000000000000","434d446964656e746966792307000000526f626572746f","5245536964656e74696679230000000000000000","434d44696e666f2300000000","524553696e666f230000000004000000696e666f","434d4473746174732300000000","52455373746174732300000000050000007374617473","434d4461757468656e74696679230a000000615374726f6e67507764","52455361757468656e74696679230000000000000000","434d44656e63727970742306000000616263646566","524553656e6372797074230000000006000000232021262724","434d44646563727970742306000000232021262724","52455364656372797074230000000006000000616263646566","434d446279652300000000","524553627965230000000000000000"] >>> messages = [RawMessage(data=TypeConverter.convert(sample, HexaString, Raw)) for sample in samples] >>> symbol = Symbol(messages=messages) >>> symbol.encodingFunctions.add(TypeEncodingFunction(ASCII)) # Change visualization to hexastring >>> Format.splitDelimiter(symbol, ASCII("#")) >>> print symbol Field-0 | Field-sep-23 | Field-2 | Field-sep-23 | Field-4 --------------- | ------------ | -------------------- | ------------ | ------- 'CMDidentify' | '#' | '....fred' | '' | '' 'RESidentify' | '#' | '........' | '' | '' 'CMDinfo' | '#' | '....' | '' | '' 'RESinfo' | '#' | '........info' | '' | '' 'CMDstats' | '#' | '....' | '' | '' 'RESstats' | '#' | '........stats' | '' | '' 'CMDauthentify' | '#' | '....myPasswd!' | '' | '' 'RESauthentify' | '#' | '........' | '' | '' 'CMDencrypt' | '#' | '....123456test' | '' | '' 'RESencrypt' | '#' | "........spqvwt6'16" | '' | '' 'CMDdecrypt' | '#' | "....spqvwt6'16" | '' | '' 'RESdecrypt' | '#' | '........123456test' | '' | '' 'CMDbye' | '#' | '....' | '' | '' 'RESbye' | '#' | '........' | '' | '' 'CMDidentify' | '#' | '....Roberto' | '' | '' 'RESidentify' | '#' | '........' | '' | '' 'CMDinfo' | '#' | '....' | '' | '' 'RESinfo' | '#' | '........info' | '' | '' 'CMDstats' | '#' | '....' | '' | '' 'RESstats' | '#' | '........stats' | '' | '' 'CMDauthentify' | '#' | '....aStrongPwd' | '' | '' 'RESauthentify' | '#' | '........' | '' | '' 'CMDencrypt' | '#' | '....abcdef' | '' | '' 'RESencrypt' | '#' | '........' | '#' | " !&'$" 'CMDdecrypt' | '#' | '....' | '#' | " !&'$" 'RESdecrypt' | '#' | '........abcdef' | '' | '' 'CMDbye' | '#' | '....' | '' | '' 'RESbye' | '#' | '........' | '' | '' --------------- | ------------ | -------------------- | ------------ | ------- >>> print symbol.fields[0]._str_debug() Field-0 |-- Alt |-- Data (Raw='CMDidentify' ((0, 88))) |-- Data (Raw='RESidentify' ((0, 88))) |-- Data (Raw='CMDinfo' ((0, 56))) |-- Data (Raw='RESinfo' ((0, 56))) |-- Data (Raw='CMDstats' ((0, 64))) |-- Data (Raw='RESstats' ((0, 64))) |-- Data (Raw='CMDauthentify' ((0, 104))) |-- Data (Raw='RESauthentify' ((0, 104))) |-- Data (Raw='CMDencrypt' ((0, 80))) |-- Data (Raw='RESencrypt' ((0, 80))) |-- Data (Raw='CMDdecrypt' ((0, 80))) |-- Data (Raw='RESdecrypt' ((0, 80))) |-- Data (Raw='CMDbye' ((0, 48))) |-- Data (Raw='RESbye' ((0, 48))) :param field : the field to consider when spliting :type: :class:`netzob.Common.Models.Vocabulary.AbstractField.AbstractField` :param delimiter : the delimiter used to split messages of the field :type: :class:`netzob.Common.Models.Types.AbstractType.AbstractType` """ if delimiter is None: raise TypeError("Delimiter cannot be None.") if field is None: raise TypeError("Field cannot be None.") if len(field.messages) < 1: raise ValueError( "The associated symbol does not contain any message.") # Find message substrings after applying delimiter splittedMessages = [] for cell in field.getValues(encoded=False, styled=False): splittedMessage = cell.split(delimiter.value.tobytes()) splittedMessages.append(splittedMessage) import itertools # Inverse the array, so that columns contains observed values for each field splittedMessages = list(itertools.izip_longest(*splittedMessages)) # If the delimiter does not create splitted fields if len(splittedMessages) <= 1: return # Else, we add (2*len(splittedMessages)-1) fields newFields = [] iField = -1 for i in range(len(splittedMessages)): iField += 1 fieldDomain = list() # temporary set that hosts all the observed values to prevent useless duplicate ones observedValues = set() has_inserted_empty_value = False isEmptyField = True # To avoid adding an empty field for v in splittedMessages[i]: if v != "" and v is not None: isEmptyField = False if v not in observedValues: fieldDomain.append(Raw(v)) observedValues.add(v) else: if not has_inserted_empty_value: fieldDomain.append(Raw(nbBytes=0)) has_inserted_empty_value = True if not isEmptyField: newField = Field( domain=DomainFactory.normalizeDomain(fieldDomain), name="Field-" + str(iField)) newField.encodingFunctions = field.encodingFunctions.values() newFields.append(newField) iField += 1 fieldName = "Field-sep-" + TypeConverter.convert( delimiter.value, BitArray, HexaString) newFields.append( Field(domain=Alt([delimiter, Raw(nbBytes=0)]), name=fieldName)) newFields.pop() # Reset the field from netzob.Inference.Vocabulary.Format import Format Format.resetFormat(field) # Create a field for each entry field.fields = newFields
def execute(self, field): """Executes the field edition following the specified messages. Children of the specified field will be replaced with new fields. :param field: the format definition that will be user :type field: :class:`netzob.Common.Models.Vocabulary.AbstractField.AbstractField` :raise Exception: if something bad happens """ if field is None: raise TypeError("The field cannot be None") fieldValues = [ TypeConverter.convert(data, Raw, HexaString) for data in field.getValues(encoded=False) ] if len(fieldValues) == 0: raise Exception("No value found in the field.") # Retrieve longuest field value maxLengthFieldValue = len(max(fieldValues, key=len)) # definies the step following specified unitsize stepUnitsize = self.__computeStepForUnitsize() # Vertical identification of variation indexedValues = [] for i in range(0, maxLengthFieldValue, stepUnitsize): currentIndexValue = [] for fieldValue in fieldValues: if i < len(fieldValue): currentIndexValue.append( fieldValue[i:min(len(fieldValue), i + stepUnitsize)]) else: currentIndexValue.append('') indexedValues.append(currentIndexValue) # If requested, merges the adjacent static fields if self.mergeAdjacentStaticFields: result = [] staticSequences = [] for values in indexedValues: if len(set(values)) == 1: # static staticSequences.append(values[0]) else: # dynamic if len(staticSequences) > 0: result.append([''.join(staticSequences)]) staticSequences = [] result.append(values) if len(staticSequences) > 0: result.append([''.join(staticSequences)]) indexedValues = result # If requested, merges the adjacent dynamic fields if self.mergeAdjacentDynamicFields: result = [] dynamicSequences = [] for values in indexedValues: if len(set(values)) > 1: # dynamic dynamicSequences.append(values) else: # static if len(dynamicSequences) > 0: dynValues = map(None, *dynamicSequences) tmp_result = [] for d in dynValues: tmp_result.append(''.join( [x if x is not None else '' for x in d])) result.append(tmp_result) dynamicSequences = [] result.append(values) if len(dynamicSequences) > 0: dynValues = map(None, *dynamicSequences) tmp_result = [] for d in dynValues: tmp_result.append(''.join( [x if x is not None else '' for x in d])) result.append(tmp_result) indexedValues = result # Create a field for each entry newFields = [] for (i, val) in enumerate(indexedValues): fName = "Field-{0}".format(i) fDomain = DomainFactory.normalizeDomain([ Raw(TypeConverter.convert(v, HexaString, BitArray)) for v in set(val) ]) newFields.append(Field(domain=fDomain, name=fName)) # attach encoding functions for newField in newFields: newField.encodingFunctions = field.encodingFunctions.values() field.fields = newFields