Example #1
0
    def bcHighPlateaus(self):
        """
        :return: Plateaus in the bit congruence at high level (> 0.8)
        """
        plateauElevation = 0.8
        plat = MessageAnalyzer.plateouStart(self.bitcongruences)

        # filter for plateaus of high bit congruence
        hiPlat = ([], [])
        for ix, vl in zip(plat[0], plat[1]):
            if vl > plateauElevation:
                hiPlat[0].append(ix)
                hiPlat[1].append(vl)
        return hiPlat
Example #2
0
    def messageSegmentation(self) -> List[MessageSegment]:
        """
        Segment message by determining local extrema of sigma-s-gauss-filtered sliding n-byte-mean bit-congruence.

        >>> from netzob.Model.Vocabulary.Messages.L4NetworkMessage import L4NetworkMessage
        >>> tstmsg = '19040aec0000027b000012850a6400c8d23d06a2535ed71ed23d09faa4673315d23d09faa1766325d23d09faa17b4b10'
        >>> l4m = L4NetworkMessage(bytes.fromhex(tstmsg))
        >>> hbg = HorizonBitcongruenceGauss(l4m)
        >>> hbg.setAnalysisParams()
        >>> hbg.analyze()
        >>> spm = hbg.messageSegmentation()
        >>> print(b''.join([seg.bytes for seg in spm]).hex() == spm[0].message.data.hex())
        True

        :return: Segmentation of this message based on this analyzer's type.
        """
        if not self.values:
            if not self._analysisArgs:
                raise ValueError('No values or analysis parameters set.')
            self.analyze()

        bcd = MessageAnalyzer.findExistingAnalysis(BitCongruenceDelta,
                                                   MessageAnalyzer.U_BYTE,
                                                   self.message)

        # all local minima
        bclmins = self.pinpointMinima()
        # local maxima, if bc[e] < bc[e+1] or bc[e] > 2*s2mbc[e] for all e in cadidate indices
        bclmaxs = self.pinpointMaxima()
        bcdmaxs = [
            e for e in bclmaxs
            if bcd.values[e + 1] > bcd.values[e] or bcd.values[e] > 2 *
            self.bitcongruences[e]
        ]
        minmax = bclmins
        for bdm in bcdmaxs:  # only keep bcdmaxs if not in scope if min
            if bdm + 1 not in minmax and bdm - 1 not in minmax:
                minmax.append(bdm)
        # starts of plateaus of bit congruences
        bcplats = MessageAnalyzer.plateouStart(
            self.bitcongruences)[0]  # bcd.values
        for bps in bcplats:  # only keep platoustarts if not in scope if min or max
            if bps + 1 not in minmax and bps - 1 not in minmax:
                minmax.append(bps)

        # # separate nan-values
        # nansep = MessageAnalyzer.separateNaNs(self.values)
        relevantPositions = list(sorted(minmax))
        # get candidates to cut segments from message
        cutCandidates = [0] + [int(b) for b in relevantPositions if not numpy.isnan(b)] \
                        + [len(self._message.data)]  # add the message end
        # cut only where a segment is of a length larger than 1
        cutPositions = [0] + [
            right for left, right in zip(cutCandidates[:-1], cutCandidates[1:])
            if right - left > 1
        ]
        # cutPositions = list(sorted(cutPositions + nansep[0]))
        # add the end of the message if its not already there
        if cutPositions[-1] != cutCandidates[-1]:
            cutPositions[-1] = cutCandidates[-1]

        segments = list()
        for lmaxCurr, lmaxNext in zip(cutPositions[:-1], cutPositions[1:]):
            segments.append(MessageSegment(self, lmaxCurr,
                                           lmaxNext - lmaxCurr))
        return segments