Пример #1
0
    def encodeChild(self, variable, readingToken):
        result = []

        if not readingToken.isValueForVariableAvailable(variable):
            return result

        if variable.varType == "Data" or variable.varType == "Size" or variable.varType == "InternetChecksum" or variable.varType == "CRC32":
            val = readingToken.getValueForVariable(variable)
            encodedVal = TypeConverter.convert(val, BitArray,
                                               variable.dataType.__class__)
        if variable.varType == "Data" or variable.varType == "Size" or variable.varType == "InternetChecksum":
            val = readingToken.getValueForVariable(variable)
            encodedVal = TypeConverter.convert(val, BitArray,
                                               variable.dataType.__class__)
            result.append(str(encodedVal))
        elif variable.varType == "Agg" or variable.varType == "Alt":
            for child in variable.children:
                result.extend(self.encodeChild(child, readingToken))
        elif variable.varType == "Eol":
            # nothing to encode when child is EOL
            pass
        else:
            raise Exception("Unknown type of variable: {0}".format(
                variable.varType))
            raise Exception("Unknown type of variable: {0}".format(
                variable.varType))

        if len(result) == 0:
            return ''
        else:
            return ''.join(result)
Пример #2
0
    def __init__(self,
                 value=None,
                 nbBytes=None,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign(),
                 alphabet=None):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            if isinstance(value, str):
                value = TypeConverter.convert(bytes(value, "utf-8"), Raw,
                                              BitArray)
            elif isinstance(value, bytes):
                value = TypeConverter.convert(value, Raw, BitArray)

        nbBits = self._convertNbBytesinNbBits(nbBytes)

        self.alphabet = alphabet

        super(Raw, self).__init__(self.__class__.__name__,
                                  value,
                                  nbBits,
                                  unitSize=unitSize,
                                  endianness=endianness,
                                  sign=sign)
Пример #3
0
    def _deserializeAlignment(self,
                              regex,
                              mask,
                              unitSize=AbstractType.UNITSIZE_8):
        """
        deserializeAlignment: Transforms the C extension results
        in a python readable way
        @param regex the C returned regex
        @param mask the C returned mask
        @param unitSize the unitSize
        @returns the python alignment
        """
        if not (unitSize == AbstractType.UNITSIZE_8 or
                unitSize == AbstractType.UNITSIZE_4):
            raise ValueError(
                "Deserializing with unitSize {0} not yet implemented, only 4 and 8 supported.".
                format(unitSize))

        align = b""
        for i, c in enumerate(mask):
            if c != 2:
                if c == 1:
                    if unitSize == AbstractType.UNITSIZE_8:
                        align += b"--"
                    elif unitSize == AbstractType.UNITSIZE_4:
                        align += b"-"
                else:
                    if unitSize == AbstractType.UNITSIZE_8:
                        align += TypeConverter.convert(regex[i:i + 1], Raw,
                                                       HexaString)
                    elif unitSize == AbstractType.UNITSIZE_4:
                        align += TypeConverter.convert(regex[i:i + 1], Raw,
                                                       HexaString)[1:]
        return align
Пример #4
0
    def _sizeRelation(self, x, x_attribute, y, y_attribute):
        if x_attribute == self.ATTR_SIZE:
            if len(x) > 0:
                x = len(x)
        else:
            if len(x) > 0:
                x = TypeConverter.convert(x[:8], Raw, Integer)
            else:
                x = 0
        if y_attribute == self.ATTR_SIZE:
            if len(y) > 0:
                y = len(y)
        else:
            if len(y) > 0:
                # Integer only may be 1, 2, 4, or 8 bytes long, so for conversion
                # we need to add 0 padding at the front of the raw numbers
                if len(y) == 3:
                    padded_y = b'\x00' + y
                elif len(y) in (5,6,7):
                    padding_length = 8 - len(y)
                    padded_y = padding_length *  b'\x00' + y
                else:
                    padded_y = y
                y = TypeConverter.convert(padded_y[:8], Raw, Integer)
            else:
                y = 0

        if x == y:
            return True
        else:
            return False
Пример #5
0
    def generate(self, generationStrategy=None):
        """Generates a random IPv4 which follows the constraints.

        >>> from netzob.all import *
        >>> f = Field(IPv4())
        >>> len(f.specialize())
        4

        >>> f = Field(IPv4("192.168.0.10"))
        >>> TypeConverter.convert(f.specialize(), Raw, IPv4)
        IPAddress('192.168.0.10')

        >>> f = Field(IPv4(network="10.10.10.0/24"))
        >>> TypeConverter.convert(f.specialize(), Raw, IPv4) in IPNetwork("10.10.10.0/24")
        True

        """
        from netzob.Model.Vocabulary.Types.BitArray import BitArray
        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.Raw import Raw

        if self.value is not None:
            return self.value
        elif self.network is not None:
            ip = random.choice(self.network)
            return TypeConverter.convert(
                ip.packed,
                Raw,
                BitArray,
                src_unitSize=self.unitSize,
                src_endianness=self.endianness,
                src_sign=self.sign,
                dst_unitSize=self.unitSize,
                dst_endianness=self.endianness,
                dst_sign=self.sign)
        else:
            not_valid = [10, 127, 169, 172, 192]

            first = random.randrange(1, 256)
            while first in not_valid:
                first = random.randrange(1, 256)

            strip = ".".join([
                str(first), str(random.randrange(1, 256)),
                str(random.randrange(1, 256)), str(random.randrange(1, 256))
            ])

            ip = IPv4.encode(strip)
            return TypeConverter.convert(
                ip.packed,
                Raw,
                BitArray,
                src_unitSize=self.unitSize,
                src_endianness=self.endianness,
                src_sign=self.sign,
                dst_unitSize=self.unitSize,
                dst_endianness=self.endianness,
                dst_sign=self.sign)
Пример #6
0
    def generate(self, generationStrategy=None):
        """Generates a random IPv4 which follows the constraints.

        >>> from netzob.all import *
        >>> f = Field(IPv4())
        >>> len(f.specialize())
        4

        >>> f = Field(IPv4("192.168.0.10"))
        >>> TypeConverter.convert(f.specialize(), Raw, IPv4)
        IPAddress('192.168.0.10')

        >>> f = Field(IPv4(network="10.10.10.0/24"))
        >>> TypeConverter.convert(f.specialize(), Raw, IPv4) in IPNetwork("10.10.10.0/24")
        True

        """
        from netzob.Model.Vocabulary.Types.BitArray import BitArray
        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.Raw import Raw

        if self.value is not None:
            return self.value
        elif self.network is not None:
            ip = random.choice(self.network)
            return TypeConverter.convert(ip.packed,
                                         Raw,
                                         BitArray,
                                         src_unitSize=self.unitSize,
                                         src_endianness=self.endianness,
                                         src_sign=self.sign,
                                         dst_unitSize=self.unitSize,
                                         dst_endianness=self.endianness,
                                         dst_sign=self.sign)
        else:
            not_valid = [10, 127, 169, 172, 192]

            first = random.randrange(1, 256)
            while first in not_valid:
                first = random.randrange(1, 256)

            strip = ".".join([
                str(first),
                str(random.randrange(1, 256)),
                str(random.randrange(1, 256)),
                str(random.randrange(1, 256))
            ])

            ip = IPv4.encode(strip)
            return TypeConverter.convert(ip.packed,
                                         Raw,
                                         BitArray,
                                         src_unitSize=self.unitSize,
                                         src_endianness=self.endianness,
                                         src_sign=self.sign,
                                         dst_unitSize=self.unitSize,
                                         dst_endianness=self.endianness,
                                         dst_sign=self.sign)
Пример #7
0
    def _update_presets(self, symbol):
        """Update the presets dict, according to the symbol definition.

        """

        if self.presets is None:
            return

        new_keys = {}
        old_keys = []
        for k, v in list(self.presets.items()):

            # Handle case where k is a Field
            if isinstance(k, Field):
                if isinstance(v, bitarray):
                    continue
                elif hasattr(k.domain, "dataType"):
                    self.presets[k] = TypeConverter.convert(v, k.domain.dataType.__class__, BitArray,
                                                            src_unitSize=k.domain.dataType.unitSize,
                                                            dst_unitSize=k.domain.dataType.unitSize,
                                                            src_sign=k.domain.dataType.sign,
                                                            dst_sign=k.domain.dataType.sign,
                                                            src_endianness=k.domain.dataType.endianness,
                                                            dst_endianness=k.domain.dataType.endianness)
                else:
                    raise Exception("Cannot find the default dataType for field '{}'".format(k))

            # Handle case where k is a string
            elif isinstance(k, str):

                # Retrieve associated Field based on its string name
                for f in symbol.getLeafFields(includePseudoFields=True):
                    if f.name == k:
                        if isinstance(v, bitarray):
                            new_keys[f] = v
                            old_keys.append(k)
                        elif hasattr(f.domain, "dataType"):
                            new_keys[f] = TypeConverter.convert(v, f.domain.dataType.__class__, BitArray,
                                                                src_unitSize=f.domain.dataType.unitSize,
                                                                dst_unitSize=f.domain.dataType.unitSize,
                                                                src_sign=f.domain.dataType.sign,
                                                                dst_sign=f.domain.dataType.sign,
                                                                src_endianness=f.domain.dataType.endianness,
                                                                dst_endianness=f.domain.dataType.endianness)
                            old_keys.append(k)
                        else:
                            raise Exception("Cannot find the default dataType for field '{}'".format(f))
                        break
            else:
                raise Exception("Preset's keys must be of Field or string types")

        # Replace string keys by their equivalent Field keys
        for old_key in old_keys:
            self.presets.pop(old_key)
        self.presets.update(new_keys)
Пример #8
0
    def _computeExpectedValue(self, parsingPath):
        self._logger.debug(
            "compute expected value for Internet checksum field")

        # first checks the pointed fields all have a value
        hasValue = True
        for field in self.fieldDependencies:
            if field.domain is not self and not parsingPath.isDataAvailableForVariable(field.domain):
                self._logger.debug("The following field domain has no value: '{0}'".format(field.domain))
                hasValue = False

        if not hasValue:
            raise Exception(
                "Expected value cannot be computed, some dependencies are missing for domain {0}".
                format(self))
        else:
            fieldValues = []
            for field in self.fieldDependencies:
                if field.domain is self:
                    fieldSize = random.randint(field.domain.dataType.size[0], field.domain.dataType.size[1])
                    fieldValue = TypeConverter.convert(b"\x00" * int(fieldSize / 8), Raw, BitArray)
                else:
                    fieldValue = parsingPath.getDataAssignedToVariable(field.domain)

                if fieldValue is None:
                    break
                elif fieldValue.tobytes() == TypeConverter.convert("PENDING VALUE", ASCII, BitArray).tobytes():
                    # Handle case where field value is not currently known.
                    raise Exception("Expected value cannot be computed, some dependencies are missing for domain {0}".format(self))
                else:
                    fieldValues.append(fieldValue)

            # Aggregate all field value in a uniq bitarray object
            concatFieldValues = bitarray('')
            for f in fieldValues:
                concatFieldValues += f

            # Convert the bitarray object in a Raw object, as the checksum function expect a Raw input
            concatFieldValues = TypeConverter.convert(concatFieldValues, BitArray, Raw)

            # compute the checksum of this value
            chsum = self.__checksum(concatFieldValues)
            b = TypeConverter.convert(chsum, Integer, BitArray,
                                      src_endianness=AbstractType.ENDIAN_LITTLE,
                                      dst_endianness=self.dataType.endianness,
                                      src_unitSize=AbstractType.UNITSIZE_16,
                                      src_sign = AbstractType.SIGN_UNSIGNED)
            return b
Пример #9
0
    def _writeSymbol(self, symbol, presets=None):
        """Write the specified symbol on the communication channel after
        specializing it into a contextualized message.

        :param symbol: the symbol to write on the channel
        :type symbol: :class:`netzob.Model.Vocabulary.Symbol.Symbol`

        :param presets: specifies how to parameterize the emitted symbol
        :type presets: dict

        :raise TypeError if parameter is not valid and Exception if an exception occurs.

        """

        self._logger.debug("Specializing symbol '{0}' (id={1}).".format(
            symbol.name, symbol.id))

        self.specializer.presets = presets
        dataBin = self.specializer.specializeSymbol(symbol).generatedContent
        self.specializer.presets = None

        self.memory = self.specializer.memory
        self.parser.memory = self.memory
        data = TypeConverter.convert(dataBin, BitArray, Raw)

        len_data = self.channel.write(data)
        self._logger.debug(
            "Writing {} octets to commnunication channel done..".format(
                len_data))
        return len_data
Пример #10
0
    def __init__(self,
                 value=None,
                 network=None,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        """Builds an IPv4 domain with optional constraints.

        :parameter value: specify a constraints over the expected value.
        :type value: an str, an IPAddress or an int which can be parsed as an IPv4 (ex. "192.168.0.10")
        :parameter network: if no value is specified (None), a constraints over the network the parsed IP belongs can be specified with this parameter (ex. "192.168.0.0/24")
        :type network: an str or an IPAddress which can be parsed as a network IPv4
        """

        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            value = TypeConverter.convert(value,
                                          IPv4,
                                          BitArray,
                                          src_unitSize=unitSize,
                                          src_endianness=endianness,
                                          src_sign=sign,
                                          dst_unitSize=unitSize,
                                          dst_endianness=endianness,
                                          dst_sign=sign)

        self.network = network

        super(IPv4, self).__init__(self.__class__.__name__,
                                   value,
                                   32,
                                   unitSize=unitSize,
                                   endianness=endianness,
                                   sign=sign)
Пример #11
0
    def __crc32(self, msg):
        self._logger.debug("Computing crc32 of {0}, {1}".format(
            TypeConverter.convert(msg, Raw, HexaString), len(msg)))

        res = binascii.crc32(msg)

        return res
Пример #12
0
    def canParse(self,
                 data,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        """Computes if specified data can be parsed as a Timestamp with the predefined constraints.

        >>> from netzob.all import *
        >>> time = Timestamp()
        >>> time.canParse(TypeConverter.convert(1444494130, Integer, BitArray, src_unitSize=AbstractType.UNITSIZE_32))
        True
        >>> # A timestamp is nothing else than 32bits parsed as an unsigned long
        >>> time.canParse(TypeConverter.convert("test", ASCII, BitArray))
        True
        >>> time.canParse(TypeConverter.convert("te", ASCII, BitArray))
        False
        
        However, some constrains over the definition of the Timestamp can be set to restrain the accepted values

        >>> from netzob.all import *
        >>> time = Timestamp(epoch=Timestamp.EPOCH_WINDOWS, unity=Timestamp.UNITY_NANOSECOND, unitSize = AbstractType.UNITSIZE_64)
        >>> # the returned year is < 1900
        >>> time.canParse(TypeConverter.convert("test", ASCII, BitArray))
        False

        """

        if data is None:
            raise TypeError("data cannot be None")

        # Timestamp must be 8 bits modulo length
        if len(data) % 8 != 0:
            return False

        if len(data) < int(self.unitSize):
            return False

        try:

            value = TypeConverter.convert(
                data[:int(self.unitSize)],
                BitArray,
                Integer,
                dst_unitSize=AbstractType.UNITSIZE_32,
                dst_sign=AbstractType.SIGN_UNSIGNED)

            # convert the value in seconds
            value = value / self.unity

            # add the utc now with the epoch
            timestamp_datetime = self.epoch + timedelta(seconds=value)

            # convert obtained datetime to timestamp in seconds
            result_sec = int(timestamp_datetime.strftime('%s'))

            datetime.fromtimestamp(result_sec)
        except Exception:
            return False

        return True
Пример #13
0
    def __init__(self,
                 value=None,
                 epoch=EPOCH_UNIX,
                 unity=UNITY_SECOND,
                 unitSize=AbstractType.UNITSIZE_32,
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.SIGN_UNSIGNED):
        """Builds a Timestamp domain with optional constraints.

        :param value: specifies the value of the timestamp.
        :type value: an int, a long or a bitarray
        :param epoch: the initial date expressed in UTC from which timestamp is measured. Default value is the UNIX Epoch.
        :type datetime.datetime
        :param unity: specifies the unity of the timestamp (seconds, milliseconds, nanoseconds). Default value is SECOND.
        :type unity: int
        """
        if value is not None and not isinstance(value, bitarray):
            # converts the specified value in bitarray
            value = TypeConverter.convert(value,
                                          Integer,
                                          BitArray,
                                          src_unitSize=unitSize,
                                          src_endianness=endianness,
                                          src_sign=sign)

        self.epoch = epoch
        self.unity = unity

        super(Timestamp, self).__init__(self.__class__.__name__,
                                        value,
                                        32,
                                        unitSize=unitSize,
                                        endianness=endianness,
                                        sign=sign)
Пример #14
0
    def __repr__(self):
        r"""
        >>> from netzob.all import *
        >>> f = Field(Raw(b"\x01\x02\x03\x04"))
        >>> s = Symbol(fields=[f])
        >>> messages = [RawMessage(s.specialize()) for x in range(5)]
        >>> s.messages = messages
        >>> print(s)# doctest: +NORMALIZE_WHITESPACE
        Source | Destination | Field
        ------ | ----------- | ------------------
        None   | None        | '\x01\x02\x03\x04'
        None   | None        | '\x01\x02\x03\x04'
        None   | None        | '\x01\x02\x03\x04'
        None   | None        | '\x01\x02\x03\x04'
        None   | None        | '\x01\x02\x03\x04'
        ------ | ----------- | ------------------

        """
        if self.value is not None:
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            return str(
                TypeConverter.convert(self.value, BitArray, self.__class__))
        else:
            return str(self.value)
Пример #15
0
    def __init__(self,
                 value=None,
                 interval=None,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            interval = value
            value = TypeConverter.convert(value,
                                          Integer,
                                          BitArray,
                                          src_unitSize=unitSize,
                                          src_endianness=endianness,
                                          src_sign=sign,
                                          dst_unitSize=unitSize,
                                          dst_endianness=endianness,
                                          dst_sign=sign)
        else:
            value = None

        if interval is not None:
            nbBits = int(
                self._computeNbUnitSizeForInterval(interval, unitSize,
                                                   sign)) * int(unitSize)
        else:
            nbBits = int(unitSize)

        super(Integer, self).__init__(self.__class__.__name__,
                                      value,
                                      nbBits,
                                      unitSize=unitSize,
                                      endianness=endianness,
                                      sign=sign)
Пример #16
0
    def regenerate(self, variableSpecializerPath, moreCallBackAccepted=True):
        """This method participates in the specialization proces.

        It creates a VariableSpecializerResult in the provided path that
        contains a generated value that follows the definition of the Data
        """
        self._logger.debug("Regenerate value {0}".format(self))
        if variableSpecializerPath is None:
            raise Exception("VariableSpecializerPath cannot be None")

        try:
            newValue = self._computeExpectedValue(variableSpecializerPath)
            variableSpecializerPath.addResult(self, newValue)
        except Exception as e:
            self._logger.debug(
                "Cannot specialize since no value is available for the value dependencies, we create a callback function in case it can be computed later: {0}"
                .format(e))

            pendingValue = TypeConverter.convert("PENDING VALUE", ASCII,
                                                 BitArray)
            variableSpecializerPath.addResult(self, pendingValue)
            if moreCallBackAccepted:
                variableSpecializerPath.registerFieldCallBack(
                    self.fieldDependencies, self, parsingCB=False)
            else:
                raise e

        return [variableSpecializerPath]
Пример #17
0
    def __repr__(self):
        """
        >>> from netzob.all import *
        >>> f = Field(Raw("\\x01\\x02\\x03\\x04"))
        >>> s = Symbol(fields=[f])
        >>> messages = [RawMessage(s.specialize()) for x in range(5)]
        >>> s.messages = messages
        >>> print(s)
        Field             
        ------------------
        '\\x01\\x02\\x03\\x04'
        '\\x01\\x02\\x03\\x04'
        '\\x01\\x02\\x03\\x04'
        '\\x01\\x02\\x03\\x04'
        '\\x01\\x02\\x03\\x04'
        ------------------

        """
        if self.value is not None:
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            return str(
                TypeConverter.convert(self.value, BitArray, self.__class__))
        else:
            return str(self.value)
Пример #18
0
    def encodeChild(self, variable, readingToken):
        result = []

        if not readingToken.isValueForVariableAvailable(variable):
            return result

        if variable.varType == "Data" or variable.varType == "Size" or variable.varType == "InternetChecksum":
            val = readingToken.getValueForVariable(variable)
            encodedVal = TypeConverter.convert(val, BitArray,
                                               variable.dataType.__class__)
            result.append(str(encodedVal))
        elif variable.varType == "Agg" or variable.varType == "Alt":
            for child in variable.children:
                result.extend(self.encodeChild(child, readingToken))
        elif variable.varType == "Eol":
            # nothing to encode when child is EOL
            pass
        else:
            raise Exception(
                "Unknown type of variable: {0}".format(variable.varType))

        if len(result) == 0:
            return ''
        else:
            return ''.join(result)
Пример #19
0
    def __init__(self,
                 value=None,
                 nbChars=(None, None),
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            value = TypeConverter.convert(value,
                                          ASCII,
                                          BitArray,
                                          src_unitSize=unitSize,
                                          src_endianness=endianness,
                                          src_sign=sign,
                                          dst_unitSize=unitSize,
                                          dst_endianness=endianness,
                                          dst_sign=sign)
        else:
            value = None

        self.nbChars = nbChars
        nbBits = self._convertNbCharsInNbBits(self.nbChars)

        super(ASCII, self).__init__(self.__class__.__name__,
                                    value,
                                    nbBits,
                                    unitSize=unitSize,
                                    endianness=endianness,
                                    sign=sign)
Пример #20
0
    def __init__(self,
                 value=None,
                 nbChars=(None, None),
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            value = TypeConverter.convert(
                value,
                ASCII,
                BitArray,
                src_unitSize=unitSize,
                src_endianness=endianness,
                src_sign=sign,
                dst_unitSize=unitSize,
                dst_endianness=endianness,
                dst_sign=sign)
        else:
            value = None

        self.nbChars = nbChars
        nbBits = self._convertNbCharsInNbBits(self.nbChars)

        super(ASCII, self).__init__(
            self.__class__.__name__,
            value,
            nbBits,
            unitSize=unitSize,
            endianness=endianness,
            sign=sign)
Пример #21
0
    def generate(self, generationStrategy=None):
        """Generates a random ASCII that respects the requested size.

        >>> from netzob.all import *
        >>> a = ASCII(nbChars=10)
        >>> gen = a.generate()
        >>> len(gen)/8
        10.0

        >>> b = ASCII("netzob")
        >>> gen = b.generate()
        >>> print(len(gen)>0)
        True

        """
        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.BitArray import BitArray

        minSize, maxSize = self.nbChars
        if maxSize is None:
            maxSize = AbstractType.MAXIMUM_GENERATED_DATA_SIZE
        if minSize is None:
            minSize = 0

        generatedSize = random.randint(minSize, maxSize)
        randomContent = ''.join([
            random.choice(string.ascii_letters + string.digits)
            for i in range(generatedSize)
        ])
        return TypeConverter.convert(randomContent, ASCII, BitArray)
Пример #22
0
    def generate(self, generationStrategy=None):
        """Generates a random ASCII that respects the requested size.

        >>> from netzob.all import *
        >>> a = ASCII(nbChars=10)
        >>> gen = a.generate()
        >>> len(gen)/8
        10.0

        >>> b = ASCII("netzob")
        >>> gen = b.generate()
        >>> print(len(gen)>0)
        True

        """
        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.BitArray import BitArray

        minSize, maxSize = self.nbChars
        if maxSize is None:
            maxSize = AbstractType.MAXIMUM_GENERATED_DATA_SIZE
        if minSize is None:
            minSize = 0

        generatedSize = random.randint(minSize, maxSize)
        randomContent = ''.join([
            random.choice(string.ascii_letters + string.digits)
            for i in range(generatedSize)
        ])
        return TypeConverter.convert(randomContent, ASCII, BitArray)
Пример #23
0
    def __init__(self, value=None, size=(None, None)):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            value = TypeConverter.convert(value, HexaString, BitArray)

        super(HexaString, self).__init__(self.__class__.__name__, value, size)
Пример #24
0
    def _writeSymbol(self, symbol, presets=None):
        """Write the specified symbol on the communication channel after
        specializing it into a contextualized message.

        :param symbol: the symbol to write on the channel
        :type symbol: :class:`netzob.Model.Vocabulary.Symbol.Symbol`

        :param presets: specifies how to parameterize the emitted symbol
        :type presets: dict

        :raise TypeError if parameter is not valid and Exception if an exception occurs.

        """

        self._logger.debug("Specializing symbol '{0}' (id={1}).".format(
            symbol.name, symbol.id))

        self.specializer.presets = presets
        dataBin = self.specializer.specializeSymbol(symbol).generatedContent
        self.specializer.presets = None

        self.memory = self.specializer.memory
        self.parser.memory = self.memory
        data = TypeConverter.convert(dataBin, BitArray, Raw)

        len_data = self.channel.write(data)
        self._logger.debug("Writing {} octets to commnunication channel done..".format(len_data))
        return len_data
Пример #25
0
    def regenerate(self, variableSpecializerPath, moreCallBackAccepted=True):
        """This method participates in the specialization proces.

        It creates a VariableSpecializerResult in the provided path that
        contains a generated value that follows the definition of the Data
        """
        self._logger.debug("Regenerate value {0}".format(self))
        if variableSpecializerPath is None:
            raise Exception("VariableSpecializerPath cannot be None")

        try:
            newValue = self._computeExpectedValue(variableSpecializerPath)

            variableSpecializerPath.addResult(self, newValue)
        except Exception as e:
            self._logger.debug(
                "Cannot specialize since no value is available for the value dependencies, we create a callback function in case it can be computed later: {0}".
                format(e))

            pendingValue = TypeConverter.convert("PENDING VALUE", ASCII,
                                                 BitArray)
            variableSpecializerPath.addResult(self, pendingValue)
            if moreCallBackAccepted:
                variableSpecializerPath.registerFieldCallBack(
                    self.fieldDependencies, self, parsingCB=False)
            else:
                raise e

        return [variableSpecializerPath]
Пример #26
0
 def encode(self, data):
     data_raw = TypeConverter.convert(data, BitArray, Raw)
     result = None
     if self.encode_data:
         result = base64.b64encode(data_raw)
     else:
         result = base64.b64decode(data_raw)
     return result
Пример #27
0
 def encode(self, data):
     self._logger.debug(data)
     return TypeConverter.convert(data,
                                  BitArray,
                                  self.type,
                                  dst_unitSize=self.unitSize,
                                  dst_endianness=self.endianness,
                                  dst_sign=self.sign)
Пример #28
0
 def __repr__(self):
     if self.value != None:
         from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
         from netzob.Model.Vocabulary.Types.BitArray import BitArray
         return str(
             TypeConverter.convert(self.value, BitArray, self.__class__))
     else:
         return str(self.value)
Пример #29
0
 def __repr__(self):
     if self.value != None:
         from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
         from netzob.Model.Vocabulary.Types.BitArray import BitArray
         return str(
             TypeConverter.convert(self.value, BitArray, self.__class__))
     else:
         return str(self.value)
Пример #30
0
    def specialize(self):
        """Specialize the current field to build a raw data that
        follows the fields definitions attached to current element.

        This method allows to generate some content following the field definition:

        >>> from netzob.all import *
        >>> f = Field("hello")
        >>> print('\\n'.join([str(f.specialize()) for x in range(3)]))
        b'hello'
        b'hello'
        b'hello'

        This method also applies on multiple fields using a Symbol

        >>> fHello = Field("hello ")
        >>> fName = Field("zoby")
        >>> s = Symbol([fHello, fName])
        >>> print('\\n'.join([str(s.specialize()) for x in range(3)]))
        b'hello zoby'
        b'hello zoby'
        b'hello zoby'

        :return: a generated content represented with an hexastring
        :rtype: :class:`str``
        :raises: :class:`netzob.Model.Vocabulary.AbstractField.GenerationException` if an error occurs while generating a message
        """
        self._logger.debug("Specializes field {0}".format(self.name))
        if self.__domain is None:
            raise InvalidDomainException("The domain is not defined.")

        from netzob.Model.Vocabulary.Domain.Specializer.FieldSpecializer import FieldSpecializer
        fs = FieldSpecializer(self)
        if self.domain.svas == SVAS.PERSISTENT:
            if isinstance(self.specializingPaths, list):
                self.specializingPaths = fs.specialize(
                    specializingPath=self.specializingPaths[0])
            else:
                self.specializingPaths = fs.specialize(
                    specializingPath=self.specializingPaths)
            specializingPaths = self.specializingPaths
        else:
            specializingPaths = fs.specialize()
        if len(specializingPaths) < 1:
            raise Exception("Cannot specialize this field")

        specializingPath = specializingPaths[0]

        self._logger.debug(
            "field specializing done: {0}".format(specializingPath))
        if specializingPath is None:
            raise Exception(
                "The specialization of the field {0} returned no result.".
                format(self.name))

        return TypeConverter.convert(
            specializingPath.getDataAssignedToVariable(self.domain), BitArray,
            Raw)
Пример #31
0
 def _generateDataValues(self, cellsData):
     result = []
     for data in cellsData:
         if len(data) > 0:
             result.append(TypeConverter.convert(
                 data[:8], Raw, Integer))  # We take only the first 8 octets
         else:
             result.append(0)
     return result
Пример #32
0
 def encode(self, data):
     self._logger.debug(data)
     return TypeConverter.convert(
         data,
         BitArray,
         self.type,
         dst_unitSize=self.unitSize,
         dst_endianness=self.endianness,
         dst_sign=self.sign)
Пример #33
0
 def _generateDataValues(self, cellsData):
     result = []
     for data in cellsData:
         if len(data) > 0:
             result.append(TypeConverter.convert(
                 data[:8], Raw, Integer))  # We take only the first 8 octets
         else:
             result.append(0)
     return result
Пример #34
0
 def __str__(self):
     from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
     from netzob.Model.Vocabulary.Types.BitArray import BitArray
     if self.value is not None:
         return "{0}={1} ({2})".format(
             self.typeName,
             TypeConverter.convert(self.value, BitArray,
                                   self.__class__), self.size)
     else:
         return "{0}={1} ({2})".format(self.typeName, self.value, self.size)
Пример #35
0
 def __str__(self):
     from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
     from netzob.Model.Vocabulary.Types.BitArray import BitArray
     if self.value is not None:
         return "{0}={1} ({2})".format(
             self.typeName,
             TypeConverter.convert(self.value, BitArray, self.__class__),
             self.size)
     else:
         return "{0}={1} ({2})".format(self.typeName, self.value, self.size)
Пример #36
0
    def encode(self, data):
        data_raw = TypeConverter.convert(data, BitArray, Raw)

        result = None
        if self.compress_data:
            result = zlib.compress(data_raw, self.compression_level)
        else:
            result = zlib.decompress(data_raw)

        return result
Пример #37
0
    def encode(self, data):
        data_raw = TypeConverter.convert(data, BitArray, Raw)

        result = None
        if self.compress_data:
            result = zlib.compress(data_raw, self.compression_level)
        else:
            result = zlib.decompress(data_raw)
            
        return result
Пример #38
0
    def convertValue(self,
                     typeClass,
                     dst_unitSize=None,
                     dst_endianness=None,
                     dst_sign=None):
        """Convert the current data in the netzob type
        specified in parameter.

        :parameter typeClass: the netzob class to which the current data must be converted
        :type typeClass: type
        :keyword dst_unitSize: the unitsize of the destination value. Values must be one of AbstractType.UNITSIZE_*. if None, the value is the default one.
        :type dst_unitSize: str
        :keyword dst_endianness: the endianness of the destination value. Values must be AbstractType.ENDIAN_BIG or AbstractType.ENDIAN_LITTLE. if None, the value is the default one.
        :type dst_endianness: str
        :keyword dst_sign: the sign of the destination. Values must be AbstractType.SIGN_SIGNED or AbstractType.SIGN_UNSIGNED. if None, the value is the default one.
        :type dst_sign: str
        :return: the converted current value in the specified netzob type
        :rtype: :class:`netzob.Model.AbstractType.AbstractType`
        """
        if typeClass is None:
            raise TypeError("TypeClass cannot be None")
        if typeClass not in AbstractType.supportedTypes():
            raise TypeError("Requested typeClass ({0}) is not supported.".
                            format(typeClass))

        if dst_unitSize is None:
            dst_unitSize = AbstractType.defaultUnitSize()
        if dst_endianness is None:
            dst_endianness = AbstractType.defaultEndianness()
        if dst_sign is None:
            dst_sign = AbstractType.defaultSign()

        if dst_unitSize not in AbstractType.supportedUnitSizes():
            raise TypeError("Dst_unitsize is not supported.")
        if dst_endianness not in AbstractType.supportedEndianness():
            raise TypeError("Dst_endianness is not supported.")
        if dst_sign not in AbstractType.supportedSign():
            raise TypeError("Sign is not supported.")

        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.BitArray import BitArray
        return typeClass(
            TypeConverter.convert(
                self.value,
                BitArray,
                typeClass,
                src_unitSize=self.unitSize,
                src_endianness=self.endianness,
                src_sign=self.sign,
                dst_unitSize=dst_unitSize,
                dst_endianness=dst_endianness,
                dst_sign=dst_sign),
            unitSize=dst_unitSize,
            endianness=dst_endianness,
            sign=dst_sign)
Пример #39
0
    def _computeExpectedValue(self, parsingPath):
        self._logger.debug("compute expected value for CRC32 field")

        # first checks the pointed fields all have a value
        hasValue = True
        for field in self.fieldDependencies:
            if field.domain != self and not parsingPath.isDataAvailableForVariable(
                    field.domain):
                self._logger.debug("Field : {0} has no value".format(field.id))
                hasValue = False

        if not hasValue:
            raise Exception(
                "Expected value cannot be computed, some dependencies are missing for domain {0}"
                .format(self))
        else:
            fieldValues = []
            for field in self.fieldDependencies:
                # Retrieve field value
                if field.domain is self:
                    fieldSize = random.randint(field.domain.dataType.size[0],
                                               field.domain.dataType.size[1])
                    fieldValue = b"\x00" * int(fieldSize / 8)
                else:
                    fieldValue = TypeConverter.convert(
                        parsingPath.getDataAssignedToVariable(field.domain),
                        BitArray, Raw)
                if fieldValue is None:
                    break
                else:
                    fieldValues.append(fieldValue)

            fieldValues = b''.join(fieldValues)
            # compute the crc of this value
            chsum = self.__crc32(fieldValues)
            b = TypeConverter.convert(chsum,
                                      Integer,
                                      BitArray,
                                      src_unitSize=AbstractType.UNITSIZE_32,
                                      src_sign=AbstractType.SIGN_UNSIGNED,
                                      src_endianness=self.endianness)
            return b
Пример #40
0
    def convertValue(self,
                     typeClass,
                     dst_unitSize=None,
                     dst_endianness=None,
                     dst_sign=None):
        """Convert the current data in the netzob type
        specified in parameter.

        :parameter typeClass: the netzob class to which the current data must be converted
        :type typeClass: type
        :keyword dst_unitSize: the unitsize of the destination value. Values must be one of AbstractType.UNITSIZE_*. if None, the value is the default one.
        :type dst_unitSize: str
        :keyword dst_endianness: the endianness of the destination value. Values must be AbstractType.ENDIAN_BIG or AbstractType.ENDIAN_LITTLE. if None, the value is the default one.
        :type dst_endianness: str
        :keyword dst_sign: the sign of the destination. Values must be AbstractType.SIGN_SIGNED or AbstractType.SIGN_UNSIGNED. if None, the value is the default one.
        :type dst_sign: str
        :return: the converted current value in the specified netzob type
        :rtype: :class:`netzob.Model.AbstractType.AbstractType`
        """
        if typeClass is None:
            raise TypeError("TypeClass cannot be None")
        if typeClass not in AbstractType.supportedTypes():
            raise TypeError(
                "Requested typeClass ({0}) is not supported.".format(
                    typeClass))

        if dst_unitSize is None:
            dst_unitSize = AbstractType.defaultUnitSize()
        if dst_endianness is None:
            dst_endianness = AbstractType.defaultEndianness()
        if dst_sign is None:
            dst_sign = AbstractType.defaultSign()

        if dst_unitSize not in AbstractType.supportedUnitSizes():
            raise TypeError("Dst_unitsize is not supported.")
        if dst_endianness not in AbstractType.supportedEndianness():
            raise TypeError("Dst_endianness is not supported.")
        if dst_sign not in AbstractType.supportedSign():
            raise TypeError("Sign is not supported.")

        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.BitArray import BitArray
        return typeClass(TypeConverter.convert(self.value,
                                               BitArray,
                                               typeClass,
                                               src_unitSize=self.unitSize,
                                               src_endianness=self.endianness,
                                               src_sign=self.sign,
                                               dst_unitSize=dst_unitSize,
                                               dst_endianness=dst_endianness,
                                               dst_sign=dst_sign),
                         unitSize=dst_unitSize,
                         endianness=dst_endianness,
                         sign=dst_sign)
Пример #41
0
 def __str__(self):
     if self.value is not None:
         from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
         from netzob.Model.Vocabulary.Types.BitArray import BitArray
         from netzob.Model.Vocabulary.Types.HexaString import HexaString
         return "{0}={1} ({2})".format(
             self.typeName,
             repr(TypeConverter.convert(self.value, BitArray, Raw)),
             self.size)
     else:
         return "{0}={1} ({2})".format(self.typeName, self.value, self.size)
Пример #42
0
    def parseRaw(self, dataToParse, fields):
        """This method parses the specified raw against the specification of the provided symbol."""
        if dataToParse is None or len(dataToParse) <= 0:
            raise Exception("Specified data to parse is empty (or None)")
        if fields is None:
            raise Exception("Specified fields is None")
        if len(fields) == 0:
            raise Exception("No field specified")

        bitArrayToParse = TypeConverter.convert(dataToParse, Raw, BitArray)

        return self.parseBitarray(bitArrayToParse, fields)
Пример #43
0
    def specialize(self, memory=None, generationStrategy=None, presets=None):
        """Specialize and generate an hexastring which content
        follows the fields definitions attached to the field of the symbol.

        >>> from netzob.all import *
        >>> f1 = Field(domain=ASCII(nbChars=5))
        >>> f0 = Field(domain=Size(f1))
        >>> s = Symbol(fields=[f0, f1])
        >>> result = s.specialize()
        >>> print(result[0])
        5
        >>> print(len(result))
        6

        You can also preset the value of some variables included in the symbol definition.

        >>> from netzob.all import *
        >>> f1 = Field(domain=ASCII("hello "))
        >>> f2 = Field(domain=ASCII(nbChars=(1,10)))
        >>> s = Symbol(fields = [f1, f2])
        >>> presetValues = dict()
        >>> presetValues[f2] = TypeConverter.convert("antoine", ASCII, BitArray)
        >>> print(s.specialize(presets = presetValues))
        b'hello antoine'

        A preseted valued bypasses all the constraints checks on your field definition.
        For example, in the following example it can be use to bypass a size field definition.

        >>> from netzob.all import *
        >>> f1 = Field()
        >>> f2 = Field(domain=Raw(nbBytes=(10,15)))
        >>> f1.domain = Size(f2)
        >>> s = Symbol(fields=[f1, f2])
        >>> presetValues = {f1: TypeConverter.convert("\xff", Raw, BitArray)}        
        >>> print(s.specialize(presets = presetValues)[0])
        195

        :keyword generationStrategy: if set, the strategy will be used to generate the fields definitions
        :type generaionrStrategy: :class:``

        :return: a generated content represented as a Raw
        :rtype: :class:`str``
        :raises: :class:`netzob.Model.Vocabulary.AbstractField.GenerationException` if an error occurs while generating a message
        """

        from netzob.Model.Vocabulary.Domain.Specializer.MessageSpecializer import MessageSpecializer
        msg = MessageSpecializer(memory=memory, presets=presets)
        spePath = msg.specializeSymbol(self)

        if spePath is not None:
            return TypeConverter.convert(spePath.generatedContent, BitArray,
                                         Raw)
Пример #44
0
    def specialize(self, memory=None, generationStrategy=None, presets=None):
        """Specialize and generate an hexastring which content
        follows the fields definitions attached to the field of the symbol.

        >>> from netzob.all import *
        >>> f1 = Field(domain=ASCII(nbChars=5))
        >>> f0 = Field(domain=Size(f1))
        >>> s = Symbol(fields=[f0, f1])
        >>> result = s.specialize()
        >>> print(result[0])
        5
        >>> print(len(result))
        6

        You can also preset the value of some variables included in the symbol definition.

        >>> from netzob.all import *
        >>> f1 = Field(domain=ASCII("hello "))
        >>> f2 = Field(domain=ASCII(nbChars=(1,10)))
        >>> s = Symbol(fields = [f1, f2])
        >>> presetValues = dict()
        >>> presetValues[f2] = TypeConverter.convert("antoine", ASCII, BitArray)
        >>> print(s.specialize(presets = presetValues))
        b'hello antoine'

        A preseted valued bypasses all the constraints checks on your field definition.
        For example, in the following example it can be use to bypass a size field definition.

        >>> from netzob.all import *
        >>> f1 = Field()
        >>> f2 = Field(domain=Raw(nbBytes=(10,15)))
        >>> f1.domain = Size(f2)
        >>> s = Symbol(fields=[f1, f2])
        >>> presetValues = {f1: TypeConverter.convert("\xff", Raw, BitArray)}        
        >>> print(s.specialize(presets = presetValues)[0])
        195

        :keyword generationStrategy: if set, the strategy will be used to generate the fields definitions
        :type generaionrStrategy: :class:``

        :return: a generated content represented as a Raw
        :rtype: :class:`str``
        :raises: :class:`netzob.Model.Vocabulary.AbstractField.GenerationException` if an error occurs while generating a message
        """

        from netzob.Model.Vocabulary.Domain.Specializer.MessageSpecializer import MessageSpecializer
        msg = MessageSpecializer(memory=memory, presets=presets)
        spePath = msg.specializeSymbol(self)

        if spePath is not None:
            return TypeConverter.convert(spePath.generatedContent, BitArray,
                                         Raw)
Пример #45
0
    def __init__(self,
                 value=None,
                 interval=None,
                 unitSize=None,
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):

        if unitSize is None:
            if interval is None:  # value handling
                if value is None:
                    unitSize = AbstractType.defaultUnitSize()
                else:
                    unitSize = Integer.checkUnitSizeForValue(value, sign)
            else:  # interval handling
                if isinstance(interval, int):
                    unitSize = Integer.checkUnitSizeForValue(interval, sign)
                elif len(interval) == 2:
                    unitSizeA = Integer.checkUnitSizeForValue(
                        interval[0], sign)
                    unitSizeB = Integer.checkUnitSizeForValue(
                        interval[1], sign)
                    unitSize = max(unitSizeA, unitSizeB)
                else:  # shouldn't happen, since _checkUnitSizeForValue raises an exception before
                    unitSize = AbstractType.defaultUnitSize()

        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray

            value = TypeConverter.convert(value,
                                          Integer,
                                          BitArray,
                                          src_unitSize=unitSize,
                                          src_endianness=endianness,
                                          src_sign=sign,
                                          dst_unitSize=unitSize,
                                          dst_endianness=endianness,
                                          dst_sign=sign)

        if interval is not None:
            nbBits = int(
                self._computeNbUnitSizeForInterval(interval, unitSize,
                                                   sign)) * int(unitSize)
        else:
            nbBits = int(unitSize)

        super(Integer, self).__init__(self.__class__.__name__,
                                      value,
                                      nbBits,
                                      unitSize=unitSize,
                                      endianness=endianness,
                                      sign=sign)
Пример #46
0
 def _generateCRC32(self, symbol):
     header = []
     lines = []
     header.append(self.ATTR_CRC32)
     messages = symbol.getMessages()
     for message in messages:
         line = []
         data = message.getStringData()
         rawContent = TypeConverter.netzobRawToPythonRaw(data)
         valCrc32 = zlib.crc32(rawContent) & 0xFFFFFFFF
         line.append(str(valCrc32))
         lines.append(b",".join(line))
     return (header, lines)
Пример #47
0
    def getMessageDetails(message):
        """Decode a raw network message and print the content of each
        encapsulated layer.

        :param filePathList: the messages to cluster.
        :type filePathList: a list of :class:`str`
        :param bpfFilter: a string representing a BPF filter.
        :type bpfFilter: :class:`str`
        :param importLayer: an integer representing the protocol layer to start importing.
        :type importLayer: :class:`int`
        """

        decoder = Decoders.EthDecoder()
        return decoder.decode(
            TypeConverter.convert(message.data, HexaString, Raw))
Пример #48
0
    def _generateSizeFieldFromBeginingOfField(self, symbol):
        header = []
        lines = []
        cells = dict()
        fields = symbol.fields
        for field in fields:
            if not field.isStatic():
                header.append((self.ATTR_VALUE, field))
                cells[field] = field.getCells(encoded=False, styled=False)

        for i_msg in range(0, len(symbol.getMessages())):
            line = []
            for field in list(cells.keys()):
                entry = cells[field][i_msg]
                for k in range(2, 3, 2):
                    if len(entry) > k:
                        line.append(
                            TypeConverter.netzobRawToInteger(entry[:k]))
                    else:
                        line.append(TypeConverter.netzobRawToInteger(entry))

            lines.append(b",".join(line))

        return (header, lines)
Пример #49
0
    def __checksum(self, msg):
        self._logger.debug("Computing checksum of {0}, {1}".format(
            TypeConverter.convert(msg, Raw, HexaString), len(msg)))

        def carry_around_add(a, b):
            c = a + b
            return (c & 0xffff) + (c >> 16)

        s = 0
        for i in range(0, len(msg), 2):
            if i + 1 >= len(msg):
                w = msg[i] & 0xFF
            else:
                w = msg[i] + (msg[i + 1] << 8)
            s = carry_around_add(s, w)
        res = ~s & 0xffff
        return res
Пример #50
0
    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, int(len(entryVal) / 2))))
            else:
                newField = Field(
                    Raw(TypeConverter.convert(entryVal, HexaString, Raw)))
            step1Fields.append(newField)

        for f in step1Fields:
            f.encodingFunctions = list(field.encodingFunctions.values())

        field.fields = step1Fields
Пример #51
0
    def parseFlow(self, message, symbols):
        """This method parses the specified message against the specification of one or multiple consecutive
        symbol. It returns a list of tuples, one tuple for each consecutive symbol that participate in the flow.
        A tupple is made of the symbol's and its alignment of the message part it applies on.
        If an error occurs, an Exception is raised."""

        if message is None:
            raise Exception("Specified cannot be None")
        if symbols is None or len(symbols) == 0:
            raise Exception(
                "Symbols cannot be None and must be a list of at least one symbol"
            )

        data_to_parse_raw = message.data
        data_to_parse_bitarray = TypeConverter.convert(data_to_parse_raw, Raw,
                                                       BitArray)
        for result in self._parseFlow_internal(data_to_parse_bitarray, symbols,
                                               self.memory):
            return result

        raise InvalidParsingPathException(
            "No parsing path returned while parsing {}".format(
                repr(data_to_parse_raw)))
Пример #52
0
    def __init__(self,
                 value=None,
                 interval=None,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            interval = value
            value = TypeConverter.convert(
                value,
                Integer,
                BitArray,
                src_unitSize=unitSize,
                src_endianness=endianness,
                src_sign=sign,
                dst_unitSize=unitSize,
                dst_endianness=endianness,
                dst_sign=sign)
        else:
            value = None

        if interval is not None:
            nbBits = int(
                self._computeNbUnitSizeForInterval(interval, unitSize,
                                                   sign)) * int(unitSize)
        else:
            nbBits = int(unitSize)

        super(Integer, self).__init__(
            self.__class__.__name__,
            value,
            nbBits,
            unitSize=unitSize,
            endianness=endianness,
            sign=sign)
Пример #53
0
    def __init__(self,
                 value=None,
                 network=None,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        """Builds an IPv4 domain with optional constraints.

        :parameter value: specify a constraints over the expected value.
        :type value: an str, an IPAddress or an int which can be parsed as an IPv4 (ex. "192.168.0.10")
        :parameter network: if no value is specified (None), a constraints over the network the parsed IP belongs can be specified with this parameter (ex. "192.168.0.0/24")
        :type network: an str or an IPAddress which can be parsed as a network IPv4
        """

        if value is not None and not isinstance(value, bitarray):
            from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
            from netzob.Model.Vocabulary.Types.BitArray import BitArray
            value = TypeConverter.convert(
                value,
                IPv4,
                BitArray,
                src_unitSize=unitSize,
                src_endianness=endianness,
                src_sign=sign,
                dst_unitSize=unitSize,
                dst_endianness=endianness,
                dst_sign=sign)

        self.network = network

        super(IPv4, self).__init__(
            self.__class__.__name__,
            value,
            32,
            unitSize=unitSize,
            endianness=endianness,
            sign=sign)
Пример #54
0
    def _computeExpectedValue(self, parsingPath):
        self._logger.debug("compute expected value for Size field")

        # first checks the pointed fields all have a value
        hasNeededData = True
        size = 0
        remainingFields = []

        for field in self.fieldDependencies:

            if field.domain == self:
                remainingFields.append(field)
            else:

                # Retrieve the size of the targeted field, if it has a fixed size
                if hasattr(field.domain, "dataType"):
                    minSize, maxSize = field.domain.dataType.size
                    if maxSize is not None and minSize == maxSize:
                        size += minSize
                        continue

                # Else, retrieve its value if it exists
                if parsingPath.isDataAvailableForVariable(field.domain):
                    remainingFields.append(field)
                else:
                    self._logger.debug("The following field domain has no value: '{0}'".format(field.domain))
                    hasNeededData = False
                    break

        if not hasNeededData:
            raise Exception("Expected value cannot be computed, some dependencies are missing for domain {0}".format(self))
        else:
            for field in remainingFields:

                # Retrieve field value
                if field.domain is self:
                    fieldValue = self.dataType.generate()
                else:
                    fieldValue = parsingPath.getDataAssignedToVariable(
                        field.domain)
                if fieldValue is None:
                    break

                # Retrieve length of field value
                size += len(fieldValue)

        size = int(size * self.factor + self.offset)
        size_raw = TypeConverter.convert(size,
                                         Integer,
                                         Raw,
                                         src_unitSize=self.dataType.unitSize,
                                         dst_unitSize=self.dataType.unitSize,
                                         src_sign=self.dataType.sign,
                                         dst_sign=self.dataType.sign)
        b = TypeConverter.convert(size_raw, Raw, BitArray)

        # add heading '0'
        while len(b) < self.dataType.size[0]:
            b.insert(0, False)

        # in some cases (when unitSize and size are not equal), it may require to delete some '0' in front
        while len(b) > self.dataType.size[0]:
            b.remove(0)

        self._logger.debug("computed value for Size field: '{}'".format(b))
        return b
Пример #55
0
    def mutate(self, prefixDescription=None):
        """Generate various mutations of the current ASCII value.

        Mutations are first applied on the ASCII value than, each obtained mutations generates
        new bitarray mutations.
        ASCII mutations are:

        * Original Version
        * Original Version in Upper case
        * Original Version in Lower case

        >>> from netzob.all import *
        >>> t = ASCII("helloworld")
        >>> values = t.mutate()
        >>> print(values['ascii(upper)-bits(littleEndian)'])
        bitarray('00010010101000100011001000110010111100101110101011110010010010100011001000100010')
        >>> print(values['ascii(inversed)-bits(bigEndian)'])
        bitarray('01100100011011000111001001101111011101110110111101101100011011000110010101101000')


        :keyword prefixDescription: prefix to attach to the description of the generated mutation.
        :type prefixDescription: :class:`str`
        :return: a dict of computed mutations having the same types than the initial one.
        :rtype: :class:`dict`<str>=:class:`netzob.Model.Vocabulary.Types.AbstractType.AbstractType`
        """
        if prefixDescription is None:
            prefixDescription = ""
        else:
            prefixDescription += "-"

        from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
        from netzob.Model.Vocabulary.Types.BitArray import BitArray

        if self.value is None:
            val = self.generate()
        else:
            val = self.value

        strValue = TypeConverter.convert(val, BitArray, ASCII)

        mutations = collections.OrderedDict()

        mutations["{0}ascii".format(prefixDescription)] = strValue
        mutations["{0}ascii(inversed)".format(
            prefixDescription)] = strValue[::-1]
        if strValue != strValue.upper():
            mutations["{0}ascii(upper)".format(
                prefixDescription)] = strValue.upper()
            mutations["{0}ascii(inversed-upper)".format(
                prefixDescription)] = strValue[::-1].upper()
        if strValue != strValue.lower():
            mutations["{0}ascii(lower)".format(
                prefixDescription)] = strValue.lower()
            mutations["{0}ascii(inversed-lower)".format(
                prefixDescription)] = strValue[::-1].lower()

        results = collections.OrderedDict()
        for mutationName, mutationValue in list(mutations.items()):
            ba = BitArray(
                TypeConverter.convert(mutationValue, ASCII, BitArray))
            results.update(ba.mutate(mutationName))

        return results
Пример #56
0
    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.Model.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(b'')
            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([b''.join(staticSequences)])
                        staticSequences = []
                    result.append(values)
            if len(staticSequences) > 0:
                result.append([b''.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 = zip(*dynamicSequences)
                        tmp_result = []
                        for d in dynValues:
                            tmp_result.append(b''.join(
                                [x if x is not None else b'' for x in d]))
                        result.append(tmp_result)
                        dynamicSequences = []
                    result.append(values)
            if len(dynamicSequences) > 0:
                dynValues = zip(*dynamicSequences)
                tmp_result = []
                for d in dynValues:
                    tmp_result.append(
                        b''.join([x if x is not None else b'' 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 = list(field.encodingFunctions.values())

        field.fields = newFields
Пример #57
0
    def canParse(self,
                 data,
                 unitSize=AbstractType.defaultUnitSize(),
                 endianness=AbstractType.defaultEndianness(),
                 sign=AbstractType.defaultSign()):
        """Computes if specified data can be parsed as an IPv4 with the predefined constraints.

        >>> from netzob.all import *
        >>> ip = IPv4()
        >>> ip.canParse("192.168.0.10")
        True
        >>> ip.canParse("198.128.0.100")
        True
        >>> ip.canParse("256.0.0.1")
        False
        >>> ip.canParse("127.0.0.1")
        True
        >>> ip.canParse("127.0.0.-1")
        False
        >>> ip.canParse("::")
        False
        >>> ip.canParse("0.0.0.0")
        False


        And with some constraints over the expected IPv4:


        >>> ip = IPv4("192.168.0.10")
        >>> ip.canParse("192.168.0.10")
        True
        >>> ip.canParse("192.168.1.10")
        False
        >>> ip.canParse(3232235530)
        True
        >>> ip = IPv4("167.20.14.20")
        >>> ip.canParse(3232235530)
        False
        >>> ip.canParse(3232235530)
        False


        or with contraints over the expected network the ipv4 belongs to:


        >>> ip = IPv4(network="192.168.0.0/24")
        >>> ip.canParse("192.168.0.10")
        True
        >>> ip.canParse("192.168.1.10")
        False

        :param data: the data to check
        :type data: python raw
        :return: True if data can be parsed as a Raw which is always the case (if len(data)>0)
        :rtype: bool
        :raise: TypeError if the data is None
        """

        if data is None:
            raise TypeError("data cannot be None")

        try:
            ip = IPv4.encode(
                data, unitSize=unitSize, endianness=endianness, sign=sign)
            if ip is None or ip.version != 4 or ip.is_netmask():
                return False
        except:
            return False
        try:
            if self.value is not None:
                from netzob.Model.Vocabulary.Types.TypeConverter import TypeConverter
                from netzob.Model.Vocabulary.Types.BitArray import BitArray
                return self.value == TypeConverter.convert(
                    data,
                    IPv4,
                    BitArray,
                    src_unitSize=unitSize,
                    src_endianness=endianness,
                    src_sign=sign,
                    dst_unitSize=self.unitSize,
                    dst_endianness=self.endianness,
                    dst_sign=self.sign)
            elif self.network is not None:
                return ip in self.network
        except:
            return False

        return True
Пример #58
0
    def specializeSymbol(self, symbol):
        """This method generates a message based on the provided symbol definition."""
        if symbol is None:
            raise Exception("Specified symbol is None")

        self._logger.debug("Specifies symbol '{0}'.".format(symbol.name))

        self._update_presets(symbol)

        # this variable host all the specialization path
        specializingPaths = [SpecializingPath(memory=self.memory)]

        for field in symbol.fields:
            self._logger.debug("Specializing field {0}".format(field.name))

            fieldDomain = field.domain
            if fieldDomain is None:
                raise Exception(
                    "Cannot specialize field '{0}' since it defines no domain".
                    format(fieldDomain))

            fs = FieldSpecializer(field, presets=self.presets)

            newSpecializingPaths = []
            for specializingPath in specializingPaths:
                newSpecializingPaths.extend(fs.specialize(specializingPath))

            specializingPaths = newSpecializingPaths

        if len(specializingPaths) > 1:
            self._logger.info(
                "TODO: multiple valid paths found when specializing this message."
            )

        if len(specializingPaths) == 0:
            raise Exception("Cannot specialize this symbol.")

        retainedPath = specializingPaths[0]

        generatedContent = None
        # let's configure the generated content
        for field in symbol.fields:

            # do no produce content if it is a pseudo field
            if field.isPseudoField is True:
                continue

            # TODO: only support one level of children... must be improved
            if len(field.fields) > 0:
                d = None
                for child in field.fields:

                    # do no produce content if it is a pseudo field
                    if child.isPseudoField is True:
                        continue

                    if d is None:
                        d = retainedPath.getDataAssignedToVariable(
                            child.domain).copy()
                    else:
                        d += retainedPath.getDataAssignedToVariable(
                            child.domain).copy()

            else:
                d = retainedPath.getDataAssignedToVariable(field.domain)

            if generatedContent is None:
                generatedContent = d.copy()
            else:
                generatedContent += d.copy()

        retainedPath.generatedContent = generatedContent

        self._logger.debug("Specialized message: {0}".format(
            TypeConverter.convert(retainedPath.generatedContent, BitArray,
                                  ASCII)))
        self.memory = retainedPath.memory

        return retainedPath