kitty.model.low_level.calculated module

Fields that are dependant on other fields - Size, Checksum etc.

class kitty.model.low_level.calculated.AbsoluteOffset(target_field, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=True, name=None)[source]

Bases: kitty.model.low_level.calculated.Offset

An absolute offset of a field from the beginning of the payload

__init__(target_field, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=True, name=None)[source]
Parameters:
  • target_field – (name of) field to calculate offset to
  • length – length of the AbsoluteOffset field (in bits)
  • correction – correction function, or value for the index, (default: divide by 8 (bytes))
  • encoder (BitFieldEncoder) – encoder for the field (default: ENC_INT_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container (default: None)
Example:
Container(fields=[
    String(name='A', value='base string'),
    String(name='B', value='bar'),
    String(name='C', value='target string'),
    AbsoluteOffset(
        target_field='C',
        length=32,
    )
])
class kitty.model.low_level.calculated.Calculated(depends_on, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]

Bases: kitty.model.low_level.field.BaseField

A base type for fields that are calculated based on other fields

FIELD_PROP_BASED = 'field property'
LENGTH_BASED = 'length'
VALUE_BASED = 'value'
__init__(depends_on, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • encoder (BitsEncoder) – encoder for the field
  • fuzzable – is container fuzzable
  • name – (unique) name of the container
hash()[source]
Return type:int
Returns:hash of the field
is_default()[source]

Checks if the field is in its default form

Returns:True if field is in default form
render(ctx=None)[source]

Render the current value into a bitstring.Bits object

Return type:bitstring.Bits
Returns:the rendered field
class kitty.model.low_level.calculated.CalculatedBits(depends_on, func, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]

Bases: kitty.model.low_level.calculated.Calculated

field that depends on the rendered value of a field, and rendered into Bits() object

__init__(depends_on, func, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=True, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • func – function for processing of the dependant data. func(Bits)->Bits
  • encoder (BitsEncoder) – encoder for the field
  • fuzzable – is container fuzzable
  • name – (unique) name of the container
class kitty.model.low_level.calculated.CalculatedInt(depends_on, bit_field, calc_func, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.Calculated

field that depends on the rendered value of another field and is rendered to (int, length, signed) tuple

__init__(depends_on, bit_field, calc_func, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • bit_field – a BitField to be used for holding the value
  • calc_func (func(bits) -> int) – function to calculate the value of the field
  • encoder (BitsEncoder) – encoder for the field (default: ENC_BITS_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container
reset()[source]
scan_for_field(field_name)[source]

If the field name is the internal field - return it

class kitty.model.low_level.calculated.CalculatedStr(depends_on, func, encoder=<kitty.model.low_level.encoder.StrEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.Calculated

field that depends on the rendered value of a byte-aligned field and rendered to a byte aligned Bits() object

__init__(depends_on, func, encoder=<kitty.model.low_level.encoder.StrEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • func – function for processing of the dependant data. func(str)->str
  • encoder (StrEncoder) – encoder for the field (default: ENC_STR_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container
class kitty.model.low_level.calculated.Checksum(depends_on, length, algorithm='crc32', encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.CalculatedInt

Checksum of another container.

__init__(depends_on, length, algorithm='crc32', encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field to be checksummed
  • length – length of the checksum field (in bits)
  • algorithm – checksum algorithm name (from Checksum._algos) or a function to calculate the value of the field. func(Bits) -> int
  • encoder (BitFieldEncoder) – encoder for the field (default: ENC_INT_DEFAULT)
  • fuzzable – is field fuzzable (default: False)
  • 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)
])
class kitty.model.low_level.calculated.Clone(depends_on, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.CalculatedBits

rendered the same as the field it depends on

__init__(depends_on, encoder=<kitty.model.low_level.encoder.BitsEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • encoder (BitsEncoder) – encoder for the field (default: ENC_BITS_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container
Example:
Container(name='empty HTML body', fields=[
    Static('<'),
    String(name='opening tag', value='body'),
    Static('>'),
    Static('</'),
    Clone(name='closing tag', depends_on='opening tag'),
    Static('>'),
])
class kitty.model.low_level.calculated.ElementCount(depends_on, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.FieldIntProperty

Number of elements inside another field. The value depends on the number of fields in the field it depends on.

Example:
Container(name='list with count', fields=[
    ElementCount(  # will be rendered to '3'
        name='element count',
        depends_on='list of items',
        length=32,
        encoder=ENC_INT_DEC
    ),
    Container(name='list of items', fields=[
        Static('element 1'),
        Static('element 2'),
        Static('element 3'),
    ])
])
class kitty.model.low_level.calculated.FieldIntProperty(depends_on, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.CalculatedInt

Calculate an int value based on some field property. The main difference from CalculatedInt is that it provides the field itself to the calculation function, not its rendered value.

__init__(depends_on, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field we depend on
  • length – length of the FieldIntProperty field (in bits)
  • correction – correction function, or value for the index
  • encoder (BitFieldEncoder) – encoder for the field (default: ENC_INT_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container (default: None)
class kitty.model.low_level.calculated.Hash(depends_on, algorithm, encoder=<kitty.model.low_level.encoder.StrEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.CalculatedStr

Hash of a field.

Note

To make it more convenient, there are multiple aliases for various hashes. Take a look at aliases.

__init__(depends_on, algorithm, encoder=<kitty.model.low_level.encoder.StrEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • depends_on – (name of) field to be hashed
  • algorithm – hash algorithm name (from Hash._algos) or a function to calculate the value of the field. func(str) -> str
  • encoder (StrEncoder) – encoder for the field (default: ENC_STR_DEFAULT)
  • fuzzable – is field fuzzable (default: False)
  • name – (unique) name of the field (default: None)
Example:
Container(name='SHA1 hashed string', fields=[
    Meta(String(name='secret', value='s3cr3t')),
    Hash(name='secret_hash', algorithm='sha1', depends_on='secret')
])
class kitty.model.low_level.calculated.IndexOf(depends_on, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.FieldIntProperty

Index of a field in its container.

Edge case behavior:

  • If field has no encloser - return 0
  • If field is not rendered - return len(rendered element list) as index/
Example:
Container(name='indexed list', fields=[
    IndexOf(  # will be rendered to '2'
        name='index of second',
        depends_on='second',
        length=32,
        encoder=ENC_INT_DEC
    ),
    Container(name='list of items', fields=[
        Static(name='first', value='A'),
        Static(name='second', value='B'),
        Static(name='third', value='C'),
    ])
])
class kitty.model.low_level.calculated.Offset(base_field, target_field, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=True, name=None)[source]

Bases: kitty.model.low_level.calculated.FieldIntProperty

A relative offset of a field from another field

__init__(base_field, target_field, length, correction=None, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=True, name=None)[source]
Parameters:
  • base_field – (name of) field to calculate offset from
  • target_field – (name of) field to calculate offset to
  • length – length of the Offset field (in bits)
  • correction – correction function, or value for the index, (default: divide by 8 (bytes))
  • encoder (BitFieldEncoder) – encoder for the field (default: ENC_INT_DEFAULT)
  • fuzzable – is container fuzzable
  • name – (unique) name of the container (default: None)
Examples:

Calculate the offset of field C from field B, in bits

Container(fields=[
    String(name='A', value='base string'),
    String(name='B', value='bar'),
    String(name='C', value='target string'),
    Offset(
        base_field='B',
        target_field='C',
        length=32,
        correction=lambda x: x,
    )
])

Calculate the absolute offset of field C from the beginning of the payload (also, see AbsoluteOffset)

Container(fields=[
    String(name='A', value='base string'),
    String(name='B', value='bar'),
    String(name='C', value='target string'),
    Offset(
        base_field=None,
        target_field='C',
        length=32,
    )
])
class kitty.model.low_level.calculated.Size(sized_field, length, calc_func=<function <lambda>>, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]

Bases: kitty.model.low_level.calculated.CalculatedInt

Size of another container. Calculated in each render call

Note

In most cases you can use the function SizeInBytes() instead, which receives the same arguments except of calc_func

__init__(sized_field, length, calc_func=<function <lambda>>, encoder=<kitty.model.low_level.encoder.BitFieldBinEncoder object>, fuzzable=False, name=None)[source]
Parameters:
  • sized_field – (name of) field to be sized
  • length – length of the size field (in bits)
  • calc_func – function to calculate the value of the field. func(bits) -> int (default: length in bytes)
  • encoder (BitFieldEncoder) – encoder for the field (default: ENC_INT_DEFAULT)
  • fuzzable – is field fuzzable (default: False)
  • 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
    )
])
kitty.model.low_level.calculated.num_bits_to_bytes(x)[source]