def __init__(self, depends_on, length, correction=None, encoder=ENC_INT_DEFAULT, fuzzable=False, name=None): ''' :param depends_on: (name of) field we depend on :param length: length of the FieldIntProperty field (in bits) :type corrention: int or func(int) -> int :param correction: correction function, or value for the index :type encoder: :class:`~kitty.model.low_level.encoder.BitFieldEncoder` :param encoder: encoder for the field (default: ENC_INT_DEFAULT) :param fuzzable: is container fuzzable :param name: (unique) name of the container (default: None) ''' if correction: if not callable(correction): if not isinstance(correction, int): raise KittyException( 'correction must be int, function or None!') self._correction = correction bit_field = BitField(value=0, length=length, encoder=encoder) super(FieldIntProperty, self).__init__(depends_on=depends_on, bit_field=bit_field, calc_func=None, fuzzable=fuzzable, name=name) self.dependency_type = Calculated.FIELD_PROP_BASED
def __init__(self, name): ''' :param name: name of the template ''' val = PseudoTemplate._counter_ PseudoTemplate._counter_ += 2 val = val * 123 field = Meta(fields=BitField(value=val, length=32)) super(PseudoTemplate, self).__init__(name=name, fuzzable=False, fields=field)
def __init__(self, sized_field, length, calc_func=lambda x: len(x) // 8, encoder=ENC_INT_DEFAULT, fuzzable=False, name=None): ''' :param sized_field: (name of) field to be sized :param length: length of the size field (in bits) :param calc_func: function to calculate the value of the field. func(bits) -> int (default: length in bytes) :type encoder: :class:`~kitty.model.low_level.encoder.BitFieldEncoder` :param encoder: encoder for the field (default: ENC_INT_DEFAULT) :param fuzzable: is field fuzzable (default: False) :param name: (unique) name of the field (default: None) :examples: Calculate the size of a field/container in bits :: Container(name='sized chunk', fields=[ RandomBytes(name='chunk', value='1234', min_length=0, max_length=75), Size( name='size in bits', sized_field='chunk', length=32, calc_func=lambda x: len(x) ) ]) Calculate the size of a field/container in bytes, and add 5 to the result :: Container(name='sized chunk', fields=[ RandomBytes(name='chunk', value='1234', min_length=0, max_length=75), Size( name='size in bytes plus 5', sized_field='chunk', length=32, calc_func=lambda x: len(x) // 8 + 5 ) ]) ''' bit_field = BitField(value=0, length=length, encoder=encoder) super(Size, self).__init__(depends_on=sized_field, bit_field=bit_field, calc_func=calc_func, fuzzable=fuzzable, name=name) self.dependency_type = Calculated.LENGTH_BASED self._need_second_pass = True
def UInt8(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None): return BitField(value, 8, signed=False, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name)
def SInt64(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None): return BitField(value, 64, signed=True, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name)
def SInt32(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None): '''Signed 32-bit field''' return BitField(value, 32, signed=True, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name)
def UInt64(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None): '''Unsigned 64-bit field''' return BitField(value, 64, signed=False, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name)
def __init__(self, depends_on, length, algorithm='crc32', encoder=ENC_INT_DEFAULT, fuzzable=False, name=None): ''' :param depends_on: (name of) field to be checksummed :param length: length of the checksum field (in bits) :param algorithm: checksum algorithm name (from Checksum._algos) or a function to calculate the value of the field. func(Bits) -> int :type encoder: :class:`~kitty.model.low_level.encoder.BitFieldEncoder` :param encoder: encoder for the field (default: ENC_INT_DEFAULT) :param fuzzable: is field fuzzable (default: False) :param name: (unique) name of the field (default: None) :example: :: Container(name='checksummed chunk', fields=[ RandomBytes(name='chunk', value='1234', min_length=0, max_length=75), Checksum(name='CRC', depends_on='chunk', length=32) ]) ''' if algorithm in Checksum._algos: func = Checksum._algos[algorithm] else: try: res = algorithm(empty_bits) kassert.is_of_types(res, int) func = algorithm except: raise KittyException( 'algorithm should be a func(str)->int or one of the strings %s' % (Checksum._algos.keys(), )) def calc_func(x): return func(x.bytes) & 0xffffffff bit_field = BitField(value=0, length=length, encoder=encoder) super(Checksum, self).__init__(depends_on=depends_on, bit_field=bit_field, calc_func=calc_func, fuzzable=fuzzable, name=name)
def SInt64(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None, full_range=False): '''Signed 64-bit field''' return BitField(value, 64, signed=True, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name, full_range=full_range)
def UInt32(value, min_value=None, max_value=None, encoder=ENC_INT_DEFAULT, fuzzable=True, name=None, full_range=False): '''Unsigned 32-bit field''' return BitField(value, 32, signed=False, min_value=min_value, max_value=max_value, encoder=encoder, fuzzable=fuzzable, name=name, full_range=full_range)
def testDefaultValueWhenNotMutated(self): ''' Check that the default value, before mutation, is as the expected data ''' expected_data = 'Th3 L33ter ' uut = Template( name='uut', fields=[ String('Th'), BitField(value=3, length=20, encoder=ENC_INT_DEC), Static(' '), Container( name='leeter ', fields=[ Dynamic(key='hmm', default_value='L3'), String('\xde\xd7\xab', encoder=ENC_STR_BASE64_NO_NL), # 3ter RandomBytes(' ', min_length=1, max_length=100) ]) ]) self.assertEqual(uut.render().tobytes(), expected_data) uut.mutate() uut.reset() self.assertEqual(uut.render().tobytes(), expected_data)
def __init__(self, sized_field, length, calc_func=lambda x: len(x) / 8, encoder=ENC_INT_DEFAULT, fuzzable=False, name=None): ''' :param sized_field: (name of) field to be sized :param length: length of the size field (in bits) :param calc_func: function to calculate the value of the field. func(bits) -> int (default: length in bytes) :type encoder: :class:`~kitty.model.low_levele.encoder.BitFieldEncoder` :param encoder: encoder for the field (default: ENC_INT_DEFAULT) :param fuzzable: is field fuzzable (default: False) :param name: (unique) name of the field (default: None) ''' bit_field = BitField(value=0, length=length, encoder=encoder) super(Size, self).__init__(depends_on=sized_field, bit_field=bit_field, calc_func=calc_func, fuzzable=fuzzable, name=name) self.dependency_type = Calculated.LENGTH_BASED self._need_second_pass = True