Complex types

ByteStruct

digraph inheritance6782c667a1 { rankdir=LR; size="8.0, 12.0"; "oser.core.ByteStruct" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.OrderedMembersMixin" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.FuzzingStructMixin" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.OserNode" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.FuzzingStructMixin" [URL="fuzzing.html#oser.core.FuzzingStructMixin",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",target="_top",tooltip="A struct mixin for fuzzing tests."]; "oser.core.OrderedMembersMixin" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.OserNode" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; }
class oser.ByteStruct(*args, **kwargs)
byte_size()

Return the size in bytes.

Returns:the length of the byte type in bytes.
Return type:int
decode(data, full_data='', context_data='')

Decode a binary string and return the number of bytes that were decoded.

Parameters:
  • data (bytes) – the data buffer that is decoded.
  • full_data (bytes) – the binary data string until the part to be decoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
Returns:

the number of bytes that were decoded.

Return type:

int

encode(full_data='', context_data='')

Return the encoded binary string.

Parameters:
  • full_data (bytes) – the binary data string until the part to be encoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
fuzzing_iterator(copy=False)

The fuzzing iterator iterates over all combinations of set fuzzing values (oser.ByteType.set_fuzzing_values()). If no fuzzing values are set the current struct is yielded.

Parameters:copy=False (bool) – if set to True the generated fuzzing values are deep copies of the original. Creating these deep copies is slow. If set to False the original struct is retruned and the generated value must be used immediately since the next generated overwrites the values on the same value.
Yields:the fuzzing combinations.
root()

return root element

size()

Return the size in bytes.

Returns:the length of the byte type in bytes.
Return type:int
up()

return parent element

Usage:

>>> from oser import ByteStruct
>>> from oser import UBInt8, UBInt16, UBInt32
>>> from oser import to_hex

>>> class Data(ByteStruct):
...     def __init__(self):
...         super(Data, self).__init__()
...
...         self.a = UBInt8(1)
...         self.b = UBInt16(1000)
...         self.c = UBInt32(1000000)

>>> instance = Data()
>>> print(instance)
Data():
    a: 1 (UBInt8)
    b: 1000 (UBInt16)
    c: 1000000 (UBInt32)

>>> print(instance.introspect())
   -    -  Data():
   0 \x01      a: 1 (UBInt8)
   1 \x03      b: 1000 (UBInt16)
   2 \xe8
   3 \x00      c: 1000000 (UBInt32)
   4 \x0f
   5 \x42
   6 \x40

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0|  1|  2|  3|  4|  5|  6
\x01\x03\xE8\x00\x0F\x42\x40
>>> bytesDecoded = instance.decode(binary)
>>> print(bytesDecoded)
7
>>> print(instance)
Data():
    a: 1 (UBInt8)
    b: 1000 (UBInt16)
    c: 1000000 (UBInt32)

BitStruct

oser.BitStruct is like a oser.ByteStruct for bit-aligned types.

Note: The result of oser.OserNode.encode() is byte-aligned. If the amount of bits is not a multiple of 8 the last bits are filled with don’t care values.

digraph inheritance3ffaa7b6bc { rankdir=LR; size="8.0, 12.0"; "oser.core.BitStruct" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.ByteStruct" -> "oser.core.BitStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.ByteStruct" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.OrderedMembersMixin" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.FuzzingStructMixin" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.OserNode" -> "oser.core.ByteStruct" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.FuzzingStructMixin" [URL="fuzzing.html#oser.core.FuzzingStructMixin",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",target="_top",tooltip="A struct mixin for fuzzing tests."]; "oser.core.OrderedMembersMixin" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.OserNode" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; }
class oser.BitStruct(*args, **kwargs)
decode(data, full_data='', context_data='')

Decode a binary string and return the number of bytes that were decoded.

Parameters:
  • data (bytes) – the data buffer that is decoded.
  • full_data (bytes) – the binary data string until the part to be decoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
encode(full_data='', context_data='')

Return the encoded binary string.

Parameters:
  • full_data (bytes) – the binary data string until the part to be encoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
fuzzing_iterator(copy=False)

The fuzzing iterator iterates over all combinations of set fuzzing values (oser.ByteType.set_fuzzing_values()). If no fuzzing values are set the current struct is yielded.

Parameters:copy=False (bool) – if set to True the generated fuzzing values are deep copies of the original. Creating these deep copies is slow. If set to False the original struct is retruned and the generated value must be used immediately since the next generated overwrites the values on the same value.
Yields:the fuzzing combinations.
root()

return root element

size()

Return the size in bits.

Returns:the length of the bit type in bits.
Return type:int
up()

return parent element

Usage:

>>> from oser import BitStruct
>>> from oser import Flag, Nibble, BitField
>>> from oser import to_hex
>>>
>>> class Data(BitStruct):
...     def __init__(self):
...         super(Data, self).__init__()
...
...         self.a = Flag(1)
...         self.b = Nibble(5)
...         self.c = BitField(value=57, length=6)
...
>>> instance = Data()
>>> print(instance)
Data():
    a: 1 (Flag)
    b: 5 (Nibble)
    c: 57 (BitField(6))

>>> print(instance.introspect())
   -    -  Data():
   0.7  1      a: 1 (Flag)
   0.6  0      b: 5 (Nibble)
   0.5  1
   0.4  0
   0.3  1
   0.2  1      c: 57 (BitField(6))
   0.1  1
   0.0  1
   1.7  0
   1.6  0
   1.5  1
   1.4  x
   1.3  x
   1.2  x
   1.1  x
   1.0  x

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0|  1
\xAF\x20
>>> bytesDecoded = instance.decode(binary)
>>> print(bytesDecoded)
2
>>> print(instance)
Data():
    a: 1 (Flag)
    b: 5 (Nibble)
    c: 57 (BitField(6))

Enum

An oser.Enum is most commonly used to give values human readable names. It can be used in bit-aligned context and byte-aligned context.

digraph inheritance74c13c0fbf { rankdir=LR; size="8.0, 12.0"; "oser._enum.Enum" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",tooltip="An enumeration serializer."]; "oser.core.ByteType" -> "oser._enum.Enum" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.ArithmeticEmulationMixin" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.core.ByteType" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",tooltip="A ``ByteType`` is an abstract class for byte types."]; "oser.core.FuzzingTypeMixin" -> "oser.core.ByteType" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.ArithmeticEmulationMixin" -> "oser.core.ByteType" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.OserNode" -> "oser.core.ByteType" [arrowsize=0.5,style="setlinewidth(0.5)"]; "oser.core.FuzzingTypeMixin" [URL="fuzzing.html#oser.core.FuzzingTypeMixin",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",target="_top",tooltip="A type mixin for fuzzing tests."]; "oser.core.OserNode" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)"]; "oser.enum.Enum" [fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5)",tooltip="An enumeration serializer."]; "oser._enum.Enum" -> "oser.enum.Enum" [arrowsize=0.5,style="setlinewidth(0.5)"]; }
class oser.Enum(prototype, values, value=None, strict=False)

An enumeration serializer.

Parameters:
  • prototype (class) – the class of the underlying data type.
  • values (dict) – a dictionary of key-value-pairs. The keys are translated into binary data represented by the values.
  • value=None (object) – the initial value.
  • strict=False (bool) – If set to True only keys and values appearing in values are accepted. Else all values are accepted.
byte_size()

Return the size in bytes.

decode(data, full_data='', context_data='')

Decode a binary string and return the number of bytes that were decoded.

Parameters:
  • data (bytes) – the data buffer that is decoded.
  • full_data (bytes) – the binary data string until the part to be decoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
Returns:

the number of bytes that were decoded.

Return type:

int

encode(full_data='', context_data='')

Return the encoded binary string.

Parameters:
  • full_data (bytes) – the binary data string until the part to be encoded. The user normally does not need to supply this.
  • context_data (bytes) – the binary data of the current context. The user normally does not need to supply this.
Returns:

the encoded binary string.

Return type:

bytes

get()

Return the value as string representation if possible of the raw value else.

Returns:the value as string or raw
Return type:object
get_value()

Return the raw value.

Returns:the raw value.
Return type:object
introspect(stop_at=None)

Return the introspection representation of the object as a string.

root()

return root element

set(value)

Set the value.

Parameters:value – the new value
set_fuzzing_values(values)

Set fuzzing values.

Parameters:values (iterable) – the values used for fuzzing.
size()

Return the size in bytes.

up()

Return the parent element.

Usage in byte context:

>>> from oser import ByteStruct
>>> from oser import Enum
>>> from oser import UBInt16
>>> from oser import to_hex
>>>
>>> class Data(ByteStruct):
...         def __init__(self):
...             super(Data, self).__init__()
...             self.enum = Enum(prototype=UBInt16,
...                              values={
...                                  "value1"    :    1,
...                                  "value22"   :   22,
...                                  "value333"  :  333,
...                                  "value4444" : 4444,
...                              }, value="value22")
...
>>> instance = Data()
>>> print(instance)
Data():
    enum: 'value22' (UBInt16)

>>> print(instance.introspect())
   -    -  Data():
   0 \x00      enum: 22 (UBInt16)
   1 \x16

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0|  1
\x00\x16
>>>
>>> instance.enum.set("value1")
>>> print(instance)
Data():
    enum: 'value1' (UBInt16)

>>> print(instance.introspect())
   -    -  Data():
   0 \x00      enum: 1 (UBInt16)
   1 \x01

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0|  1
\x00\x01
>>> bytesDecoded = instance.decode(binary)
>>> print(bytesDecoded)
2
>>> print(instance)
Data():
    enum: 'value1' (UBInt16)

>>>
>>> instance.decode("\x01\x4D")
2
>>> print(instance)
Data():
    enum: 'value333' (UBInt16)

>>> print(instance.introspect())
   -    -  Data():
   0 \x01      enum: 333 (UBInt16)
   1 \x4d

Usage in bit context:

>>> from oser import BitStruct
>>> from oser import Enum
>>> from oser import Flag
>>> from oser import to_hex
>>>
>>> class Data(BitStruct):
...         def __init__(self):
...             super(Data, self).__init__()
...             self.enum = Enum(prototype=Flag,
...                              values={
...                                  "false" : 0,
...                                  "true" : 1,
...                              }, value="true")
...
>>> instance = Data()
>>> print(instance)
Data():
    enum: 'true' (Flag)

>>> print(instance.introspect())
   -    -  Data():
   0.7  1      enum: 1 (Flag)
   0.6  x
   0.5  x
   0.4  x
   0.3  x
   0.2  x
   0.1  x
   0.0  x

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0
\x80
>>>
>>> instance.enum.set("false")
>>> print(instance)
Data():
    enum: 'false' (Flag)

>>> print(instance.introspect())
   -    -  Data():
   0.7  0      enum: 0 (Flag)
   0.6  x
   0.5  x
   0.4  x
   0.3  x
   0.2  x
   0.1  x
   0.0  x

>>> binary = instance.encode()
>>> print(to_hex(binary))
   0
\x00
>>> bytesDecoded = instance.decode(binary)
>>> print(bytesDecoded)
1
>>> print(instance)
Data():
    enum: 'false' (Flag)

>>>
>>> instance.decode("\x80")
1
>>> print(instance)
Data():
    enum: 'true' (Flag)

>>> print(instance.introspect())
   -    -  Data():
   0.7  1      enum: 1 (Flag)
   0.6  x
   0.5  x
   0.4  x
   0.3  x
   0.2  x
   0.1  x
   0.0  x