Skip to content

Instantly share code, notes, and snippets.

@andreberg
Last active February 24, 2020 17:59
Show Gist options
  • Save andreberg/5962681 to your computer and use it in GitHub Desktop.
Save andreberg/5962681 to your computer and use it in GitHub Desktop.
[Synalyze It Pro: Python 2 and 3 Bytecode Grammar] Targets .pyc and .pyo bytecode files. #synalyzeitpro #grammar #python #python3 #bytecode
<?xml version="1.0" encoding="UTF-8"?>
<ufwb version="1.5.1">
<grammar name="Python Bytecode" start="id:104" author="André Berg" email="[email protected]" fileextension="pyc, pyo" uti="public.data" complete="yes">
<description>Grammar for PYC and PYO files
Version: 8
Now works with pyc/pyo files generated by Python 2, Python 3.0-3.2 and Python 3.3.
References
http://daeken.com/2010-02-20_Python_Marshal_Format.html
http://nedbatchelder.com/blog/200804/the_structure_of_pyc_files.html
See also: marshal.c, longobject.c, ceval.c and _bootstrap.py from Python source</description>
<scripts>
<script name="Timestamp" type="DataType" id="43">
<description>Parse header timestamp, which is a 4 byte little endian value starting at offset 4.</description>
<source language="Python"># Data type script for displaying and manipulating the
# timestamp header bytes in a Python bytcode (pyc) file.
#
# pyc header
# 8 16
# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
# |X|X|X|X|0|D|0|A| |T|I|M|E|S|T|M|P|
# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
# \______/\______/ \_______________/
# inc. cr/lf timestamp
#
# Author: Andre Berg
#
# You can change the TIME_FORMAT constant below to the
# format you are most comfortable with. By default it
# will use an ISO-8601 date time format.
#
import time, struct
import datetime
ASCTIME_FORMAT = &quot;%a %b %d %H:%M:%S %Y&quot;
ISODATE_FORMAT = &quot;%Y-%m-%d %H:%M:%S&quot;
TIME_FORMAT = ISODATE_FORMAT
def parseByteRange(element, byteView, bitPos, bitLength, results):
# this method parses data starting at bitPos, bitLength bits are remaining
&quot;&quot;&quot;parseByteRange method&quot;&quot;&quot;
tsBytes = byteView.readUnsignedInt(bitPos/8, 4, ENDIAN_LITTLE)
stamp = str(time.strftime(TIME_FORMAT, time.localtime(tsBytes)))
# create and set new value
value = Value()
value.setString(stamp)
# how many bytes were processed?
processedBytes = 4
iteration = 0
results.addElement(element, processedBytes, iteration, value)
# return number of processed bytes
return processedBytes
def fillByteRange(value, byteArray, bitPos, bitLength):
# this method translates edited values back to the file
&quot;&quot;&quot;fillByteRange method&quot;&quot;&quot;
editedString = value.getString()
newStamp = int(time.mktime(time.strptime(editedString, TIME_FORMAT)))
newBytes = struct.pack('I', newStamp)
# write an integer back to file
byteArray.fillRange(bitPos/8, 4, newBytes)
</source>
</script>
<script name="LongObjectValue" type="DataType" id="528">
<description>Interpret value part of Python's long integer representation (PyLong objects). See longintrepr.h, longint.c and longint.h in Python's source code.</description>
<source language="Python"># Data type script for interpreting the value part
# of Python's long integer object representation.
#
# Serialization of PyLong objects to marshal's bytecode
# format has the following layout:
#
# +--+--+--+--+--+--+--+--+--+
# |6C|XX|XX|XX|XX|NN| ... |NN|
# +--+--+--+--+--+--+--+--+--+
# \_/ \_________/ \_________/
# l size digit arr.
#
# The size determines the length of the variable digit array portion.
# It is exactly size * 2 bytes long.
#
# Python's long objects are packed structures representings
# arbitrary size integers. In the source code these are represented
# by PyLong objects which have a size and an array of digits
# that get de- and reconstructed by some trickery with shifting
# operations.
#
# marshal.c then does some additional trickery to store and decode
# them. If you are really interested to find out about this, see
# the following files in Python's source code:
#
# methods r_long and r_PyLong in marshal.c
# longintrepr.h, longobj.h and longobj.c, specifically the method long_from_bytes
#
# Author: Andre Berg
#
import marshal
import sys
def sysbits():
if sys.maxsize &gt; 2**32:
return 64
else:
return 32
def is_64bit():
if sysbits() &gt; 32:
return True
else:
return False
def is_32bit():
if sysbits() &lt;= 32:
return True
else:
return False
# Unfortunately Python 2.6 doesn't have sys.int_info yet
# so we have to guess PyLong_SHIFT.
if is_64bit():
PyLong_SHIFT = 30
SIZEOF_LONG = 8
else:
PyLong_SHIFT = 15
SIZEOF_LONG = 4
PyLong_BASE = (1 &lt;&lt; PyLong_SHIFT)
PyLong_MASK = (PyLong_BASE - 1)
PyLong_MARSHAL_SHIFT = 15
PyLong_MARSHAL_BASE = (1 &lt;&lt; PyLong_MARSHAL_SHIFT)
PyLong_MARSHAL_MASK = (PyLong_MARSHAL_BASE - 1)
PyLong_MARSHAL_RATIO = round(PyLong_SHIFT / PyLong_MARSHAL_SHIFT)
def r_long(b):
x = b[0]
x |= b[1] &lt;&lt; 8
x |= b[2] &lt;&lt; 16
x |= b[3] &lt;&lt; 24
if SIZEOF_LONG &gt; 4:
# Sign extension for 64-bit machines
x |= -(x &amp; 0x80000000)
return x
def parseByteRange(element, byteView, bitPos, bitLength, results):
# this method parses data starting at bitPos, bitLength bits are remaining
&quot;&quot;&quot;parseByteRange method&quot;&quot;&quot;
tsBytes = []
bv = byteView
# need to read the whole marshal structure incl 0x6C indicating type 'l'ong and 4 size bytes
type_mask = '\x6C'
size_mask = '\x00\x00\x00\x00'
offset = len(type_mask) + len(size_mask)
if sys.byteorder == 'little':
endianess = ENDIAN_LITTLE
else:
endianess = ENDIAN_BIG
start = ((bitPos/8) - offset)
size = abs(int(byteView.readSignedInt(int(start + 1), 4, endianess)))
if PyLong_MARSHAL_SHIFT == 30:
size &lt;&lt;= 2
else:
size &lt;&lt;= 1
for i in range(0, size + offset):
tsBytes.append(byteView.readByte(int(start + i)))
tsBytesStr = &quot;&quot;
for b in tsBytes:
tsBytesStr += chr(b)
# create and set new value
value = Value()
value.setString(str(marshal.loads(tsBytesStr)))
# how many bytes were processed?
processedBytes = size
iteration = 0
results.addElement(element, processedBytes, iteration, value)
# return number of processed bytes
return processedBytes
def fillByteRange(value, byteArray, bitPos, bitLength):
# this method translates edited values back to the file
&quot;&quot;&quot;fillByteRange method&quot;&quot;&quot;
# write an integer back to file
# byteArray.writeUnsignedIntBits(highWord, bitPos, bitLength, ENDIAN_BIG)
# Note: although it would be somewhat trivial to write this method
# using Python's marshal.dumps() method, one would also have to check
# that the integer entered actually converts to a type 6C ('l') bytearray
# because otherwise the length of the file would change. The difficulty is that
# different Python versions handle integer size and limits differently.
#
# The implementation below only applies the change if the length of the file
# wouldn't change.
#
offset = len('\x6C\x00\x00\x00\x00')
start = ((bitPos/8) - offset)
editedString = value.getString()
try:
newBytes = marshal.dumps(long(editedString))
except ValueError:
return
valuePortion = newBytes[offset:]
if newBytes[0] == '\x6C' and len(valuePortion) == (bitLength/8):
byteArray.fillRange(start, len(newBytes), newBytes)
</source>
</script>
</scripts>
<structure name="defaults" id="105" encoding="UTF-8" endian="little" signed="no"/>
<structure name="Python Bytecode" id="104" extends="id:105">
<scriptelement name="DetermineBytecodeVersion" id="107">
<script name="unnamed" type="Generic">
<source language="Lua">function log(msg)
logSrc = currentMapper:getCurrentLogSrc()
logSrc:logMessage(&quot;PYT&quot;, 111, synalysis.SEVERITY_INFO, tostring(msg))
end
function getPycVersion()
bv = currentMapper:getCurrentByteView()
byteAtOffsetEight = bv:readByte(8)
--log(byteAtOffsetEight)
if byteAtOffsetEight == 0x63 then
byteAtOffsetTwenty = bv:readByte(25)
--log(byteAtOffsetTwenty)
if byteAtOffsetTwenty == 0x73 then
return 20
else
return 30
end
else
return 33
end
end
function pycVersionAsString()
n = getPycVersion()
if n &gt;= 33 then
return &quot;Version 3.3&quot;
elseif n == 30 then
return &quot;Version 3.0&quot;
else
return &quot;Version 2.0&quot;
end
end
function resultAsString(r)
if r == nil then
return &quot;nil&quot;
elseif r.getName ~= nil then
return tostring(r:getName())
else
return &quot;Unknown&quot;
end
end
currentGrammar = currentMapper:getCurrentGrammar()
results = currentMapper:getCurrentResults()
byteArray = currentMapper:getCurrentByteArray()
byteView = currentMapper:getCurrentByteView()
fileLength = byteView:getLength()
lastResult = results:getLastResult()
marshalDataResult = results:getResultByName(&quot;Marshal data&quot;)
flagsResult = results:getResultByName(&quot;flags&quot;)
topLevelResult = results:getResultByName(&quot;Python Bytecode&quot;)
prevResult = results:getPrevResult(lastResult)
pycVersion = getPycVersion()
pycVersionStr = pycVersionAsString()
--log(&quot;Bytecode &quot; .. pycVersionStr)
version2Structure = currentGrammar:getStructureByName(&quot;Version 2&quot;)
version30Structure = currentGrammar:getStructureByName(&quot;Version 3.0&quot;)
version33Structure = currentGrammar:getStructureByName(&quot;Version 3.3&quot;)
whichStructure = nil
if (pycVersion == 20) then
whichStructure = version2Structure
elseif (pycVersion == 30) then
whichStructure = version30Structure
else
whichStructure = version33Structure
end
bytesProcessed = currentMapper:mapStructureAtPosition(whichStructure, 0, fileLength)</source>
</script>
</scriptelement>
</structure>
<structure name="Version 2" id="109" repeatmin="0" extends="id:105">
<structref name="Header" id="111" structure="id:110"/>
<structure name="Marshal data" id="112" length="0" order="variable">
<structref name="Element" id="114" repeatmax="-1" structure="id:113"/>
</structure>
</structure>
<structure name="Version 3.0" id="117" repeatmin="0" extends="id:105">
<structref name="Header" id="119" structure="id:118"/>
<structure name="Marshal data" id="120" length="0" alignment="0" order="variable">
<structref name="Element" id="122" repeatmax="-1" structure="id:121"/>
</structure>
</structure>
<structure name="Version 3.3" id="125" repeatmin="0" extends="id:105">
<structref name="Header" id="127" structure="id:126"/>
<structure name="Marshal data" id="128" length="0" alignment="0" order="variable">
<structref name="Element" id="129" repeatmax="-1" structure="id:121"/>
</structure>
</structure>
<structure name="Header (Python 2)" id="110" length="8" repeatmin="0" extends="id:105">
<number name="Magic Number" id="132" fillcolor="F72D17" type="integer" length="2"/>
<binary name="CRLF" id="133" fillcolor="F9AF2D" length="2"/>
<custom name="Timestamp" id="134" fillcolor="26FFFF" length="4" script="id:43"/>
</structure>
<structure name="Header (Python 3.0)" id="118" length="8" repeatmin="0" extends="id:105">
<number name="Magic Number" id="136" fillcolor="F72D17" type="integer" length="2"/>
<binary name="CRLF" id="137" fillcolor="F9AF2D" length="2"/>
<custom name="Timestamp" id="138" fillcolor="26FFFF" length="4" script="id:43"/>
</structure>
<structure name="Header (Python 3.2)" id="126" length="12" repeatmin="0" extends="id:105">
<number name="Magic Number" id="140" fillcolor="F72D17" type="integer" length="2"/>
<binary name="CRLF" id="141" fillcolor="F9AF2D" length="2"/>
<custom name="Timestamp" id="142" fillcolor="26FFFF" length="4" script="id:43"/>
<number name="Size" id="143" fillcolor="0FD8FF" type="integer" length="4"/>
</structure>
<structure name="Code (Python 2)" id="145" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="146" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Code" value="63"/>
</fixedvalues>
</binary>
<number name="argcount" id="147" fillcolor="BF0C86" type="integer" length="4"/>
<number name="nlocals" id="148" fillcolor="BF581D" type="integer" length="4"/>
<number name="stacksize" id="149" fillcolor="FF7600" type="integer" length="4"/>
<binary name="flags" id="150" fillcolor="F9AF2D" length="4"/>
<structref name="code" id="152" structure="id:151"/>
<structref name="consts" id="154" structure="id:153"/>
<structref name="names" id="155" structure="id:153"/>
<structref name="varnames" id="156" structure="id:153"/>
<structref name="freevars" id="157" structure="id:153"/>
<structref name="cellvars" id="158" structure="id:153"/>
<structref name="filename" id="159" structure="id:151"/>
<structref name="name" id="160" structure="id:151"/>
<number name="firstlineno" id="161" fillcolor="FB82D7" type="integer" length="4"/>
<structref name="lnotab" id="162" structure="id:151"/>
</structure>
<structure name="Code (Python 3)" id="164" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="165" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Code" value="63"/>
</fixedvalues>
</binary>
<number name="argcount" id="166" fillcolor="BF0C86" type="integer" length="4"/>
<number name="nlocals" id="167" fillcolor="BF581D" type="integer" length="4"/>
<number name="stacksize" id="168" fillcolor="FF7600" type="integer" length="4"/>
<binary name="flags" id="169" fillcolor="F9AF2D" length="8"/>
<structref name="code" id="170" structure="id:151"/>
<structref name="consts" id="172" structure="id:171"/>
<structref name="names" id="173" structure="id:171"/>
<structref name="varnames" id="174" structure="id:171"/>
<structref name="freevars" id="175" structure="id:171"/>
<structref name="cellvars" id="176" structure="id:171"/>
<structref name="filename" id="177" structure="id:151"/>
<structref name="name" id="178" structure="id:151"/>
<number name="firstlineno" id="179" fillcolor="FB82D7" type="integer" length="4"/>
<structref name="lnotab" id="180" structure="id:151"/>
</structure>
<structure name="String" id="182" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="183" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="String" value="73"/>
<fixedvalue name="Unicode" value="75"/>
<fixedvalue name="InternedString" value="74"/>
</fixedvalues>
</binary>
<number name="length" id="184" fillcolor="38EC0D" type="integer" length="4"/>
<string name="data" id="185" fillcolor="00B80B" repeatmin="0" type="fixed-length" length="length"/>
</structure>
<structure name="Type" id="187" disabled="yes" extends="id:105">
<binary name="type" id="188" disabled="yes" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Ellipsis" value="2E"/>
<fixedvalue name="Null" value="30"/>
<fixedvalue name="None" value="4E"/>
<fixedvalue name="True" value="54"/>
<fixedvalue name="False" value="46"/>
<fixedvalue name="Code" value="63"/>
<fixedvalue name="Float" value="66"/>
<fixedvalue name="Binary Float" value="67"/>
<fixedvalue name="Int" value="69"/>
<fixedvalue name="Int64" value="49"/>
<fixedvalue name="Long" value="6C"/>
<fixedvalue name="String Ref" value="52"/>
<fixedvalue name="String" value="73"/>
<fixedvalue name="StopIteration" value="53"/>
<fixedvalue name="Interned String" value="74"/>
<fixedvalue name="Unicode" value="75"/>
<fixedvalue name="Complex" value="78"/>
<fixedvalue name="Binary Complex" value="79"/>
<fixedvalue name="Tuple" value="28"/>
<fixedvalue name="List" value="5B"/>
<fixedvalue name="Dict" value="7B"/>
<fixedvalue name="Set" value="3C"/>
<fixedvalue name="Frozenset" value="3E"/>
<fixedvalue name="Unknown" value="3F"/>
</fixedvalues>
</binary>
</structure>
<structure name="TupleLikes (Python 2)" id="153" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="190" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Tuple" value="28"/>
<fixedvalue name="List" value="5B"/>
<fixedvalue name="Set" value="3C"/>
<fixedvalue name="Frozenset" value="3E"/>
</fixedvalues>
</binary>
<number name="length" id="191" fillcolor="8503C2" type="integer" length="4"/>
<structref name="element" id="192" repeatmax="length" structure="id:113"/>
</structure>
<structure name="TupleLikes (Python 3)" id="171" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="194" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Tuple" value="28"/>
<fixedvalue name="List" value="5B"/>
<fixedvalue name="Set" value="3C"/>
<fixedvalue name="Frozenset" value="3E"/>
</fixedvalues>
</binary>
<number name="length" id="195" fillcolor="8503C2" type="integer" length="4"/>
<structref name="element" id="196" repeatmax="length" structure="id:121"/>
</structure>
<structure name="Int" id="198" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="199" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Int" value="69"/>
</fixedvalues>
</binary>
<number name="value" id="200" fillcolor="DC0713" type="integer" length="4" signed="yes"/>
</structure>
<structure name="Int64" id="202" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="203" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Int64" value="49"/>
</fixedvalues>
</binary>
<number name="value" id="204" fillcolor="DC0713" type="integer" length="8" signed="yes"/>
</structure>
<structure name="None" id="206" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="207" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="None" value="4E"/>
</fixedvalues>
</binary>
</structure>
<structure name="Float" id="209" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="210" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Float" value="66"/>
</fixedvalues>
</binary>
<number name="length" id="211" fillcolor="BCBCDE" type="integer" length="1"/>
<string name="value" id="212" fillcolor="8177FC" type="fixed-length" length="length"/>
</structure>
<structure name="BinaryFloat" id="214" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="215" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="BinaryFloat" value="67"/>
</fixedvalues>
</binary>
<number name="value" id="216" fillcolor="F80492" type="float" length="64" lengthunit="bit"/>
</structure>
<structure name="Complex" id="218" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="219" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Complex" value="78"/>
</fixedvalues>
</binary>
<structref name="real" id="220" fillcolor="916C40" structure="id:209"/>
<structref name="imag" id="221" fillcolor="CBBBA1" structure="id:209"/>
</structure>
<structure name="BinaryComplex" id="223" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="224" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="BinaryComplex" value="79"/>
</fixedvalues>
</binary>
<structref name="real" id="225" fillcolor="916C44" structure="id:214"/>
<structref name="imag" id="226" fillcolor="CBBBA1" structure="id:214"/>
</structure>
<structure name="Dict (Python 2)" id="228" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="229" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Dict" value="7B"/>
</fixedvalues>
</binary>
<structref name="element" id="230" fillcolor="FDACFD" repeatmax="-1" structure="id:113"/>
<binary name="terminator" mustmatch="yes" id="231" fillcolor="F942A9" length="1">
<fixedvalues>
<fixedvalue name="Null" value="30"/>
</fixedvalues>
</binary>
</structure>
<structure name="Dict (Python 3)" id="233" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="234" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="Dict" value="7B"/>
</fixedvalues>
</binary>
<structref name="element" id="235" fillcolor="FDACFD" repeatmax="-1" structure="id:121"/>
<binary name="terminator" mustmatch="yes" id="236" fillcolor="F942A9" length="1">
<fixedvalues>
<fixedvalue name="Null" value="30"/>
</fixedvalues>
</binary>
</structure>
<structure name="StringRef" id="238" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="239" fillcolor="F9DD25" length="1">
<fixedvalues>
<fixedvalue name="StringRef" value="52"/>
</fixedvalues>
</binary>
<number name="index" id="240" fillcolor="F9B931" type="integer" length="4"/>
</structure>
<structure name="Element (Python 2)" id="113" repeatmin="0" extends="id:105" order="variable">
<structref name="Int" id="242" repeatmin="0" structure="id:198"/>
<structref name="Int64" id="243" repeatmin="0" structure="id:202"/>
<structref name="Tuple" id="244" repeatmin="0" structure="id:153"/>
<structref name="Float" id="245" repeatmin="0" structure="id:209"/>
<structref name="BinaryFloat" id="246" repeatmin="0" structure="id:214"/>
<structref name="Complex" id="247" repeatmin="0" structure="id:218"/>
<structref name="BinaryComplex" id="248" repeatmin="0" structure="id:223"/>
<structref name="Null" id="250" repeatmin="0" structure="id:249"/>
<structref name="StopIteration" id="252" repeatmin="0" structure="id:251"/>
<structref name="Unknown" id="254" repeatmin="0" structure="id:253"/>
<structref name="Ellipsis" id="256" repeatmin="0" structure="id:255"/>
<structref name="Boolean" id="258" repeatmin="0" structure="id:257"/>
<structref name="Dict" id="259" repeatmin="0" structure="id:228"/>
<structref name="Code" id="260" repeatmin="0" structure="id:145"/>
<structref name="StringLikes" id="261" repeatmin="0" structure="id:151"/>
<structref name="String" id="262" repeatmin="0" structure="id:182"/>
<structref name="StringRef" id="263" repeatmin="0" structure="id:238"/>
<structref name="LongObject" id="265" repeatmin="0" structure="id:264"/>
<structref name="None" id="266" repeatmin="0" structure="id:206"/>
</structure>
<structure name="Element (Python 3)" id="121" repeatmin="0" extends="id:105" order="variable">
<structref name="Int" id="268" repeatmin="0" structure="id:198"/>
<structref name="Int64" id="269" repeatmin="0" structure="id:202"/>
<structref name="None" id="270" repeatmin="0" structure="id:206"/>
<structref name="Tuple" id="271" repeatmin="0" structure="id:171"/>
<structref name="Float" id="272" repeatmin="0" structure="id:209"/>
<structref name="BinaryFloat" id="273" repeatmin="0" structure="id:214"/>
<structref name="Complex" id="274" repeatmin="0" structure="id:218"/>
<structref name="BinaryComplex" id="275" repeatmin="0" structure="id:223"/>
<structref name="Null" id="276" repeatmin="0" structure="id:249"/>
<structref name="StopIteration" id="277" repeatmin="0" structure="id:251"/>
<structref name="Unknown" id="278" repeatmin="0" structure="id:253"/>
<structref name="Ellipsis" id="279" repeatmin="0" structure="id:255"/>
<structref name="Boolean" id="280" repeatmin="0" structure="id:257"/>
<structref name="Dict" id="281" repeatmin="0" structure="id:233"/>
<structref name="Code" id="282" repeatmin="0" structure="id:164"/>
<structref name="StringLikes" id="283" repeatmin="0" structure="id:151"/>
<structref name="String" id="284" repeatmin="0" structure="id:182"/>
<structref name="StringRef" id="285" repeatmin="0" structure="id:238"/>
<structref name="LongObject" id="286" repeatmin="0" structure="id:264"/>
</structure>
<structure name="Null" id="249" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="288" fillcolor="AEAEAE" length="1">
<fixedvalues>
<fixedvalue name="Null" value="30"/>
</fixedvalues>
</binary>
</structure>
<structure name="StopIteration" id="251" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="290" fillcolor="999999" length="1">
<fixedvalues>
<fixedvalue name="StopIteration" value="53"/>
</fixedvalues>
</binary>
</structure>
<structure name="Unknown" id="253" repeatmin="0" extends="id:105">
<binary name="Type" mustmatch="yes" id="292" fillcolor="F98A8B" length="1">
<fixedvalues>
<fixedvalue name="Unknown" value="3F"/>
</fixedvalues>
</binary>
</structure>
<structure name="Ellipsis" id="255" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="294" fillcolor="B0B4B9" length="4">
<fixedvalues>
<fixedvalue name="Ellipsis" value="2E"/>
</fixedvalues>
</binary>
</structure>
<structure name="Boolean" id="257" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="296" fillcolor="A50079" length="1">
<fixedvalues>
<fixedvalue name="True" value="54"/>
<fixedvalue name="False" value="46"/>
</fixedvalues>
</binary>
</structure>
<structure name="TruncatedString" id="298" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="299" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="String" value="73"/>
<fixedvalue name="InternedString" value="74"/>
<fixedvalue name="Unicode" value="75"/>
</fixedvalues>
</binary>
<number name="length" id="300" fillcolor="35CA25" type="integer" length="4"/>
<string name="data" id="301" fillcolor="52920F" type="fixed-length" length="length - 1"/>
</structure>
<structure name="StringLikes" id="151" repeatmin="0" extends="id:105" order="variable">
<structref name="StringRef" id="303" repeatmin="0" structure="id:238"/>
<structref name="String" id="304" repeatmin="0" structure="id:182"/>
</structure>
<structure name="LongObject" id="264" repeatmin="0" extends="id:105">
<binary name="type" mustmatch="yes" id="306" fillcolor="007FFF" length="1">
<fixedvalues>
<fixedvalue name="LongObject" value="6C"/>
</fixedvalues>
</binary>
<number name="size" id="307" fillcolor="D58F3D" type="integer" length="4" signed="yes"/>
<custom name="value" id="308" fillcolor="BF581D" length="remaining" script="id:528"/>
</structure>
</grammar>
</ufwb>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment