Beispiel #1
0
class Point(FixedObject):
    classID = 32
    _construct = Struct(
        "",
        Rename("x", field),
        Rename("y", field),
    )

    def __init__(self, x, y=None):
        if y is None: (x, y) = x
        self.x = x
        self.y = y

    @property
    def value(self):
        return (self.x, self.y)

    def __iter__(self):
        return iter(self.value)

    def __repr__(self):
        return 'Point(%r, %r)' % self.value

    def to_value(self):
        return Container(x=self.x, y=self.y)

    @classmethod
    def from_value(cls, value):
        return cls(value.x, value.y)
Beispiel #2
0
class Dictionary(Collection):
    classID = 24
    _construct = Struct("dictionary",
                        UBInt32("length"),
                        MetaRepeater(lambda ctx: ctx.length, Struct("items",
                                                                    Rename(
                                                                        "key", field),
                                                                    Rename(
                                                                        "value", field),
                                                                    )),
                        )

    def __init__(self, value=None):
        if value == None:
            value = {}
        Collection.__init__(self, value)

    def to_value(self):
        items = [Container(key=key, value=value)
                 for (key, value) in dict(self.value).items()]
        return Container(items=items, length=len(items))

    @classmethod
    def from_value(cls, obj):
        value = dict([(item.key, item.value) for item in obj.items])
        return cls(value)

    def __getattr__(self, name):
        if name.startswith('__') and name.endswith('__'):
            return super(Dictionary, self).__getattr__(name)
        return getattr(self.value, name)

    def copy(self):
        return self.__class__(self.value.copy())
Beispiel #3
0
class Collection(FixedObjectWithRepeater, ContainsRefs):
    _construct = Struct(
        "",
        UBInt32("length"),
        MetaRepeater(lambda ctx: ctx.length, Rename("items", field)),
    )

    def __init__(self, value=None):
        if value == None:
            value = []
        FixedObject.__init__(self, value)

    def __iter__(self):
        return iter(self.value)

    def __getattr__(self, name):
        if name in ('append', 'count', 'extend', 'index', 'insert', 'pop',
                    'remove', 'reverse', 'sort'):
            return getattr(self.value, name)
        return super(Collection, self).__getattr__(name)

    def __getitem__(self, index):
        return self.value[index]

    def __setitem__(self, index, value):
        self.value[index] = value

    def __delitem__(self, index):
        del self.value[index]

    def __len__(self):
        return len(self.value)

    def copy(self):
        return self.__class__(list(self.value.copy))
Beispiel #4
0
class ColorForm(Form):
    """A rectangular array of pixels, used for holding images.
    width, height - dimensions
    depth - how many bits are used to specify the color at each pixel.
    bits - a Bitmap with varying internal structure, depending on depth.
    colors - the colors pointed to by the bits array. (I think?)
    privateOffset - ?
    """
    classID = 35
    _construct = Struct("",
                        Embed(Form._construct),
                        Rename("colors", field),  # Array
                        )
Beispiel #5
0
class Form(FixedObject, ContainsRefs):
    """A rectangular array of pixels, used for holding images.
    Attributes:
        width, height - dimensions
        depth - how many bits are used to specify the color at each pixel.
        bits - a Bitmap with varying internal structure, depending on depth.
        privateOffset - ?

    Note: do not modify the dict returned from the .value property.
    """

    classID = 34
    _construct = Struct(
        "form",
        Rename("width", field),
        Rename("height", field),
        Rename("depth", field),
        Rename("privateOffset", field),
        Rename("bits", field),  # Bitmap
    )

    def __init__(self, **fields):
        self.width = 0
        self.height = 0
        self.depth = None
        self.privateOffset = None
        self.bits = Bitmap("")
        self.colors = None

        self.__dict__.update(fields)

    @property
    def value(self):
        return dict((k, getattr(self, k)) for k in self.__dict__
                    if not k.startswith("_"))

    def to_value(self):
        return Container(**self.value)

    @classmethod
    def from_value(cls, value):
        return cls(**dict(value))

    def copy(self):
        return self.__class__.from_value(self.to_value())

    def __repr__(self):
        return "<%s(%ix%i)>" % (
            self.__class__.__name__,
            self.width,
            self.height,
        )

    def built(self):
        if isinstance(self.bits, ByteArray):
            self.bits = Bitmap.from_byte_array(self.bits.value)
        assert isinstance(self.bits, Bitmap)

    def to_array(self):
        pixel_bytes = bytearray(self.bits.value)

        if self.depth == 32:
            argb_array = pixel_bytes

        elif self.depth <= 8:
            wide_argb_array = bytearray(len(pixel_bytes) * 4)

            num_colors = 2**self.depth
            if self.colors:
                colors = [color.to_argb_array() for color in self.colors]
                colors += [None] * (num_colors - len(colors))
            else:
                colors = default_colormap()[0:num_colors]
            assert len(colors) == num_colors

            # Precompute pixel colors for each byte.
            # This is way faster than doing different bit-shifting ops to get
            # each pixel depending on depth.

            multicolors = itertools.product(colors, repeat=8 // self.depth)
            multicolors = [
                bytearray(b'').join(multicolor) for multicolor in multicolors
            ]

            wide_argb_array = bytearray(b'').join(
                operator.itemgetter(*pixel_bytes)(multicolors))

            # Rows are rounded to be a whole number of words (32 bits) long.
            # Presumably this is because Bitmaps are compressed (run-length
            # encoded) in 32-bit segments.
            pixels_per_word = 32 // self.depth
            pixels_in_last_word = self.width % pixels_per_word
            skip = (pixels_per_word - pixels_in_last_word) % pixels_per_word

            out_rowlen = self.width * 4
            in_rowlen = out_rowlen + skip * 4
            row_indexes = xrange(0, len(wide_argb_array), in_rowlen)
            argb_array = bytearray(b'').join(wide_argb_array[i:i + out_rowlen]
                                             for i in row_indexes)
        else:
            raise NotImplementedError  # TODO: depth 16

        size = (self.width, self.height)
        return PIL.Image.frombuffer("RGBA", size, buffer(argb_array), "raw",
                                    "ARGB", 0, 1)

    @classmethod
    def from_string(cls, width, height, rgba_string):
        """Returns a Form with 32-bit RGBA pixels
        Accepts string containing raw RGBA color values
        """
        # Convert RGBA string to ARGB
        raw = ""
        for i in range(0, len(rgba_string), 4):
            raw += rgba_string[i + 3]  # alpha
            raw += rgba_string[i:i + 3]  # rgb

        assert len(rgba_string) == width * height * 4

        return Form(
            width=width,
            height=height,
            depth=32,
            bits=Bitmap(raw),
        )
Beispiel #6
0
layer3_payload = Switch(
    "next", lambda ctx: ctx["header"].protocol, {"TCP": layer4_tcp, "UDP": layer4_udp}, default=Pass
)

layer3_ipv4 = Struct("layer3_ipv4", Rename("header", ipv4_header), layer3_payload)

layer3_ipv6 = Struct("layer3_ipv6", Rename("header", ipv6_header), layer3_payload)

layer2_ethernet = Struct(
    "layer2_ethernet",
    Rename("header", ethernet_header),
    Switch("next", lambda ctx: ctx["header"].type, {"IPv4": layer3_ipv4, "IPv6": layer3_ipv6}, default=Pass),
)

ip_stack = Rename("ip_stack", layer2_ethernet)


if __name__ == "__main__":
    cap1 = unhexlify(
        six.b(
            "0011508c283c001150886b570800450001e971474000800684e4c0a80202525eedda11"
            "2a0050d98ec61d54fe977d501844705dcc0000474554202f20485454502f312e310d0a"
            "486f73743a207777772e707974686f6e2e6f72670d0a557365722d4167656e743a204d"
            "6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420"
            "352e313b20656e2d55533b2072763a312e382e302e3129204765636b6f2f3230303630"
            "3131312046697265666f782f312e352e302e310d0a4163636570743a20746578742f78"
            "6d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d"
            "6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d"
            "302e382c696d6167652f706e672c2a2f2a3b713d302e350d0a4163636570742d4c616e"
            "67756167653a20656e2d75732c656e3b713d302e350d0a4163636570742d456e636f64"
Beispiel #7
0
def greedy_string(name):
  """
  Variable-length string field.
  """
  return Rename(name, StringAdapter(OptionalGreedyRange(Field(None, 1))))
Beispiel #8
0
"""
TCP/IP Protocol Stack
Note: before parsing the application layer over a TCP stream, you must
first combine all the TCP frames into a stream. See utils.tcpip for
some solutions
"""
from construct import Struct, Rename, HexDumpAdapter, Field, Switch, Pass
from construct.protocols.layer2.ethernet import ethernet_header
from construct.protocols.layer3.ipv4 import ipv4_header
from construct.protocols.layer3.ipv6 import ipv6_header
from construct.protocols.layer4.tcp import tcp_header
from construct.protocols.layer4.udp import udp_header

layer4_tcp = Struct(
    "layer4_tcp",
    Rename("header", tcp_header),
    HexDumpAdapter(
        Field(
            "next", lambda ctx: ctx["_"]["header"].payload_length - ctx[
                "header"].header_length)),
)

layer4_udp = Struct(
    "layer4_udp",
    Rename("header", udp_header),
    HexDumpAdapter(Field("next", lambda ctx: ctx["header"].payload_length)),
)

layer3_payload = Switch("next",
                        lambda ctx: ctx["header"].protocol, {
                            "TCP": layer4_tcp,
Beispiel #9
0
CELL_MEASURE_REPORT = Struct("cell_measure_report", UBInt8("type"),
                             UBInt8("version"), Bytes("enbid", 8),
                             UBInt16("cellid"), UBInt32("xid"),
                             BitStruct("flags", Padding(15), Bit("dir")),
                             UBInt32("seq"), UBInt16("length"),
                             UBInt16("action"), UBInt32("interval"),
                             UBInt8("opcode"))

CELL_MEASURE_REQUEST = Struct("cell_measure_request", UBInt8("type"),
                              UBInt8("version"), Bytes("enbid", 8),
                              UBInt16("cellid"), UBInt32("xid"),
                              BitStruct("flags", Padding(15), Bit("dir")),
                              UBInt32("seq"), UBInt16("length"),
                              UBInt16("action"), UBInt8("opcode"),
                              UBInt32("interval"),
                              Rename("options", OptionalGreedyRange(OPTIONS)))

CELL_MEASURE_RESPONSE = Struct("cell_measure_response",
                               Rename("options", OptionalGreedyRange(OPTIONS)))

MAC_PRBS_REQUEST = Struct("mac_prbs_request")

MAC_PRBS_REPORT = Struct("mac_prbs_report", UBInt8("dl_prbs_total"),
                         UBInt32("dl_prbs_used"), UBInt8("ul_prbs_total"),
                         UBInt32("ul_prbs_used"))

EP_MAC_PRBS_REQUEST = 0x0101
EP_MAC_PRBS_REPORT = 0x0102

CELL_MEASURE_TYPES = {EP_MAC_PRBS_REPORT: MAC_PRBS_REPORT}
Beispiel #10
0
TODO tests
"""
from construct import (ULint8, ULint16, Array, Struct, BitStruct, BitField,
                       Byte, SLInt16, Padding, Rename)

u16 = ULint16
s16 = SLInt16
u8 = ULint8

AccelerometerData = Struct("AccelerometerData", s16("x_accel"), s16("y_accel"),
                           s16("z_accel"))

Dummy24Bits = BitStruct("s24", BitField("value", 24))

GyroscopeData = Struct("AccelerometerData", Rename("roll", Dummy24Bits),
                       Rename("yaw", Dummy24Bits),
                       Rename("pitch", Dummy24Bits))

MagnetData = Struct("MagnetData", Array(6, Byte("unknown")))

### Some notes on the Point field usage
## Touchscreen Pressure
# Stored as a 12 bit integer in the extra data of the first two points. It is
# not yet known how to translate this value to a usable pressure value -
# currently it is assumed to be a resistance value reading.
## UIC firmware version
# 16 bit integer stored in the extra data of points 6 to 8 (only one bit of the
# first coordinate of point 6 is used).
Point = Struct(
    "Point",
Beispiel #11
0
    Rename("header", ipv6_header),
    layer3_payload,
)

layer2_ethernet = Struct("layer2_ethernet",
    Rename("header", ethernet_header),
    Switch("next", lambda ctx: ctx["header"].type,
        {
            "IPv4" : layer3_ipv4,
            "IPv6" : layer3_ipv6,
        },
        default = Pass,
    )
)

ip_stack = Rename("ip_stack", layer2_ethernet)


if __name__ == "__main__":
    cap1 = (
    "0011508c283c001150886b570800450001e971474000800684e4c0a80202525eedda11"
    "2a0050d98ec61d54fe977d501844705dcc0000474554202f20485454502f312e310d0a"
    "486f73743a207777772e707974686f6e2e6f72670d0a557365722d4167656e743a204d"
    "6f7a696c6c612f352e30202857696e646f77733b20553b2057696e646f7773204e5420"
    "352e313b20656e2d55533b2072763a312e382e302e3129204765636b6f2f3230303630"
    "3131312046697265666f782f312e352e302e310d0a4163636570743a20746578742f78"
    "6d6c2c6170706c69636174696f6e2f786d6c2c6170706c69636174696f6e2f7868746d"
    "6c2b786d6c2c746578742f68746d6c3b713d302e392c746578742f706c61696e3b713d"
    "302e382c696d6167652f706e672c2a2f2a3b713d302e350d0a4163636570742d4c616e"
    "67756167653a20656e2d75732c656e3b713d302e350d0a4163636570742d456e636f64"
    "696e673a20677a69702c6465666c6174650d0a4163636570742d436861727365743a20"
Beispiel #12
0
E_SINGLE = Struct("e_single", UBInt16("action"), UBInt8("opcode"))

E_TRIG = Struct("e_trig", UBInt16("action"), UBInt8("opcode"))

HELLO = Struct("hello", UBInt32("padding"))

CAPS_REQUEST = Struct("caps_request", UBInt8("type"), UBInt8("version"),
                      Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"),
                      BitStruct("flags", Padding(15), Bit("dir")),
                      UBInt32("seq"), UBInt16("length"), UBInt16("action"),
                      UBInt8("opcode"), UBInt32("dummy"))

CAPS_RESPONSE = Struct(
    "caps_response",
    BitStruct("flags", Padding(29), Bit("handover"), Bit("ue_measure"),
              Bit("ue_report")), Rename("options",
                                        OptionalGreedyRange(OPTIONS)))

RAN_MAC_SLICE_REQUEST = Struct("ran_mac_slice_request", UBInt8("type"),
                               UBInt8("version"), Bytes("enbid", 8),
                               UBInt16("cellid"), UBInt32("xid"),
                               BitStruct("flags", Padding(15), Bit("dir")),
                               UBInt32("seq"), UBInt16("length"),
                               UBInt16("action"), UBInt8("opcode"),
                               Bytes("plmn_id", 4), UBInt8("dscp"),
                               Bytes("padding", 3))

SET_RAN_MAC_SLICE_REQUEST = Struct(
    "set_ran_mac_slice_request", UBInt8("type"), UBInt8("version"),
    Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"),
    BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"),
    UBInt16("length"), UBInt16("action"), UBInt8("opcode"),
Beispiel #13
0
ASSOC_RESPONSE = Struct("assoc_response", UBInt8("version"), UBInt8("type"),
                        UBInt32("length"), UBInt32("seq"), Bytes("sta", 6))

NETWORKS = Struct("networks", Bytes("bssid", 6),
                  Bytes("ssid", WIFI_NWID_MAXSIZE + 1))

ADD_LVAP = Struct(
    "add_lvap", UBInt8("version"), UBInt8("type"), UBInt32("length"),
    UBInt32("seq"), UBInt32("module_id"),
    BitStruct("flags", Padding(13), Bit("set_mask"), Bit("associated"),
              Bit("authenticated")), UBInt16("assoc_id"), Bytes("hwaddr", 6),
    UBInt8("channel"), UBInt8("band"), UBInt8("supported_band"),
    Bytes("sta", 6), Bytes("encap", 6), Bytes("bssid", 6),
    Bytes("ssid", WIFI_NWID_MAXSIZE + 1),
    Rename("networks", OptionalGreedyRange(NETWORKS)))

DEL_LVAP = Struct("del_lvap", UBInt8("version"), UBInt8("type"),
                  UBInt32("length"), UBInt32("seq"), UBInt32("module_id"),
                  Bytes("sta", 6), UBInt8("csa_switch_mode"),
                  UBInt8("csa_switch_count"), UBInt8("csa_switch_channel"))

STATUS_LVAP = Struct(
    "status_lvap", UBInt8("version"), UBInt8("type"), UBInt32("length"),
    UBInt32("seq"),
    BitStruct("flags", Padding(13), Bit("set_mask"), Bit("associated"),
              Bit("authenticated")), UBInt16("assoc_id"), Bytes("wtp", 6),
    Bytes("sta", 6), Bytes("encap", 6), Bytes("hwaddr", 6), UBInt8("channel"),
    UBInt8("band"), UBInt8("supported_band"), Bytes("bssid", 6),
    Bytes("ssid", WIFI_NWID_MAXSIZE + 1),
    Rename("networks", OptionalGreedyRange(NETWORKS)))