Ejemplo n.º 1
0
def check_file(opt):
    """
    Calculate the CRC of a file.
    This algorithm uses the table_driven CRC algorithm.
    """
    if opt.undefined_crc_parameters:
        sys.stderr.write("{0:s}: error: undefined parameters\n".format(progname))
        sys.exit(1)
    alg = Crc(
        width=opt.width, poly=opt.poly,
        reflect_in=opt.reflect_in, xor_in=opt.xor_in,
        reflect_out=opt.reflect_out, xor_out=opt.xor_out,
        table_idx_width=opt.tbl_idx_width)

    if not opt.reflect_in:
        register = opt.xor_in
    else:
        register = alg.reflect(opt.xor_in, opt.width)

    try:
        with open(opt.check_file, 'rb') as f:
            check_bytes = bytearray(f.read(1024))
            while check_bytes != b"":
                register = crc_file_update(alg, register, check_bytes)
                check_bytes = bytearray(f.read(1024))
    except IOError:
        sys.stderr.write(
            "{0:s}: error: can't open file {1:s}\n".format(progname, opt.check_file))
        sys.exit(1)

    if opt.reflect_out:
        register = alg.reflect(register, opt.width)
    register = register ^ opt.xor_out
    return register
Ejemplo n.º 2
0
 def __init__(self, minMic=0.7):
     self.minMic = minMic
     self.tiger_crc = Crc(width=16,
                          poly=0x1021,
                          xor_in=0x0000,
                          xor_out=0x0000,
                          reflect_in=False,
                          reflect_out=False)
Ejemplo n.º 3
0
 def __init__(self, model='dallas-1-wire'):
     self.params = CrcModels().get_params(model)
     self.encoder = Crc(self.params['width'],
                        self.params['poly'],
                        self.params['reflect_in'],
                        self.params['xor_in'],
                        self.params['reflect_out'],
                        self.params['xor_out'])
Ejemplo n.º 4
0
def Crc32(frame) -> int:
    #CRC32
    polynomial = 0x104c11db6
    crc = Crc(width=32,
              poly=polynomial,
              reflect_in=True,
              xor_in=(1 << 32) - 1,
              reflect_out=True,
              xor_out=0x00)
    crc_calc = crc.bit_by_bit(frame)
    return crc_calc
Ejemplo n.º 5
0
def check_string(opt):
    """
    Return the calculated CRC sum of a string.
    """
    error = False
    if opt.undefined_crc_parameters:
        sys.stderr.write(
            "{0:s}: error: undefined parameters\n".format(progname))
        sys.exit(1)
    if opt.algorithm == 0:
        opt.algorithm = opt.algo_bit_by_bit | opt.algo_bit_by_bit_fast | opt.algo_table_driven

    alg = Crc(width=opt.width,
              poly=opt.poly,
              reflect_in=opt.reflect_in,
              xor_in=opt.xor_in,
              reflect_out=opt.reflect_out,
              xor_out=opt.xor_out,
              table_idx_width=opt.tbl_idx_width)

    crc = None
    if opt.algorithm & opt.algo_bit_by_bit:
        bbb_crc = alg.bit_by_bit(opt.check_string)
        if crc != None and bbb_crc != crc:
            error = True
        crc = bbb_crc
    if opt.algorithm & opt.algo_bit_by_bit_fast:
        bbf_crc = alg.bit_by_bit_fast(opt.check_string)
        if crc != None and bbf_crc != crc:
            error = True
        crc = bbf_crc
    if opt.algorithm & opt.algo_table_driven:
        # no point making the python implementation slower by using less than 8 bits as index.
        opt.tbl_idx_width = 8
        tbl_crc = alg.table_driven(opt.check_string)
        if crc != None and tbl_crc != crc:
            error = True
        crc = tbl_crc

    if error:
        sys.stderr.write(
            "{0:s}: error: different checksums!\n".format(progname))
        if opt.algorithm & opt.algo_bit_by_bit:
            sys.stderr.write(
                "       bit-by-bit:        {0:#x}\n".format(bbb_crc))
        if opt.algorithm & opt.algo_bit_by_bit_fast:
            sys.stderr.write(
                "       bit-by-bit-fast:   {0:#x}\n".format(bbf_crc))
        if opt.algorithm & opt.algo_table_driven:
            sys.stderr.write(
                "       table_driven:      {0:#x}\n".format(tbl_crc))
        sys.exit(1)
    return crc
Ejemplo n.º 6
0
    def __get_crc(self, model, check_str='123456789', expected_crc=None):
        """
        Get the CRC for a set of parameters from the Python reference implementation.
        """
        if self.verbose:
            out_str = 'Crc(width = {width:d}, poly = {poly:#x}, reflect_in = {reflect_in}, xor_in = {xor_in:#x}, reflect_out = {reflect_out}, xor_out = {xor_out:#x})'.format(
                **model)
            if expected_crc is not None:
                out_str += ' [check = {0:#x}]'.format(expected_crc)
            print(out_str)
        alg = Crc(width=model['width'],
                  poly=model['poly'],
                  reflect_in=model['reflect_in'],
                  xor_in=model['xor_in'],
                  reflect_out=model['reflect_out'],
                  xor_out=model['xor_out'])
        error = False
        crc = expected_crc

        if self.use_algo_bit_by_bit:
            bbb_crc = alg.bit_by_bit(check_str)
            if crc is None:
                crc = bbb_crc
            error = error or bbb_crc != crc
        if self.use_algo_bit_by_bit_fast:
            bbf_crc = alg.bit_by_bit_fast(check_str)
            if crc is None:
                crc = bbf_crc
            error = error or bbf_crc != crc
        if self.use_algo_table_driven:
            tbl_crc = alg.table_driven(check_str)
            if crc is None:
                crc = tbl_crc
            error = error or tbl_crc != crc

        if error:
            print('error: different checksums!')
            if expected_crc is not None:
                print('       check:             {0:#x}'.format(expected_crc))
            if self.use_algo_bit_by_bit:
                print('       bit-by-bit:        {0:#x}'.format(bbb_crc))
            if self.use_algo_bit_by_bit_fast:
                print('       bit-by-bit-fast:   {0:#x}'.format(bbf_crc))
            if self.use_algo_table_driven:
                print('       table_driven:      {0:#x}'.format(tbl_crc))
            return None
        return crc
Ejemplo n.º 7
0
def check_crc(code_bytes):
    # Initialize the CRC algorithm
    crc = Crc(width=16,
              poly=0x1021,
              reflect_in=True,
              xor_in=0xffff,
              reflect_out=True,
              xor_out=0xffff)

    # Separate the 128-bit number from its CRC value
    received_number = code_bytes[0:16]
    received_crc = int.from_bytes(code_bytes[16:18], byteorder="little")

    # Compute the CRC value of the received number
    computed_crc = crc.bit_by_bit_fast(received_number)

    return computed_crc, received_crc
Ejemplo n.º 8
0
def check_string(opt):
    """
    Return the calculated CRC sum of a string.
    """
    error = False
    if opt.undefined_crc_parameters:
        sys.stderr.write("{0:s}: error: undefined parameters\n".format(progname))
        sys.exit(1)
    if opt.algorithm == 0:
        opt.algorithm = opt.algo_bit_by_bit | opt.algo_bit_by_bit_fast | opt.algo_table_driven

    alg = Crc(
        width=opt.width, poly=opt.poly,
        reflect_in=opt.reflect_in, xor_in=opt.xor_in,
        reflect_out=opt.reflect_out, xor_out=opt.xor_out,
        table_idx_width=opt.tbl_idx_width)

    crc = None
    if opt.algorithm & opt.algo_bit_by_bit:
        bbb_crc = alg.bit_by_bit(opt.check_string)
        if crc != None and bbb_crc != crc:
            error = True
        crc = bbb_crc
    if opt.algorithm & opt.algo_bit_by_bit_fast:
        bbf_crc = alg.bit_by_bit_fast(opt.check_string)
        if crc != None and bbf_crc != crc:
            error = True
        crc = bbf_crc
    if opt.algorithm & opt.algo_table_driven:
        # no point making the python implementation slower by using less than 8 bits as index.
        opt.tbl_idx_width = 8
        tbl_crc = alg.table_driven(opt.check_string)
        if crc != None and tbl_crc != crc:
            error = True
        crc = tbl_crc

    if error:
        sys.stderr.write("{0:s}: error: different checksums!\n".format(progname))
        if opt.algorithm & opt.algo_bit_by_bit:
            sys.stderr.write("       bit-by-bit:        {0:#x}\n".format(bbb_crc))
        if opt.algorithm & opt.algo_bit_by_bit_fast:
            sys.stderr.write("       bit-by-bit-fast:   {0:#x}\n".format(bbf_crc))
        if opt.algorithm & opt.algo_table_driven:
            sys.stderr.write("       table_driven:      {0:#x}\n".format(tbl_crc))
        sys.exit(1)
    return crc
Ejemplo n.º 9
0
def _get_init_value(opt):
    """
    Return the init value of a C implementation, according to the selected
    algorithm and to the given options.
    If no default option is given for a given parameter, value in the cfg_t
    structure must be used.
    """
    if opt.algorithm == opt.algo_bit_by_bit:
        if opt.xor_in is None or opt.width is None or opt.poly is None:
            return None
        crc = Crc(width=opt.width,
                  poly=opt.poly,
                  reflect_in=opt.reflect_in,
                  xor_in=opt.xor_in,
                  reflect_out=opt.reflect_out,
                  xor_out=opt.xor_out,
                  table_idx_width=opt.tbl_idx_width)
        init = crc.nondirect_init
    elif opt.algorithm == opt.algo_bit_by_bit_fast:
        if opt.xor_in is None:
            return None
        init = opt.xor_in
    elif opt.algorithm == opt.algo_table_driven:
        if opt.reflect_in is None or opt.xor_in is None or opt.width is None:
            return None
        if opt.poly is None:
            poly = 0
        else:
            poly = opt.poly
        crc = Crc(width=opt.width,
                  poly=poly,
                  reflect_in=opt.reflect_in,
                  xor_in=opt.xor_in,
                  reflect_out=opt.reflect_out,
                  xor_out=opt.xor_out,
                  table_idx_width=opt.tbl_idx_width)
        if opt.reflect_in:
            init = crc.reflect(crc.direct_init, opt.width)
        else:
            init = crc.direct_init
    else:
        init = 0
    return _pretty_hex(init, opt.width)
Ejemplo n.º 10
0
    def __get_crc(self, model, check_str = '123456789', expected_crc = None):
        """
        Get the CRC for a set of parameters from the Python reference implementation.
        """
        if self.verbose:
            out_str = 'Crc(width = {width:d}, poly = {poly:#x}, reflect_in = {reflect_in}, xor_in = {xor_in:#x}, reflect_out = {reflect_out}, xor_out = {xor_out:#x})'.format(**model)
            if expected_crc is not None:
                out_str += ' [check = {0:#x}]'.format(expected_crc)
            print(out_str)
        alg = Crc(width = model['width'], poly = model['poly'],
            reflect_in = model['reflect_in'], xor_in = model['xor_in'],
            reflect_out = model['reflect_out'], xor_out = model['xor_out'])
        error = False
        crc = expected_crc

        if self.use_algo_bit_by_bit:
            bbb_crc = alg.bit_by_bit(check_str)
            if crc is None:
                crc = bbb_crc
            error = error or bbb_crc != crc
        if self.use_algo_bit_by_bit_fast:
            bbf_crc = alg.bit_by_bit_fast(check_str)
            if crc is None:
                crc = bbf_crc
            error = error or bbf_crc != crc
        if self.use_algo_table_driven:
            tbl_crc = alg.table_driven(check_str)
            if crc is None:
                crc = tbl_crc
            error = error or tbl_crc != crc

        if error:
            print('error: different checksums!')
            if expected_crc is not None:
                print('       check:             {0:#x}'.format(expected_crc))
            if self.use_algo_bit_by_bit:
                print('       bit-by-bit:        {0:#x}'.format(bbb_crc))
            if self.use_algo_bit_by_bit_fast:
                print('       bit-by-bit-fast:   {0:#x}'.format(bbf_crc))
            if self.use_algo_table_driven:
                print('       table_driven:      {0:#x}'.format(tbl_crc))
            return None
        return crc
Ejemplo n.º 11
0
def _get_table_init(opt):  # TODO: change to return a list
    """
    Return the precalculated CRC table for the table_driven implementation.
    """
    if opt.algorithm != opt.algo_table_driven:
        return "0"
    if opt.width is None or opt.poly is None or opt.reflect_in is None:
        return "0"
    crc = Crc(
        width=opt.width,
        poly=opt.poly,
        reflect_in=opt.reflect_in,
        xor_in=0,
        reflect_out=False,
        xor_out=0,  # set unimportant variables to known values
        table_idx_width=opt.tbl_idx_width,
        slice_by=opt.slice_by)
    crc_tbl = crc.gen_table()
    if opt.width > 32:
        values_per_line = 4
    elif opt.width >= 16:
        values_per_line = 8
    else:
        values_per_line = 16
    format_width = max(opt.width, 8)
    if opt.slice_by == 1:
        indent = 4
    else:
        indent = 8

    out = [''] * opt.slice_by
    for i in range(opt.slice_by):
        out[i] = _get_simple_table(opt, crc_tbl[i], values_per_line,
                                   format_width, indent)
    fixed_indent = ' ' * (indent - 4)
    out = '{0:s}{{\n'.format(fixed_indent) + \
        '\n{0:s}}},\n{0:s}{{\n'.format(fixed_indent).join(out) + \
        '\n{0:s}}}'.format(fixed_indent)
    if opt.slice_by == 1:
        return out
    return '{\n' + out + '\n}'
Ejemplo n.º 12
0
class CrcEncoder(object):
    def __init__(self, model='dallas-1-wire'):
        self.params = CrcModels().get_params(model)
        self.encoder = Crc(self.params['width'],
                           self.params['poly'],
                           self.params['reflect_in'],
                           self.params['xor_in'],
                           self.params['reflect_out'],
                           self.params['xor_out'])

    def encode(self, msg):
        crc_hex = self.encoder.bit_by_bit(msg)
        return chr(crc_hex) + msg
Ejemplo n.º 13
0
def _get_init_value(opt):
    """
    Return the init value of a C implementation, according to the selected
    algorithm and to the given options.
    If no default option is given for a given parameter, value in the cfg_t
    structure must be used.
    """
    if opt.algorithm == opt.algo_bit_by_bit:
        if opt.xor_in is None or opt.width is None or opt.poly is None:
            return None
        crc = Crc(
            width=opt.width, poly=opt.poly,
            reflect_in=opt.reflect_in, xor_in=opt.xor_in,
            reflect_out=opt.reflect_out, xor_out=opt.xor_out,
            table_idx_width=opt.tbl_idx_width)
        init = crc.nondirect_init
    elif opt.algorithm == opt.algo_bit_by_bit_fast:
        if opt.xor_in is None:
            return None
        init = opt.xor_in
    elif opt.algorithm == opt.algo_table_driven:
        if opt.reflect_in is None or opt.xor_in is None or opt.width is None:
            return None
        if opt.poly is None:
            poly = 0
        else:
            poly = opt.poly
        crc = Crc(
            width=opt.width, poly=poly,
            reflect_in=opt.reflect_in, xor_in=opt.xor_in,
            reflect_out=opt.reflect_out, xor_out=opt.xor_out,
            table_idx_width=opt.tbl_idx_width)
        if opt.reflect_in:
            init = crc.reflect(crc.direct_init, opt.width)
        else:
            init = crc.direct_init
    else:
        init = 0
    return _pretty_hex(init, opt.width)
Ejemplo n.º 14
0
def _get_table_init(opt):       # TODO: change to return a list
    """
    Return the precalculated CRC table for the table_driven implementation.
    """
    if opt.algorithm != opt.algo_table_driven:
        return "0"
    if opt.width is None or opt.poly is None or opt.reflect_in is None:
        return "0"
    crc = Crc(
        width=opt.width, poly=opt.poly,
        reflect_in=opt.reflect_in,
        xor_in=0, reflect_out=False, xor_out=0,     # set unimportant variables to known values
        table_idx_width=opt.tbl_idx_width,
        slice_by=opt.slice_by)
    crc_tbl = crc.gen_table()
    if opt.width > 32:
        values_per_line = 4
    elif opt.width >= 16:
        values_per_line = 8
    else:
        values_per_line = 16
    format_width = max(opt.width, 8)
    if opt.slice_by == 1:
        indent = 4
    else:
        indent = 8

    out = [''] * opt.slice_by
    for i in range(opt.slice_by):
        out[i] = _get_simple_table(opt, crc_tbl[i], values_per_line, format_width, indent)
    fixed_indent = ' ' * (indent - 4)
    out = '{0:s}{{\n'.format(fixed_indent) + \
        '\n{0:s}}},\n{0:s}{{\n'.format(fixed_indent).join(out) + \
        '\n{0:s}}}'.format(fixed_indent)
    if opt.slice_by == 1:
        return out
    return '{\n' + out + '\n}'
Ejemplo n.º 15
0
class RelationFinder(object):
    """Provides multiple algorithms to find relations between messages.

    >>> import binascii
    >>> from netzob.all import *
    >>> samples = [b"0007ff2f000000000000", b"0011ffaaaaaaaaaaaaaabbcc0010000000000000", b"0012ffddddddddddddddddddddfe1f000000000000"]
    >>> messages = [RawMessage(data=binascii.unhexlify(sample)) for sample in samples]
    >>> symbol = Symbol(messages=messages)
    >>> Format.splitStatic(symbol)
    >>> rels = RelationFinder.findOnFields(symbol.fields[1], symbol.fields[3])
    >>> print(len(rels))
    1
    >>> for rel in rels:
    ...     print(rel["relation_type"] + " between " + rel["x_field"].name + ":" + rel["x_attribute"] + \
            " and " + rel["y_field"].name + ":" + rel["y_attribute"])
    SizeRelation between Field-1:value and Field-3:size

    >>> rels = RelationFinder.findOnSymbol(symbol)
    >>> print(len(rels))
    1
    >>> for rel in rels:
    ...     print(rel["relation_type"] + " between fields " + str([x.name for x in rel["x_fields"]]) + ":" + rel["x_attribute"] + \
            " and fields " + str([y.name for y in rel["y_fields"]]) + ":" + rel["y_attribute"])
    SizeRelation between fields ['Field-1']:value and fields ['Field-3']:size

     The following illustrates DataRelation

     >>> samples = ["Adrien > my name is Adrien", "Zoby > my name is Zoby"]
     >>> messages = [RawMessage(sample) for sample in samples]
     >>> symbol = Symbol(messages=messages)
     >>> Format.splitAligned(symbol)
     >>> results = RelationFinder.findOnSymbol(symbol)
     >>> len(results)
     3
     >>> print(results[0]['relation_type'])
     DataRelation
     >>> results[0]['x_fields'][0].getValues()
     [b'Adrien', b'Zoby']

    """

    # Field's attributes
    ATTR_VALUE = "value"
    ATTR_SIZE = "size"
    ATTR_CRC32 = "crc32"
    ATTR_TIGER_CRC16 = "tiger_crc16"
    AVAILABLE_ATTRIBUTES = [ATTR_VALUE, ATTR_SIZE]

    # Relation types
    REL_SIZE = "SizeRelation"
    REL_DATA = "DataRelation"
    REL_EQUALITY = "EqualityRelation"
    REL_UNKNOWN = "Unknown"

    def __init__(self):
        self.tiger_crc = Crc(width=16, poly=0x1021, xor_in=0x0000, xor_out=0xFFFF, reflect_in=True, reflect_out=True)
        pass

    @staticmethod
    @typeCheck(AbstractField)
    def findOnSymbol(symbol):
        """Find exact relations between fields in the provided
        symbol/field.

        :param symbol: the symbol in which we are looking for relations
        :type symbol: :class:`netzob.Model.Vocabulary.AbstractField.AbstractField`
        """

        rf = RelationFinder()
        return rf.executeOnSymbol(symbol)

    @staticmethod
    @typeCheck(AbstractField, AbstractField, str, str)
    def findOnFields(x_field, y_field, x_attribute=None, y_attribute=None):
        """Find exact relations between the provided fields, according
        to their optional specified attributes.

        """

        rf = RelationFinder()
        return rf.executeOnFields(x_field, y_field, x_attribute, y_attribute)

    # @typeCheck(AbstractField)
    # def executeOnSymbol(self, symbol):
    #     """
    #     :param symbol: the symbol in which we are looking for relations
    #     :type symbol: :class:`netzob.Model.Vocabulary.AbstractField.AbstractField`
    #     """

    #     cells = [field.getValues(encoded=False, styled=False)
    #              for field in symbol.getExtendedFields()
    #              #if not field.isStatic()
    #              ]
    #     if cells:
    #         # Invert array dimensions liks this:
    #         # < [[m0f0, m1f0, ...], [m0f1, m1f1, ...]]
    #         # > [(m0f0, m0f1, ...), (m1f0, m1f1, ...)]
    #         for algo, refs in _libRelation.find(zip(*cells)).items():
    #             for ref_idx, ref_off, ref_size, rels in refs:
    #                 print "Relations(%s) with F%d:" % (algo, ref_idx)
    #                 for rel_id, rel_conf in enumerate(rels):
    #                     print "  %d. F[%d][%d:%d]" % ((rel_id,) + rel_conf)

    # def executeOnCells(self, cellsTable):
    #     if cellsTable:
    #         # Invert array dimensions liks this:
    #         # < [[m0f0, m1f0, ...], [m0f1, m1f1, ...]]
    #         # > [(m0f0, m0f1, ...), (m1f0, m1f1, ...)]
    #         for algo, refs in _libRelation.find(zip(*cellsTable)).items():
    #             for ref_idx, ref_off, ref_size, rels in refs:
    #                 print "Relations(%s) with F%d:" % (algo, ref_idx)
    #                 for rel_id, rel_conf in enumerate(rels):
    #                     print "  %d. F[%d][%d:%d]" % ((rel_id,) + rel_conf)

    @typeCheck(AbstractField)
    def executeOnSymbol(self, symbol):
        """Find exact relations between fields of the provided symbol.
        """

        (attributeValues_headers,
         attributeValues) = self._generateAttributeValuesForSymbol(symbol)
        results = []

        for i, x_values in enumerate(attributeValues[:-1]):
            for j, y_values in enumerate(attributeValues[:]):
                if j <= i:
                    continue
                isRelation = True
                for k in range(len(x_values)):
                    if not (x_values[k] == y_values[k]):
                        isRelation = False
                        break
                if isRelation:

                    # TODO make configurable
                    # # Do no keep relations where a field's values does not change
                    # if len(set(x_values)) == 1 or len(set(y_values)) == 1:
                    #     continue

                    (x_fields, x_attribute) = attributeValues_headers[i]
                    (y_fields, y_attribute) = attributeValues_headers[j]
                    # The relation should not apply on the same field
                    if len(x_fields) == 1 and len(y_fields) == 1 and x_fields[
                        0].id == y_fields[0].id:
                        continue
                    relation_type = self._findRelationType(x_attribute,
                                                           y_attribute, x_fields, y_fields)
                    # We do not consider unqualified relation (for example, the size of a field is linked to the size of another field)
                    if relation_type == self.REL_UNKNOWN:
                        continue
                    # DataRelation should produce an empty intersection between related fields
                    if relation_type == self.REL_DATA and len(
                            set(x_fields).intersection(set(y_fields))) > 0:
                        continue
                    # SizeRelation should a size field composed of multiple fields
                    if relation_type == self.REL_SIZE:
                        if x_attribute == self.ATTR_VALUE:
                            if len(x_fields) > 1:
                                continue
                        elif y_attribute == self.ATTR_VALUE:
                            if len(y_fields) > 1:
                                continue
                    # EqualityRelation should a field be equal to another field composed of multiple fields
                    if relation_type == self.REL_EQUALITY:
                        if x_attribute == self.ATTR_VALUE:
                            if len(x_fields) > 1:
                                continue
                        elif y_attribute == self.ATTR_VALUE:
                            if len(y_fields) > 1:
                                continue
                    self._logger.debug("Relation found between '" + str(
                        x_fields) + ":" + x_attribute + "' and '" + str(
                        y_fields) + ":" + y_attribute + "'")
                    id_relation = str(uuid.uuid4())
                    results.append({
                        'id': id_relation,
                        "relation_type": relation_type,
                        'x_fields': x_fields,
                        'x_attribute': x_attribute,
                        'y_fields': y_fields,
                        'y_attribute': y_attribute
                    })
        return results

    @typeCheck(AbstractField, AbstractField, str, str)
    def executeOnFields(self,
                        x_field,
                        y_field,
                        x_attribute=None,
                        y_attribute=None):
        """Find exact relations between fields according to their
        optional selected attributes.
        """

        results = []
        # Convert cells according to their interesting attribute (data, size or offset)
        if x_attribute == self.ATTR_SIZE and y_attribute == self.ATTR_SIZE:  # A relation between two size field is uncertain...
            return results
        x_values = x_field.getValues(encoded=False, styled=False)
        y_values = y_field.getValues(encoded=False, styled=False)

        # Select attributes for fields comparison
        if x_attribute is None:
            x_attributes = self.AVAILABLE_ATTRIBUTES
        else:
            x_attributes = [x_attribute]

        if y_attribute is None:
            y_attributes = self.AVAILABLE_ATTRIBUTES
        else:
            y_attributes = [y_attribute]

        # Try to find a relation that matches each cell
        relation_fcts = {}
        # relation_fcts[self.REL_SIZE] = self._sizeRelation(x_attribute,y_attribute)
        # TODO Pass correct parameters to equalRelation
        relation_fcts[self.REL_SIZE] = self._sizeRelation
        relation_fcts[self.REL_EQUALITY] = self._equalRelation

        for x_attribute in x_attributes:
            for y_attribute in y_attributes:
                for (relation_name, relation_fct) in list(relation_fcts.items()):
                    isRelation = True
                    for i in range(len(x_values)):
                        if not relation_fct(x_values[i], x_attribute, y_values[i], y_attribute):
                            isRelation = False
                            break
                    if isRelation:
                        self._logger.debug("Relation found between '" + x_attribute + ":" + str(
                            x_field.name) + "' and '" + y_attribute + ":" + str(y_field.name) + "'")
                        self._logger.debug("  Relation: " + relation_name)
                        id_relation = str(uuid.uuid4())
                        results.append({'id': id_relation,
                                        "relation_type": relation_name,
                                        'x_field': x_field,
                                        'x_attribute': x_attribute,
                                        'y_field': y_field,
                                        'y_attribute': y_attribute})
        return results

    def _findRelationType(self, x_attribute, y_attribute, x_fields, y_fields):
        typeRelation = self.REL_UNKNOWN
        if (x_attribute == self.ATTR_VALUE and y_attribute == self.ATTR_SIZE) or (
                x_attribute == self.ATTR_SIZE and y_attribute == self.ATTR_VALUE):
            typeRelation = self.REL_SIZE
        elif x_attribute == y_attribute == self.ATTR_VALUE:
            typeRelation = self.REL_DATA
        elif self._checkEqualityRelation(x_fields, y_fields) or {self.ATTR_VALUE, self.ATTR_TIGER_CRC16} == {
        x_attribute, y_attribute}:
            typeRelation = self.REL_EQUALITY
        return typeRelation

    def _checkEqualityRelation(self, x_fields, y_fields):
        x_values = []
        for x_field in x_fields:
            x_values += x_field.getValues(encoded=False, styled=False)
        y_values = []
        for y_field in y_fields:
            y_values += y_field.getValues(encoded=False, styled=False)
        if set(x_values) == set(y_values):
            return True
        else:
            return False

    def _equalRelation(self, x, x_attribute, y, y_attribute):
        if x == y:
            return True
        else:
            return False

    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:
                y = TypeConverter.convert(y[:8], Raw, Integer)
            else:
                y = 0

        if x == y:
            return True
        else:
            return False

    def _generateAttributeValuesForSymbol(self, symbol):
        # First we compute the possible list of payloads
        lines_data = []
        line_header = []

        # Compute the list of values for each field
        (fields, fieldsValues) = self._getAllFieldsValues(symbol)

        # Compute the table of concatenation of values
        for i in range(len(fieldsValues[:])):
            for j in range(i + 1, len(fieldsValues) + 1):
                # We generate the data
                concatCellsData = self._generateConcatData(fieldsValues[i:j])

                # We generate lines and header for fields values
                line_header.append((fields[i:j], self.ATTR_VALUE))
                lines_data.append(self._generateDataValues(concatCellsData))

                # We generate lines and header for fields values
                line_header.append((fields[i:j], self.ATTR_SIZE))
                lines_data.append(self._generateSizeValues(concatCellsData))

                # # Generate CRC32
                # line_header.append((fields[i:j], self.ATTR_CRC32))
                # lines_data.append(self._generateCRC32(concatCellsData))

                line_header.append((fields[i:j], self.ATTR_TIGER_CRC16))
                lines_data.append(self._generateTigerCRC16(concatCellsData))

        # # # Now we generate values for fields sizes
        # # (multipleSize_Header, multipleSize_lines) = self._generateSizeFieldFromBeginingOfField(symbol)
        # # line_header.extend(multipleSize_Header)
        # # for i_line in range(0, len(lines)):
        # #     lines[i_line] = lines[i_line] + "," + multipleSize_lines[i_line]

        # # # Now we generate values for CRC32
        # # (crc32Header, crc32Lines) = self._generateCRC32(symbol)
        # # line_header.extend(crc32Header)
        # # for i_line in range(0, len(lines)):
        # #     line = lines[i_line]
        # #     lines[i_line] = line + "," + crc32Lines[i_line]

        return (line_header, lines_data)

    def _getAllFieldsValues(self, field):
        # This recursive function returns a tuple containing
        # (array of all fields, array of values of each field)
        if len(field.fields) > 0:
            fields = []
            values = []
            for f in field.fields:
                (retFields, retValues) = self._getAllFieldsValues(f)
                fields.extend(retFields)
                values.extend(retValues)
            return (fields, values)
        else:
            return ([field], [field.getValues(encoded=False, styled=False)])

    def _generateConcatData(self, cellsDataList):
        """Generates the concatenation of each cell of each field.
        Example:
          cellsData_1 = ["a", "aa", "aaa"]
          cellsData_2 = ["b", "bb", "bbb"]
          res = ["ab", "aabb", "aaabbb"]
        """

        if len(cellsDataList) < 1:
            return []
        result = [b"" for cell in cellsDataList[0]]
        for cellsData in cellsDataList:
            for i, data in enumerate(cellsData):
                result[i] += data
        return result

    def _generateDataValues(self, cellsData):
        result = []
        for data in cellsData:
            if len(data) > 0:
                data = data[:8]  # We take at most 8 bytes
                unitSize = int(AbstractType.UNITSIZE_8) * len(data)
                unitSize = int(pow(2, math.ceil(math.log(
                    unitSize, 2))))  # Round to the nearest upper power of 2
                result.append(
                    Integer.encode(
                        data,
                        endianness=AbstractType.ENDIAN_BIG,
                        unitSize=str(unitSize)))
            else:
                result.append(0)
        return result

    def _generateSizeValues(self, cellsData):
        result = []
        for data in cellsData:
            if len(data) > 0:
                result.append(len(data))  # Size in octets
            else:
                result.append(0)
        return result

    def _generateCRC32(self, cellsData):
        result = []
        for data in cellsData:
            valCrc32 = zlib.crc32(data)  # & 0xFFFFFFFF
            result.append(valCrc32)
        return result

    def _generateTigerCRC16(self, cellsData):
        result = []
        for data in cellsData:
            data = data + bytes([len(data)])
            valCrc32 = int.from_bytes(int.to_bytes(self.tiger_crc.bit_by_bit_fast(data), 2, byteorder="big"),
                                      byteorder="big", signed=True)
            result.append(valCrc32)
        return result
Ejemplo n.º 16
0
class CorrelationFinder(object):
    """Correlation identification based on MINE (Maximal
    Information-based Nonparametric Exploration) statistics.
    TODO: implement CRC in class correctly

    >>> import binascii
    >>> from netzob.all import *
    >>> samples = [b"0007ff2f000000000000", b"0011ffaaaaaaaaaaaaaabbcc0010000000000000", b"0012ffddddddddddddddddddddfe1f000000000000"]
    >>> messages = [RawMessage(data=binascii.unhexlify(sample)) for sample in samples]
    >>> symbol = Symbol(messages=messages)
    >>> Format.splitStatic(symbol)
    >>> rels = CorrelationFinder.find(symbol)
    >>> print(len(rels))
    64
    """

    # Field's attributes
    ATTR_VALUE = "value"
    ATTR_SIZE = "size"
    ATTR_CRC32 = "crc32"
    ATTR_TIGER_CRC16 = "tiger_crc16"

    # Relation types
    REL_SIZE = "SizeRelation"
    REL_DATA = "DataRelation"

    @staticmethod
    @typeCheck(AbstractField, float)
    def find(symbol, minMic=0.7):
        """Find correlations between fields in the provided symbol,
        according to a minimum threshold. The underlying work is as
        follow: we compute the combination of each field's attribute
        (value, size, etc.), execute MINE correlation finder on it and
        parse the results.

        :param symbol: the symbol in which we are looking for correlations
        :type symbol: :class:`netzob.Model.Vocabulary.AbstractField.AbstractField`
        :param minMic: the minimum correlation score 
        :type minMic: :class:`float`
        """

        try:
            import numpy
        except:
            # Fall back to classical relations
            import logging
            logging.warn(
                "'numpy' and 'minepy' packages needed for CorrelationFinder. Fall back to RelationFinder instead."
            )
            return RelationFinder.findOnSymbol(symbol)

        cf = CorrelationFinder(minMic)
        return cf.execute(symbol)

    def __init__(self, minMic=0.7):
        self.minMic = minMic
        self.tiger_crc = Crc(width=16,
                             poly=0x1021,
                             xor_in=0x0000,
                             xor_out=0x0000,
                             reflect_in=False,
                             reflect_out=False)

    @typeCheck(AbstractField)
    def execute(self, symbol):
        """
        :param symbol: the symbol in which we are looking for correlations
        :type symbol: :class:`netzob.Model.Vocabulary.AbstractField.AbstractField`
        """

        (attributeValues_headers,
         attributeValues) = self._generateAttributeValuesForSymbol(symbol)
        symbolResults = []

        # MINE computation of each field's combination
        for i, values_x in enumerate(attributeValues[:-1]):
            for j, values_y in enumerate(attributeValues[i + 1:]):
                mine = MINE(alpha=0.6, c=15)
                mine.compute_score(numpy.array(values_x),
                                   numpy.array(values_y))
                mic = round(mine.mic(), 2)
                if mic > float(self.minMic):
                    # We add the relation to the results
                    (x_fields, x_attribute) = attributeValues_headers[i]
                    (y_fields, y_attribute) = attributeValues_headers[j]
                    # The relation should not apply on the same field
                    if len(x_fields) == 1 and len(y_fields) == 1 and x_fields[
                            0].id == y_fields[0].id:
                        continue
                    pearson = numpy.corrcoef(values_x, values_y)[0, 1]
                    if not numpy.isnan(pearson):
                        pearson = round(pearson, 2)
                    relation_type = self._findRelationType(
                        x_attribute, y_attribute)
                    self._debug_mine_stats(mine)
                    self._logger.debug("Correlation found between '" +
                                       str(x_fields) + ":" + x_attribute +
                                       "' and '" + str(y_fields) + ":" +
                                       y_attribute + "'")
                    self._logger.debug("  MIC score: " + str(mic))
                    self._logger.debug("  Pearson score: " + str(pearson))
                    id_relation = str(uuid.uuid4())
                    symbolResults.append({
                        'id': id_relation,
                        "relation_type": relation_type,
                        'x_fields': x_fields,
                        'x_attribute': x_attribute,
                        'y_fields': y_fields,
                        'y_attribute': y_attribute,
                        'mic': mic,
                        'pearson': pearson
                    })
        return symbolResults

    def _debug_mine_stats(self, mine):
        self._logger.debug("MIC: " + str(mine.mic()))
        self._logger.debug("MAS: " + str(mine.mas()))
        self._logger.debug("MEV: " + str(mine.mev()))
        self._logger.debug("MCN (eps=0): " + str(mine.mcn(0)))
        self._logger.debug("MCN (eps=1-MIC): " + str(mine.mcn_general()))

    def _findRelationType(self, x_attribute, y_attribute):
        typeRelation = "Unknown"
        if (x_attribute == self.ATTR_VALUE and y_attribute
                == self.ATTR_SIZE) or (x_attribute == self.ATTR_SIZE
                                       and y_attribute == self.ATTR_VALUE):
            typeRelation = self.REL_SIZE
        elif (x_attribute == x_attribute) and x_attribute == self.ATTR_VALUE:
            typeRelation = self.REL_DATA
        return typeRelation

    def _generateAttributeValuesForSymbol(self, symbol):
        # First we compute the possible list of payloads
        lines_data = []
        line_header = []

        # Compute the table of values
        valuesTable = []
        fields = symbol.fields
        for field in fields:
            valuesTable.append(field.getValues(encoded=False, styled=False))

        # Compute the table of concatenation of values
        for i in range(len(fields[:])):
            for j in range(i + 1, len(fields) + 1):
                # We generate the data
                concatCellsData = self._generateConcatData(valuesTable[i:j])

                # We generate lines and header for fields values
                line_header.append((fields[i:j], self.ATTR_VALUE))
                lines_data.append(self._generateDataValues(concatCellsData))

                # We generate lines and header for fields values
                line_header.append((fields[i:j], self.ATTR_SIZE))
                lines_data.append(self._generateSizeValues(concatCellsData))

                # Generate CRC32
                line_header.append((fields[i:j], self.ATTR_CRC32))
                lines_data.append(self._generateCRC32(concatCellsData))

        # # # Now we generate values for fields sizes
        # # (multipleSize_Header, multipleSize_lines) = self._generateSizeFieldFromBeginingOfField(symbol)
        # # line_header.extend(multipleSize_Header)
        # # for i_line in range(0, len(lines)):
        # #     lines[i_line] = lines[i_line] + "," + multipleSize_lines[i_line]

        # # # Now we generate values for CRC32
        # # (crc32Header, crc32Lines) = self._generateCRC32(symbol)
        # # line_header.extend(crc32Header)
        # # for i_line in range(0, len(lines)):
        # #     line = lines[i_line]
        # #     lines[i_line] = line + "," + crc32Lines[i_line]

        return (line_header, lines_data)

    def _generateConcatData(self, cellsDataList):
        """Generates the concatenation of each cell of each field.
        Example:
          cellsData_1 = ["a", "aa", "aaa"]
          cellsData_2 = ["b", "bb", "bbb"]
          res = ["ab", "aabb", "aaabbb"]
        """

        if len(cellsDataList) < 1:
            return []
        result = [b"" for cell in cellsDataList[0]]
        for cellsData in cellsDataList:
            for i, data in enumerate(cellsData):
                result[i] += data
        return result

    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

    def _generateSizeValues(self, cellsData):
        result = []
        for data in cellsData:
            if len(data) > 0:
                result.append(len(data))  # Size in octets
            else:
                result.append(0)
        return result

    def _generateCRC32(self, cellsData):
        result = []
        for data in cellsData:
            valCrc32 = zlib.crc32(data) & 0xFFFFFFFF
            result.append(valCrc32)
        return result

    def _generateTigerCRC16(self, cellsData):
        result = []
        for data in cellsData:
            data = data + bytes([len(data)])
            valCrc32 = self.tiger_crc.bit_by_bit_fast(data)
            result.append(valCrc32)
        return result

    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)
Ejemplo n.º 17
0
 def __init__(self):
     self.tiger_crc = Crc(width=16, poly=0x1021, xor_in=0x0000, xor_out=0xFFFF, reflect_in=True, reflect_out=True)
     pass
Ejemplo n.º 18
0
#!/usr/bin/env python3

import time

from pyftdi.spi import SpiController
from pycrc.algorithms import Crc


# ---------------------------------------------------------------------------
# DSI utilities
# ---------------------------------------------------------------------------

EOTP = [ 0x08, 0x0f, 0x0f, 0x01 ]

DSI_CRC = Crc(width=16, poly=0x1021, xor_in=0xffff, xor_out=0x0000, reflect_in=True, reflect_out=True)


def parity(x):
	p = 0
	while x:
		p ^= x & 1
		x >>= 1
	return p

def dsi_header(data):
	cmd = (data[2] << 16) | (data[1] << 8) | data[0]
	ecc = 0
	if parity(cmd & 0b111100010010110010110111): ecc |= 0x01;
	if parity(cmd & 0b111100100101010101011011): ecc |= 0x02;
	if parity(cmd & 0b011101001001101001101101): ecc |= 0x04;
	if parity(cmd & 0b101110001110001110001110): ecc |= 0x08;
Ejemplo n.º 19
0
from liteeth.common import *
from litex.soc.cores.clock import *

from litex.soc.cores.uart import RS232PHYTX
from pycrc.algorithms import Crc

from litex.soc.interconnect.stream import AsyncFIFO

# calculate a 16bit CIRTT-CRC
FLIR_CRC = Crc(width=16,
               poly=0x1021,
               xor_in=0x0000,
               xor_out=0x0000,
               reflect_in=False,
               reflect_out=False)


def flirCRC(payload):
    crc = FLIR_CRC.bit_by_bit(bytes(payload))
    return [(crc >> 8) & 0xff, crc & 0xff]


# Assemble a FLIR packet
def flir_packet(func, args):
    header = [
        0x6e, 0x00, 0x00, func, (len(args) >> 8 & 0xff), (len(args) & 0xff)
    ]
    payload = header + flirCRC(header) + args
    return Array(payload + flirCRC(payload))

Ejemplo n.º 20
0
HEADERLENS[TYPE_REQLIC1] = 20
HEADERLENS[TYPE_HELLO] = 24
HEADERLENS[TYPE_STUBR] = 20
HEADERLENS[TYPE_REQLIC2] = 20
HEADERLENS[TYPE_STUB2] = 20
HEADERLENS[TYPE_RESP] = 24
PREFIXES = [0x2f, 0x4c, 0x4e]

# Protocol changed around version 11.10
VER_NEW = (11, 10)

CRCWIDTH = 14
CRCPOLY = 0x2e97
crc = Crc(width=CRCWIDTH,
          poly=CRCPOLY,
          reflect_in=True,
          xor_in=0,
          reflect_out=True,
          xor_out=0)


class _Client(object):
    """Base class for both server types"""
    def __init__(self, server, port=None):
        if port is None:
            port, server = server.split('@')
            port = int(port)

        self.server = server  # server hostname for TCP connections
        self.port = port  # server port number for TCP connections
        self.debug = False  # show raw binary sent and received
        self.verbose = False  # show parsed messages received