示例#1
0
 def category(self, value: Category):
     if value != self.category:
         self.__category = value
         if self.category == self.Category.generic:
             self.checksum = GenericCRC()
         elif self.category == self.Category.wsp:
             self.checksum = WSPChecksum()
         else:
             raise ValueError("Unknown Category")
示例#2
0
    def test_enocean_crc_polynomial(self):
        e = Encoding()

        msg1 = "aa9a6d201006401009802019e411e8035b"
        msg2 = "aa9a6d2010000ffdaaf01019e411e8071b"

        # Remove Preamble + SOF + EOF for CRC calculation
        msg1 = util.hex2bit("a6d201006401009802019e411e8035")
        crc1 = util.hex2bit("35")
        msg2 = util.hex2bit("a6d2010000ffdaaf01019e411e8071")
        crc2 = util.hex2bit("71")

        wsp_checker = WSPChecksum()
        calc_crc1 = wsp_checker.calculate(msg1)
        calc_crc2 = wsp_checker.calculate(msg2)
        self.assertTrue(calc_crc1 == crc1)
        self.assertTrue(calc_crc2 == crc2)
示例#3
0
    def __init__(self, name: str, start: int, end: int, color_index: int, field_type: FieldType,
                 fuzz_created=False, auto_created=False, data_range_start=0):
        assert field_type.function == FieldType.Function.CHECKSUM
        super().__init__(name, start, end, color_index, fuzz_created, auto_created, field_type)

        self.__category = self.Category.generic
        self.__data_ranges = [[data_range_start, self.start]]  # type: list[list[int,int]]
        self.checksum = GenericCRC(polynomial=0)  # type: GenericCRC or WSPChecksum
示例#4
0
    def test_enocean_crc_polynomial(self):
        e = Encoding()

        msg1 = "aa9a6d201006401009802019e411e8035b"
        msg2 = "aa9a6d2010000ffdaaf01019e411e8071b"

        # Remove Preamble + SOF + EOF for CRC calculation
        msg1 = util.hex2bit("a6d201006401009802019e411e8035")
        crc1 = util.hex2bit("35")
        msg2 = util.hex2bit("a6d2010000ffdaaf01019e411e8071")
        crc2 = util.hex2bit("71")

        wsp_checker = WSPChecksum()
        calc_crc1 = wsp_checker.calculate(msg1)
        calc_crc2 = wsp_checker.calculate(msg2)
        self.assertTrue(calc_crc1 == crc1)
        self.assertTrue(calc_crc2 == crc2)
示例#5
0
    def from_xml(cls, tag: ET.Element, field_types_by_type_id=None):
        lbl = super().from_xml(tag, field_types_by_type_id)
        result = cls.from_label(lbl)
        result.data_ranges = ast.literal_eval(tag.get("data_ranges", "[]"))
        result.category = cls.Category[tag.get("category", "generic")]

        crc_tag = tag.find("crc")
        if crc_tag is not None:
            result.checksum = GenericCRC.from_xml(crc_tag)

        wsp_tag = tag.find("wsp_checksum")
        if wsp_tag is not None:
            result.checksum = WSPChecksum.from_xml(wsp_tag)

        return result
示例#6
0
    def from_xml(cls, tag: ET.Element, field_types_by_caption=None):
        lbl = super().from_xml(tag, field_types_by_caption)
        if lbl.field_type is None or lbl.field_type.function != FieldType.Function.CHECKSUM:
            checksum_field_type = next(
                (ft for ft in field_types_by_caption.values() if ft.function == FieldType.Function.CHECKSUM),
                FieldType("checksum", FieldType.Function.CHECKSUM, display_format_index=1))
            lbl.field_type = checksum_field_type
        result = cls.from_label(lbl)
        result.data_ranges = ast.literal_eval(tag.get("data_ranges", "[]"))
        result.category = cls.Category[tag.get("category", "generic")]

        crc_tag = tag.find("crc")
        if crc_tag is not None:
            result.checksum = GenericCRC.from_xml(crc_tag)

        wsp_tag = tag.find("wsp_checksum")
        if wsp_tag is not None:
            result.checksum = WSPChecksum.from_xml(wsp_tag)

        return result
示例#7
0
class ChecksumLabel(ProtocolLabel):
    __slots__ = ("__data_ranges", "checksum", "__category")

    class Category(Enum):
        generic = "generic"
        wsp = "Wireless Short Packet (WSP)"

    def __init__(self, name: str, start: int, end: int, color_index: int, field_type: FieldType,
                 fuzz_created=False, auto_created=False, data_range_start=0):
        assert field_type.function == FieldType.Function.CHECKSUM
        super().__init__(name, start, end, color_index, fuzz_created, auto_created, field_type)

        self.__category = self.Category.generic
        self.__data_ranges = [[data_range_start, self.start]]  # type: list[list[int,int]]
        self.checksum = GenericCRC(polynomial=0)  # type: GenericCRC or WSPChecksum

    def calculate_checksum(self, bits: array.array) -> array.array:
        return self.checksum.calculate(bits)

    def calculate_checksum_for_message(self, message, use_decoded_bits: bool) -> array.array:
        data = array.array("B", [])
        bits = message.decoded_bits if use_decoded_bits else message.plain_bits
        for data_range in self.data_ranges:
            data.extend(bits[data_range[0]:data_range[1]])
        return self.calculate_checksum(data)

    @property
    def data_ranges(self):
        if self.category == self.Category.wsp:
            return [[12, -4]]
        else:
            return self.__data_ranges

    @data_ranges.setter
    def data_ranges(self, value):
        self.__data_ranges = value

    @property
    def is_generic_crc(self):
        return self.category == self.Category.generic

    @property
    def category(self) -> Category:
        return self.__category

    @category.setter
    def category(self, value: Category):
        if value != self.category:
            self.__category = value
            if self.category == self.Category.generic:
                self.checksum = GenericCRC()
            elif self.category == self.Category.wsp:
                self.checksum = WSPChecksum()
            else:
                raise ValueError("Unknown Category")

    def to_label(self, field_type: FieldType) -> ProtocolLabel:
        result = ProtocolLabel(name=self.name, start=self.start, end=self.end - 1, color_index=self.color_index, field_type=field_type,
                               auto_created=self.auto_created, fuzz_created=self.fuzz_created)
        result.apply_decoding = self.apply_decoding
        result.show = self.show
        result.fuzz_me = self.fuzz_me
        result.fuzz_values = self.fuzz_values
        result.display_format_index = self.display_format_index
        return result

    @classmethod
    def from_label(cls, label: ProtocolLabel):
        result = ChecksumLabel(name=label.name, start=label.start, end=label.end - 1, color_index=label.color_index,
                               field_type=FieldType(label.name, FieldType.Function.CHECKSUM),
                               fuzz_created=label.fuzz_created, auto_created=label.auto_created)
        result.apply_decoding = label.apply_decoding
        result.show = label.show
        result.fuzz_me = label.fuzz_me
        result.fuzz_values = label.fuzz_values
        result.display_format_index = label.display_format_index
        return result

    @classmethod
    def from_xml(cls, tag: ET.Element, field_types_by_caption=None):
        lbl = super().from_xml(tag, field_types_by_caption)
        if lbl.field_type is None or lbl.field_type.function != FieldType.Function.CHECKSUM:
            checksum_field_type = next(
                (ft for ft in field_types_by_caption.values() if ft.function == FieldType.Function.CHECKSUM),
                FieldType("checksum", FieldType.Function.CHECKSUM, display_format_index=1))
            lbl.field_type = checksum_field_type
        result = cls.from_label(lbl)
        result.data_ranges = ast.literal_eval(tag.get("data_ranges", "[]"))
        result.category = cls.Category[tag.get("category", "generic")]

        crc_tag = tag.find("crc")
        if crc_tag is not None:
            result.checksum = GenericCRC.from_xml(crc_tag)

        wsp_tag = tag.find("wsp_checksum")
        if wsp_tag is not None:
            result.checksum = WSPChecksum.from_xml(wsp_tag)

        return result

    def to_xml(self):
        result = super().to_xml()
        result.tag = "checksum_label"
        result.attrib.update({"data_ranges": str(self.data_ranges), "category": self.category.name})
        result.append(self.checksum.to_xml())
        return result
示例#8
0
    def find(self):
        result = list()
        bitvectors_by_n_gram_length = defaultdict(list)
        for i, bitvector in enumerate(self.bitvectors):
            bin_num = int(math.ceil(len(bitvector) / self.n_gram_length))
            bitvectors_by_n_gram_length[bin_num].append(i)

        crc = GenericCRC()
        for length, message_indices in bitvectors_by_n_gram_length.items():
            checksums_for_length = []
            for index in message_indices:
                bits = self.bitvectors[index]
                data_start, data_stop, crc_start, crc_stop = WSPChecksum.search_for_wsp_checksum(
                    bits)
                if (data_start, data_stop, crc_start, crc_stop) != (0, 0, 0,
                                                                    0):
                    checksum_range = ChecksumRange(start=crc_start,
                                                   length=crc_stop - crc_start,
                                                   data_range_start=data_start,
                                                   data_range_end=data_stop,
                                                   crc=WSPChecksum(),
                                                   score=1 /
                                                   len(message_indices),
                                                   field_type="checksum",
                                                   message_indices={index})
                    try:
                        present = next(c for c in checksums_for_length
                                       if c == checksum_range)
                        present.message_indices.add(index)
                    except StopIteration:
                        checksums_for_length.append(checksum_range)
                    continue

                crc_object, data_start, data_stop, crc_start, crc_stop = crc.guess_all(
                    bits, ignore_positions=self.already_labeled_cols)

                if (crc_object, data_start, data_stop, crc_start,
                        crc_stop) != (0, 0, 0, 0, 0):
                    checksum_range = ChecksumRange(start=crc_start,
                                                   length=crc_stop - crc_start,
                                                   data_range_start=data_start,
                                                   data_range_end=data_stop,
                                                   crc=copy.copy(crc_object),
                                                   score=1 /
                                                   len(message_indices),
                                                   field_type="checksum",
                                                   message_indices={index})

                    try:
                        present = next(rng for rng in checksums_for_length
                                       if rng == checksum_range)
                        present.message_indices.add(index)
                        continue
                    except StopIteration:
                        pass

                    checksums_for_length.append(checksum_range)

                    matching = awre_util.check_crc_for_messages(
                        message_indices, self.bitvectors, data_start,
                        data_stop, crc_start, crc_stop,
                        *crc_object.get_parameters())

                    checksum_range.message_indices.update(matching)

            # Score ranges
            for rng in checksums_for_length:
                rng.score = len(rng.message_indices) / len(message_indices)

            try:
                result.append(max(checksums_for_length, key=lambda x: x.score))
            except ValueError:
                pass  # no checksums found for this length

        self._debug("Found Checksums", result)
        try:
            max_scored = max(filter(
                lambda x: len(x.message_indices) >= 2 and x.score >= self.
                minimum_score, result),
                             key=lambda x: x.score)
        except ValueError:
            return []

        result = list(filter(lambda x: x.crc == max_scored.crc, result))
        self._debug("Filtered Checksums", result)

        return result