Exemplo n.º 1
0
    def parse(s: BytesIO, flags: int) -> CacheBitmap:
        self = CacheBitmapV3(3)

        self.cacheId = flags & 0x00000003
        self.flags = (flags & 0x0000FF80) >> 7
        bitsPerPixelId = (flags & 0x00000078) >> 3

        # The spec says this should never be 0, but it is...
        self.bpp = CBR23_BPP[bitsPerPixelId]

        self.cacheIndex = Uint16LE.unpack(s)
        self.key1 = Uint32LE.unpack(s)
        self.key2 = Uint32LE.unpack(s)
        self.bpp = Uint8.unpack(s)

        compressed = Uint8.unpack(s)
        s.read(1)  # Reserved (1 bytes)

        self.codecId = Uint8.unpack(s)
        self.width = Uint16LE.unpack(s)
        self.height = Uint16LE.unpack(s)
        dataLen = Uint32LE.unpack(s)

        if compressed:  # TS_COMPRESSED_BITMAP_HEADER_EX present.
            s.read(24)  # Non-essential.

        self.data = s.read(dataLen)

        return self
Exemplo n.º 2
0
    def parse(s: BytesIO, flags: int, glyph: GlyphSupport) -> 'CacheGlyph':
        """
        Parse a CACHE_GLYPH order.

        :param s: The byte stream to parse
        :param flags: The UPDATE PDU controlFlags
        :param glyph: One of Glyph or GlyphV2 classes to select the parsing strategy
        """

        self = CacheGlyph()

        if GlyphSupport.GLYPH_SUPPORT_ENCODE:
            self.cacheId = flags & 0x0F
            cGlyphs = flags >> 8
            unicodePresent = (flags >> 4 & 0x0F) & 0x01
            self.glyphs = [GlyphV2.parse(s) for _ in range(cGlyphs)]
        else:
            self.cacheId = Uint8.unpack(s)
            cGlyphs = Uint8.unpack(s)
            unicodePresent = flags & CG_GLYPH_UNICODE_PRESENT
            self.glyphs = [Glyph.parse(s) for _ in range(cGlyphs)]

        if unicodePresent and cGlyphs > 0:
            self.unicode = read_utf16_str(s, cGlyphs)

        return self
Exemplo n.º 3
0
    def update(self, s: BytesIO):

        if self.ctx.field(1):
            self.nLeftRect = read_coord(s, self.ctx.deltaCoords,
                                        self.nLeftRect)
        if self.ctx.field(2):
            self.nTopRect = read_coord(s, self.ctx.deltaCoords, self.nTopRect)
        if self.ctx.field(3):
            self.nWidth = read_coord(s, self.ctx.deltaCoords, self.nWidth)
        if self.ctx.field(4):
            self.nHeight = read_coord(s, self.ctx.deltaCoords, self.nHeight)

        if self.ctx.field(5):
            r = Uint8.unpack(s)
            self.color = (self.color & 0x00FFFF00) | r
        if self.ctx.field(6):
            g = Uint8.unpack(s)
            self.color = (self.color & 0x00FF00FF) | (g << 8)
        if self.ctx.field(7):
            b = Uint8.unpack(s)
            self.color = (self.color & 0x0000FFFF) | (b << 16)

        if self.ctx.field(8):
            self.numRectangles = Uint8.unpack(s)

        if self.ctx.field(9):
            self.cbData = Uint16LE.unpack(s)
            self.rectangles = read_delta_rectangles(s, self.numRectangles)

        return self
Exemplo n.º 4
0
    def update(self, s: BytesIO):

        num = self.numPoints
        if self.ctx.field(1):
            self.x0 = read_coord(s, self.ctx.deltaCoords, self.x0)
        if self.ctx.field(2):
            self.y0 = read_coord(s, self.ctx.deltaCoords, self.y0)
        if self.ctx.field(3):
            self.rop2 = Uint8.unpack(s)
        if self.ctx.field(4):
            self.fillMode = Uint8.unpack(s)
        if self.ctx.field(5):
            self.bg = read_rgb(s)
        if self.ctx.field(6):
            self.fg = read_rgb(s)

        self.brush.update(s, self.ctx.fieldFlags >> 6)

        if self.ctx.field(12):
            num = Uint8.unpack(s)

        if self.ctx.field(13):
            self.cbData = Uint8.unpack(s)
            self.numPoints = num
            self.points = read_delta_points(s, self.numPoints, self.x0,
                                            self.y0)

        self.bgMode = BACKMODE_TRANSPARENT if self.rop2 & 0x80 else BACKMODE_OPAQUE
        self.rop2 = self.rop2 & 0x1F

        return self
Exemplo n.º 5
0
    def update(self, s: BytesIO):

        if self.ctx.field(1):
            self.x = read_coord(s, self.ctx.deltaCoords, self.x)
        if self.ctx.field(2):
            self.y = read_coord(s, self.ctx.deltaCoords, self.y)
        if self.ctx.field(3):
            self.w = read_coord(s, self.ctx.deltaCoords, self.w)
        if self.ctx.field(4):
            self.h = read_coord(s, self.ctx.deltaCoords, self.h)
        if self.ctx.field(5):
            self.rop = Uint8.unpack(s)
        if self.ctx.field(6):
            self.bg = read_rgb(s)
        if self.ctx.field(7):
            self.fg = read_rgb(s)

        self.brush.update(s, self.ctx.fieldFlags >> 7)

        if self.ctx.field(13):
            self.numRectangles = Uint8.unpack(s)

        if self.ctx.field(14):
            self.cbData = Uint16LE.unpack(s)
            self.rectangles = read_delta_rectangles(s, self.numRectangles)

        return self
Exemplo n.º 6
0
    def update(self, s: BytesIO):

        if self.ctx.field(1):
            self.nLeftRect = read_coord(s, self.ctx.deltaCoords,
                                        self.nLeftRect)
        if self.ctx.field(2):
            self.nTopRect = read_coord(s, self.ctx.deltaCoords, self.nTopRect)
        if self.ctx.field(3):
            self.nWidth = read_coord(s, self.ctx.deltaCoords, self.nWidth)
        if self.ctx.field(4):
            self.nHeight = read_coord(s, self.ctx.deltaCoords, self.nHeight)
        if self.ctx.field(5):
            self.bRop = Uint8.unpack(s)
        if self.ctx.field(6):
            self.nXSrc = read_coord(s, self.ctx.deltaCoords, self.nXSrc)
        if self.ctx.field(7):
            self.nYSrc = read_coord(s, self.ctx.deltaCoords, self.nYSrc)
        if self.ctx.field(8):
            self.numRectangles = Uint8.unpack(s)

        if self.ctx.field(9):
            self.cbData = Uint16LE.unpack(s)
            self.rectangles = read_delta_rectangles(s, self.numRectangles)

        return self
Exemplo n.º 7
0
Arquivo: common.py Projeto: xuyi/pyrdp
def read_encoded_uint16(s: BytesIO) -> int:
    """Read an encoded UINT16."""
    # 2.2.2.2.1.2.1.2
    b = Uint8.unpack(s)
    if b & 0x80:
        return (b & 0x7F) << 8 | Uint8.unpack(s)
    else:
        return b & 0x7F
Exemplo n.º 8
0
Arquivo: common.py Projeto: xuyi/pyrdp
def read_encoded_int16(s: BytesIO) -> int:
    # 2.2.2.2.1.2.1.3
    msb = Uint8.unpack(s)
    val = msb & 0x3F

    if msb & 0x80:
        lsb = Uint8.unpack(s)
        val = (val << 8) | lsb

    return -val if msb & 0x40 else val
Exemplo n.º 9
0
def readLength(s: BinaryIO) -> int:
    """
    Unpack a PER length indicator
    :param s: stream
    """
    byte = Uint8.unpack(s.read(1))

    if byte & 0x80:
        byte &= ~0x80
        return (byte << 8) + Uint8.unpack(s.read(1))
    else:
        return byte
Exemplo n.º 10
0
def readLength(s):
    """
    Unpack a PER length indicator
    :param s: stream
    :type s: file
    :return: int
    """
    byte = Uint8.unpack(s.read(1))
    size = 0
    if byte & 0x80:
        byte &= ~0x80
        return (byte << 8) + Uint8.unpack(s.read(1))
    else:
        return byte
Exemplo n.º 11
0
    def _parse_secondary(self, s: BytesIO, flags: int):
        Uint16LE.unpack(s)  # orderLength (unused)
        extraFlags = Uint16LE.unpack(s)
        orderType = Uint8.unpack(s)

        assert orderType >= 0 and orderType < len(_sec)
        _sec[orderType](self, s, orderType, extraFlags)
Exemplo n.º 12
0
    def update(self, s: BytesIO):
        if self.ctx.field(1):
            self.cacheId = Uint16LE.unpack(s)
        if self.ctx.field(2):
            self.left = read_coord(s, self.ctx.deltaCoords, self.left)
        if self.ctx.field(3):
            self.top = read_coord(s, self.ctx.deltaCoords, self.top)
        if self.ctx.field(4):
            self.width = read_coord(s, self.ctx.deltaCoords, self.width)
        if self.ctx.field(5):
            self.height = read_coord(s, self.ctx.deltaCoords, self.height)
        if self.ctx.field(6):
            self.rop = Uint8.unpack(s)
        if self.ctx.field(7):
            self.nXSrc = read_coord(s, self.ctx.deltaCoords, self.nXSrc)
        if self.ctx.field(8):
            self.nYSrc = read_coord(s, self.ctx.deltaCoords, self.nYSrc)
        if self.ctx.field(9):
            self.bg = read_rgb(s)
        if self.ctx.field(10):
            self.fg = read_rgb(s)

        self.brush.update(s, self.ctx.fieldFlags >> 10)

        if self.ctx.field(16):
            self.cacheIndex = Uint16LE.unpack(s)

        self.colorIndex = self.cacheId >> 8
        self.cacheId = self.cacheId & 0xFF

        return self
Exemplo n.º 13
0
    def update(self, s: BytesIO) -> 'MemBlt':
        ctx = self.ctx

        if ctx.field(1):
            self.cacheId = Uint16LE.unpack(s)
        if ctx.field(2):
            self.left = read_coord(s, ctx.deltaCoords, self.left)
        if ctx.field(3):
            self.top = read_coord(s, ctx.deltaCoords, self.top)
        if ctx.field(4):
            self.width = read_coord(s, ctx.deltaCoords, self.width)
        if ctx.field(5):
            self.height = read_coord(s, ctx.deltaCoords, self.height)
        if ctx.field(6):
            self.rop = Uint8.unpack(s)
        if ctx.field(7):
            self.xSrc = read_coord(s, ctx.deltaCoords, self.xSrc)
        if ctx.field(8):
            self.ySrc = read_coord(s, ctx.deltaCoords, self.ySrc)
        if ctx.field(9):
            self.cacheIndex = Uint16LE.unpack(s)

        self.colorIndex = self.cacheId >> 8
        self.cacheId = self.cacheId & 0xFF

        return self
Exemplo n.º 14
0
    def update(self, s: BytesIO, flags: int):
        """
        Update the context when parsing a new primary order.

        This method should be called at the beginning of every new
        primary order to process contextual changes.

        :param s BytesIO: The raw byte stream
        :param flags int: The controlFlags received in the UPDATE PDU.

        :return: The orderType to act upon.
        """

        if flags & ControlFlags.TS_TYPE_CHANGE:
            self.orderType = Uint8.unpack(s)
        assert self.orderType is not None

        self.fieldFlags = read_field_flags(s, flags, self.orderType)

        # Process bounding rectangle updates
        if flags & ControlFlags.TS_BOUNDS:
            self.bounded = True
            if not flags & ControlFlags.TS_ZERO_BOUNDS_DELTAS:
                self.bounds.update(s)
        else:
            self.bounded = False

        self.deltaCoords = flags & ControlFlags.TS_DELTA_COORDS != 0

        return self.orderType
Exemplo n.º 15
0
def readSelection(s):
    """
    Unpack a PER selection
    :param s: stream
    :type s: file
    :return: int
    """
    return Uint8.unpack(s.read(1))
Exemplo n.º 16
0
def readEnumeration(s):
    """
    Unpack a PER enumeration format
    :param s: stream
    :type s: file
    :return: int
    """
    return Uint8.unpack(s.read(1))
Exemplo n.º 17
0
    def update(self, s: BytesIO):
        if self.ctx.field(1):
            self.cacheId = Uint8.unpack(s)
        if self.ctx.field(2):
            self.ulCharInc = Uint8.unpack(s)
            self.flAccel = Uint8.unpack(s)
        if self.ctx.field(3):
            self.bg = read_rgb(s)
        if self.ctx.field(4):
            self.fg = read_rgb(s)
        if self.ctx.field(5):
            self.bkLeft = read_coord(s, self.ctx.deltaCoords, self.bkLeft)
        if self.ctx.field(6):
            self.bkTop = read_coord(s, self.ctx.deltaCoords, self.bkTop)
        if self.ctx.field(7):
            self.bkRight = read_coord(s, self.ctx.deltaCoords, self.bkRight)
        if self.ctx.field(8):
            self.bkBottom = read_coord(s, self.ctx.deltaCoords, self.bkBottom)
        if self.ctx.field(9):
            self.opLeft = read_coord(s, self.ctx.deltaCoords, self.opLeft)
        if self.ctx.field(10):
            self.opTop = read_coord(s, self.ctx.deltaCoords, self.opTop)
        if self.ctx.field(11):
            self.opRight = read_coord(s, self.ctx.deltaCoords, self.opRight)
        if self.ctx.field(12):
            self.opBottom = read_coord(s, self.ctx.deltaCoords, self.opBottom)
        if self.ctx.field(13):
            self.x = read_coord(s, self.ctx.deltaCoords, self.x)
        if self.ctx.field(14):
            self.y = read_coord(s, self.ctx.deltaCoords, self.y)

        if self.ctx.field(15):
            cbData = Uint8.unpack(s)

            if cbData > 1:
                # Read glyph data.
                self.glyph = GlyphV2.parse(s)
                self.cacheIndex = self.glyph.cacheIndex
                s.read(2)  # Padding / Unicode representation
            else:
                # Only a cache index.
                assert cbData == 1
                self.glyph = None  # Glyph must be retrieved from cacheIndex
                self.cacheIndex = Uint8.unpack(s)

        return self
Exemplo n.º 18
0
def readChoice(s):
    """
    Unpack a PER choice
    :param s: stream
    :type s: file
    :return: int
    """
    return Uint8.unpack(s.read(1))
Exemplo n.º 19
0
def readNumberOfSet(s):
    """
    Unpack a PER NumberOfSet
    :param s: stream
    :type s: file
    :return: int
    """
    return Uint8.unpack(s.read(1))
Exemplo n.º 20
0
    def update(self, s: BytesIO):

        if self.ctx.field(1):
            self.left = read_coord(s, self.ctx.deltaCoords, self.left)
        if self.ctx.field(2):
            self.top = read_coord(s, self.ctx.deltaCoords, self.top)
        if self.ctx.field(3):
            self.right = read_coord(s, self.ctx.deltaCoords, self.right)
        if self.ctx.field(4):
            self.bottom = read_coord(s, self.ctx.deltaCoords, self.bottom)
        if self.ctx.field(5):
            self.rop2 = Uint8.unpack(s)
        if self.ctx.field(6):
            self.fillMode = Uint8.unpack(s)
        if self.ctx.field(7):
            self.color = read_rgb(s)

        return self
Exemplo n.º 21
0
    def _parse_order(self, s: BytesIO):
        controlFlags = Uint8.unpack(s)

        if not (controlFlags & ControlFlags.TS_STANDARD):
            self._parse_altsec(s, controlFlags)
        elif (controlFlags & ControlFlags.TS_SECONDARY):
            self._parse_secondary(s, controlFlags)
        else:
            self._parse_primary(s, controlFlags)
Exemplo n.º 22
0
def readUniversalTag(s: BinaryIO, tag: Tag, isConstruct: bool) -> bool:
    """
    Unpack universal tag and return True if the proper tag was read.
    :param s: stream
    :param tag: BER tag
    :param isConstruct: True if a construct is expected
    """
    byte = Uint8.unpack(s.read(1))
    return byte == ((Class.BER_CLASS_UNIV | berPC(isConstruct)) |
                    (Tag.BER_TAG_MASK & tag))
Exemplo n.º 23
0
def readObjectIdentifier(s: BinaryIO):
    """
    Unpack a PER object identifier (tuple of 6 integers)
    :param s: stream
    :return: (int, int, int, int, int, int)
    """
    size = readLength(s)
    if size != 5:
        raise ValueError("Object identifier size must be 5 (got %d instead)" % size)
    
    a_oid = [0, 0, 0, 0, 0, 0]
    t12 = Uint8.unpack(s.read(1))
    a_oid[0] = t12 >> 4
    a_oid[1] = t12 & 0x0f
    a_oid[2] = Uint8.unpack(s.read(1))
    a_oid[3] = Uint8.unpack(s.read(1))
    a_oid[4] = Uint8.unpack(s.read(1))
    a_oid[5] = Uint8.unpack(s.read(1))
    return tuple(a_oid)
Exemplo n.º 24
0
    def parse(s: BytesIO) -> 'CacheColorTable':
        self = CacheColorTable()

        self.cacheIndex = Uint8.unpack(s)
        numberColors = Uint16LE.unpack(s)

        assert numberColors == 256
        self.colors = [read_color(s) for _ in range(numberColors)]

        return self
Exemplo n.º 25
0
    def update(self, s: BytesIO):

        if self.ctx.field(1):
            self.cacheId = Uint8.unpack(s)
        if self.ctx.field(2):
            self.flAccel = Uint8.unpack(s)
        if self.ctx.field(3):
            self.ulCharInc = Uint8.unpack(s)
        if self.ctx.field(4):
            self.fOpRedundant = Uint8.unpack(s)
        if self.ctx.field(5):
            self.bg = read_rgb(s)
        if self.ctx.field(6):
            self.fg = read_rgb(s)
        if self.ctx.field(7):
            self.bkLeft = Uint16LE.unpack(s)
        if self.ctx.field(8):
            self.bkTop = Uint16LE.unpack(s)
        if self.ctx.field(9):
            self.bkRight = Uint16LE.unpack(s)
        if self.ctx.field(10):
            self.bkBottom = Uint16LE.unpack(s)
        if self.ctx.field(11):
            self.opLeft = Uint16LE.unpack(s)
        if self.ctx.field(12):
            self.opTop = Uint16LE.unpack(s)
        if self.ctx.field(13):
            self.opRight = Uint16LE.unpack(s)
        if self.ctx.field(14):
            self.opBottom = Uint16LE.unpack(s)

        self.brush.update(s, self.ctx.fieldFlags >> 14)

        if self.ctx.field(20):
            self.x = Uint16LE.unpack(s)
        if self.ctx.field(21):
            self.y = Uint16LE.unpack(s)

        if self.ctx.field(22):
            cbData = Uint8.unpack(s)
            self.data = s.read(cbData)

        return self
Exemplo n.º 26
0
    def update(self, s: BytesIO, flags: int):
        if flags & 0b00001:
            self.x = Uint8.unpack(s)
        if flags & 0b00010:
            self.y = Uint8.unpack(s)
        if flags & 0b00100:
            self.style = Uint8.unpack(s)
        if flags & 0b01000:
            self.hatch = Uint8.unpack(s)
        if flags & 0b10000:
            self.data = (s.read(7) + bytes([self.hatch]))[::-1]

        if self.style & CACHED_BRUSH:
            self.index = self.hatch
            self.bpp = BMF_BPP[self.style & 0x07]
            if self.bpp == 0:
                self.bpp = 1

        return self
Exemplo n.º 27
0
def readLength(s: BinaryIO) -> int:
    """
    Read length of BER structure
    Length is on 1, 2 or 3 bytes
    :param s: stream
    """

    byte = Uint8.unpack(s.read(1))
    if byte & 0x80:
        byte &= ~0x80

        if byte == 1:
            return Uint8.unpack(s.read(1))
        elif byte == 2:
            return Uint16BE.unpack(s.read(2))
        else:
            raise ValueError("BER length must be 1 or 2")
    else:
        return byte
Exemplo n.º 28
0
def readEnumeration(s: BinaryIO) -> int:
    """
    Unpack a BER enumeration value
    :param s: stream
    """
    if not readUniversalTag(s, Tag.BER_TAG_ENUMERATED, False):
        raise ValueError("Bad enumeration tag")

    if readLength(s) != 1:
        raise ValueError("Enumeration size must be 1")

    return Uint8.unpack(s.read(1))
Exemplo n.º 29
0
    def update(self, s: BytesIO):
        if self.ctx.field(1):
            self.x = read_coord(s, self.ctx.deltaCoords, self.x)
        if self.ctx.field(2):
            self.y = read_coord(s, self.ctx.deltaCoords, self.y)
        if self.ctx.field(3):
            self.w = read_coord(s, self.ctx.deltaCoords, self.w)
        if self.ctx.field(4):
            self.h = read_coord(s, self.ctx.deltaCoords, self.h)

        if self.ctx.field(5):
            r = Uint8.unpack(s)
            self.color = (self.color & 0x00FFFF00) | r
        if self.ctx.field(6):
            g = Uint8.unpack(s)
            self.color = (self.color & 0x00FF00FF) | (g << 8)
        if self.ctx.field(7):
            b = Uint8.unpack(s)
            self.color = (self.color & 0x0000FFFF) | (b << 16)

        return self
Exemplo n.º 30
0
Arquivo: common.py Projeto: xuyi/pyrdp
    def parse(s: BytesIO) -> Glyph:
        self = Glyph()

        self.cacheIndex = Uint8.unpack(s)

        self.x = read_encoded_int16(s)
        self.y = read_encoded_int16(s)
        self.w = read_encoded_uint16(s)
        self.h = read_encoded_uint16(s)

        self.data = read_glyph_bitmap(self.w, self.h, s)

        return self