Example #1
0
 class IdentifyRsp(NpiRequest, SyncRsp, FromNwp):
     command = Commands.RTLS_CMD_IDENTIFY
     struct = Struct(
         "capabilities" / FlagsEnum(Int16ul, Capabilities),
         "revNum" / Int16ul,
         "devId" / Enum(Int8ul, DeviceFamily),
         "identifier" / NiceBytes(ReverseBytes(Byte[6])),
     )
Example #2
0
def __get_struct(is_wiiu: bool) -> Struct:
    if is_wiiu:
        content_hash = 'sha1' / Padded(0x20, ChecksumRaw(hashlib.sha1))
        app_type = ['app_type' / Hex(Bytes(4)), '_unk2' / Bytes(0x3a)]
    else:
        content_hash = 'sha256' / ChecksumRaw(hashlib.sha256)
        app_type = ['_unk2' / Bytes(0x3e)]

    return InliningStruct(
        'signature' / common.signature,
        '__raw_header_signed__' @ AttributeRawCopy(
            InlineStruct(
                'issuer' / PaddedString(0x40, 'ascii'),
                'format_version' / Byte, 'ca_crl_version' / Byte,
                'signer_crl_version' / Byte, '_unk1' / Bytes(1),
                'system_version' / Hex(Bytes(8)), 'title_id' / common.TitleID,
                'title_type' / Hex(Bytes(4)), 'group_id' / Hex(Bytes(2)), *
                app_type, 'access_rights' / Hex(Bytes(4)),
                'title_version' / Int16ub, 'content_count' / Int16ub,
                'boot_index' / Int16ub, Padding(2), 'content_info_sha256' /
                ChecksumValue(hashlib.sha256, this._.content_info))),
        'content_info' / ChecksumSourceData(
            Array(
                64,
                Struct(
                    'content_index' / Int16ub, 'content_count' / Int16ub,
                    'contents_sha256' / IfThenElse(
                        this.content_count > 0,
                        ChecksumValue(
                            hashlib.sha256, lambda this: this._.
                            contents[this.content_index:this.content_index +
                                     this.content_count], True),
                        ChecksumRaw(hashlib.sha256))))),
        'contents' / Array(
            this.content_count,
            ChecksumSourceData(
                Struct(
                    'id' / Hex(Int32ub),
                    'index' / Int16ub,
                    # 0x2000: always set (?)
                    # 0x4000: appears in DLC TMDs ("optional"?)
                    # 0x8000: "shared"?
                    'type' / FlagsEnum(Int16ub,
                                       encrypted=0x0001,
                                       hashed=0x0002,
                                       cfm=0x0004,
                                       unk1=0x2000,
                                       unk2=0x4000,
                                       unk3=0x8000),
                    'size' / Int64ub,
                    content_hash))),
        'certificates' / common.certificates,
        VerifyOrWriteChecksums,
        Terminated)
Example #3
0
def __get_struct(is_wiiu: bool) -> Struct:
    if is_wiiu:
        swap = lambda x: x  # noop  # noqa: E731
        encoding = 'utf-16-be'
        # tga file
        icon_struct = Struct('128' / Bytes(0x2c + 128 * 128 * 4))
        icon_struct = 'icons_tga' / Padded(icon_struct.sizeof() + 4,
                                           icon_struct)
        region_all = 0xffffffff
    else:
        swap = ByteSwapped
        encoding = 'utf-16-le'
        # raw RGB565
        icon_struct = 'icons_raw' / Struct('24' / Bytes(24 * 24 * 2),
                                           '48' / Bytes(48 * 48 * 2))
        region_all = 0x7fffffff

    return InliningStruct(
        'checksum' / ChecksumValue(hashlib.sha256, this),
        ChecksumSourceData(
            InlineStruct(
                'title_id' / swap(common.TitleID), 'version' / swap(Int32ub),
                '_unk1' / Bytes(4), 'regions' / swap(
                    FlagsEnum(Int32ub,
                              JP=1 << 0,
                              US=1 << 1,
                              EU=1 << 2,
                              AU=1 << 3,
                              CN=1 << 4,
                              KO=1 << 5,
                              TW=1 << 6,
                              ALL=region_all)), '_unk2' / Bytes(0x1c),
                'title_info' / DictZipAdapter(
                    languages,
                    Array(
                        16,
                        Struct('short_name' / PaddedString(0x80, encoding),
                               'long_name' / PaddedString(0x100, encoding),
                               'publisher' / PaddedString(0x80, encoding)))),
                icon_struct)), VerifyOrWriteChecksums, Terminated)
Example #4
0
        """

        return Int32ul.build(obj.form_id)


ServiceFlags = FlagsEnum(
    Int32ul,
    weapons=0x00000001,
    armor=0x00000002,
    alcohol=0x00000004,
    books=0x00000008,
    food=0x00000010,
    chems=0x00000020,
    stimpacks=0x00000040,
    lights=0x00000080,
    _unknown_0=0x00000100,
    _unknown_1=0x00000200,
    miscellaneous=0x00000400,
    _unknown_2=0x00000800,
    _unknown_3=0x00001000,
    potions=0x00002000,
    training=0x00004000,
    _unknown_4=0x00008000,
    recharge=0x00010000,
    repair=0x00020000,
)

EquipmentTypeEnum = Enum(
    Int32sl,
    none=-1,
    big_guns=0,
Example #5
0
    AlignedStruct, If

from etl.parsers.etw.core import Etw, build_etw, Guid as EtwGuid
from etl.parsers.tracelogging import build_tracelogging, TraceLogging
from etl.utils import Guid
from etl.wmi import wmi_trace_marker

EventHeaderType = Enum(Int8ul,
                       EVENT_HEADER_EVENT32=0x12,
                       EVENT_HEADER_EVENT64=0x13)

EventHeaderFlag = FlagsEnum(Int16ul,
                            EVENT_HEADER_FLAG_EXTENDED_INFO=0x0001,
                            EVENT_HEADER_FLAG_PRIVATE_SESSION=0x0002,
                            EVENT_HEADER_FLAG_STRING_ONLY=0x0004,
                            EVENT_HEADER_FLAG_TRACE_MESSAGE=0x0008,
                            EVENT_HEADER_FLAG_NO_CPUTIME=0x0010,
                            EVENT_HEADER_FLAG_32_BIT_HEADER=0x0020,
                            EVENT_HEADER_FLAG_64_BIT_HEADER=0x0040,
                            EVENT_HEADER_FLAG_CLASSIC_HEADER=0x0100,
                            EVENT_HEADER_FLAG_PROCESSOR_INDEX=0x0200)

EventHeaderPropertyFlag = FlagsEnum(
    Int16ul,
    EVENT_HEADER_PROPERTY_XML=0x0001,
    EVENT_HEADER_PROPERTY_FORWARDED_XML=0x0002,
    EVENT_HEADER_PROPERTY_LEGACY_EVENTLOG=0x0004,
    EVENT_HEADER_PROPERTY_RELOGGABLE=0x0008)

EventDescriptor = Struct("Id" / Int16ul, "Version" / Int8ul,
                         "Channel" / Int8ul, "Level" / Int8ul,
                         "Opcode" / Int8ul, "Task" / Int16ul,
Example #6
0
    EVENT_TRACE_GROUP_UMS=0x19,
    EVENT_TRACE_GROUP_ALPC=0x1a,
    EVENT_TRACE_GROUP_SPLITIO=0x1b,
    EVENT_TRACE_GROUP_THREAD_POOL=0x1c,
    EVENT_TRACE_GROUP_HYPERVISOR=0x1d,
    EVENT_TRACE_GROUP_HYPERVISORX=0x1e,
)
"""
Different flags use in the trace header to determine the nature of the event
:see: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/etw/tracelog/wmi_buffer_header.htm
"""
EtwBufferFlag = FlagsEnum(Int16ul,
                          ETW_BUFFER_FLAG_NORMAL=0x0,
                          ETW_BUFFER_FLAG_FLUSH_MARKER=0x1,
                          ETW_BUFFER_FLAG_EVENTS_LOST=0x2,
                          ETW_BUFFER_FLAG_BUFFER_LOST=0x4,
                          ETW_BUFFER_FLAG_RTBACKUP_CORRUPT=0x8,
                          ETW_BUFFER_FLAG_RTBACKUP=0x10,
                          ETW_BUFFER_FLAG_PROC_INDEX=0x20,
                          ETW_BUFFER_FLAG_COMPRESSED=0x40)
"""
The nature of the buffer use to generate the event (ETW)
:see: https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/etw/tracelog/wmi_buffer_header.htm
"""
EtwBufferType = Enum(Int16ul,
                     ETW_BUFFER_TYPE_GENERIC=0x0,
                     ETW_BUFFER_TYPE_RUNDOWN=0x1,
                     ETW_BUFFER_TYPE_CTX_SWAP=0x2,
                     ETW_BUFFER_TYPE_REFTIME=0x3,
                     ETW_BUFFER_TYPE_HEADER=0x4,
                     ETW_BUFFER_TYPE_BATCHED=0x5,
Example #7
0
    unknown=0x7fff,  # no track or not analyzed
    rekordbox=0x8000,
    cd=0)


class StateMaskAdapter(Adapter):
    def _encode(self, obj, context):
        return obj | 0x84  # add bits which are always 1

    def _decode(self, obj, context):
        return obj


StateMask = FlagsEnum(StateMaskAdapter(Int16ub),
                      on_air=8,
                      sync=16,
                      master=32,
                      play=64)

# received on udp port 50002
StatusPacket = Struct(
    "magic" / Const(b'Qspt1WmJOL', String(10)),
    "type" / StatusPacketType,
    "model" / Padded(20, CString(encoding="ascii")),
    "u1" / Const(1, Int8ub),
    "u2" / Default(
        Int8ub, 4
    ),  # some kind of revision? 3 for cdj2000nx, 4 for xdj1000. 1 for djm/rekordbox, 0 for link query
    "player_number" / Int8ub,  # 0x11 for rekordbox
    # 34 bytes until now
    Embedded(
Example #8
0
    Const(b'Vgm '),
    'eof_offset'        / Int32ul,
    'version'           / Int32ul,
    'SN76489_clock'     / Int32ul,
    'YM2413_clock'      / Int32ul,
    'gd3_offset'        / Int32ul,
    'nr_samples'        / Int32ul,
    'loop_offset'       / Int32ul,
    'loop_nr_samples'   / Int32ul,
    'frame_rate'        / Int32ul,
    'SN76489_feedback'  / Int16ul,
    'SN76489_shift_reg' / Byte,
    'SN76489_flags'     /
        FlagsEnum(Byte,
            freq0_is_0x400 = 0x01,
            output_negate  = 0x02,
            stereo         = 0x04,
            clock_divider  = 0x08,
        ),
    'YM2612_clock'      / Int32ul,
    'YM2151_clock'      / Int32ul,
    'data_offset'       / Int32ul,
    'sega_pcm_clock'    / Int32ul,
    'sega_pcm_if_reg'   / Int32ul,
)

class VgmParser(object):
    def __init__(self, buf, pos):
        self._buf = buf
        self._pos = pos

    def has_more(self):
Example #9
0
        return encoded

class TempAdapter(Adapter):
    """ Adapter to encode and decode temperature. """
    def _decode(self, obj, ctx):
        return float(obj / 2.0)

    def _encode(self, obj, ctx):
        return int(obj * 2.0)

ModeFlags = "ModeFlags" / FlagsEnum(Int8ub,
                                    AUTO=0x00,
                                    MANUAL=0x01,
                                    AWAY=0x02,
                                    BOOST=0x04,
                                    DST=0x08,
                                    WINDOW=0x10,
                                    LOCKED=0x20,
                                    UNKNOWN=0x40,
                                    LOW_BATTERY=0x80)


class AwayDataAdapter(Adapter):
    """ Adapter to encode and decode away data. """
    def _decode(self, obj, ctx):
        (day, year, hour_min, month) = struct.unpack("BBBB", obj)
        year += 2000

        min = 0
        if hour_min & 0x01:
            min = 30
Example #10
0
    FLG_VOLTEX = 0x1000,
    FLG_ZLIB = 0x80000000,
    FLG_ZSTD = 0x20000000
} FLG_CONTIGUOUS_MIP;
'''
ddsx_flags_enum = FlagsEnum(Int32ul,
                            FLG_7ZIP=0x40000000,
                            FLG_ADDRU_MASK=0xf,
                            FLG_ADDRV_MASK=0xf0,
                            FLG_ARRTEX=0x200000,
                            FLG_COMPR_MASK=0xe0000000,
                            FLG_CONTIGUOUS_MIP=0x100,
                            FLG_CUBTEX=0x800,
                            FLG_GAMMA_EQ_1=0x8000,
                            FLG_GENMIP_BOX=0x2000,
                            FLG_GENMIP_KAIZER=0x4000,
                            FLG_GLES3_TC_FMT=0x100000,
                            FLG_HASBORDER=0x400,
                            FLG_HOLD_SYSMEM_COPY=0x10000,
                            FLG_HQ_PART=0x80000,
                            FLG_NEED_PAIRED_BASETEX=0x20000,
                            FLG_NONPACKED=0x200,
                            FLG_OODLE=0x60000000,
                            FLG_REV_MIP_ORDER=0x40000,
                            FLG_VOLTEX=0x1000,
                            FLG_ZLIB=0x80000000,
                            FLG_ZSTD=0x20000000)
'''
struct Header {
    uint label;
    uint d3dFormat;
    uint flags;
Example #11
0
RGB = Struct(
    "red" / Default(Byte, 0),
    "green" / Default(Byte, 0),
    "blue" / Default(Byte, 0),
)

Color = Struct(
    Embedded(RGB),
    "white" / Default(Byte, 0),
    "brightness" / Default(Byte, 0),
)

WeekDayEnum = FlagsEnum(Byte,
                        sun=0x01,
                        mon=0x02,
                        tue=0x04,
                        wed=0x08,
                        thu=0x10,
                        fri=0x20,
                        sat=0x40)

Alarm = Struct(
    "id" / Byte,  # 1-6, 6 = wake up fall sleep mode, ff = end of list
    Embedded(HourMinuteSecond),
    "mode" / Enum(Byte, Single=0x01, RepeatDaily=0x02, RepeatOnDays=0x03),
    "days" / Switch(
        this.mode,
        {
            "Single": RawAsInt(Byte),  # date in BCD
            "RepeatDaily": Byte,
            "RepeatOnDays": WeekDayEnum,
        },
Example #12
0
class FNVPlugin(BasePlugin):
    """The plugin for Fallout: New Vegas.

    This plugin structure *should* handle plugins for the games:
        - Fallout 3
        - Fallout: New Vegas

    Note:
        This structure *currently* reads all data on initialization.
        This may appear as *slower* initialization times for larger plugins.
        Should be fixed by
        `lazy constructs <https://construct.readthedocs.io/en/latest/lazy.html>`_
        when they become more stable.

    **Credit:**
        - `FopDoc <https://tes5edit.github.io/fopdoc/FalloutNV/Records.html>`_
    """

    subrecord_struct = Struct(
        "type" / PaddedString(4, "utf8"),
        "data_size" / Int16ul,
        "data" / Bytes(lambda this: this.data_size),
        "parsed"
        / Computed(
            lambda this: FNVPlugin.parse_subrecord(
                this._.id, this._.type, this.type, this.data
            )
        ),
    )
    """The structure for FO3/FNV subrecords.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV subrecords
    """

    record_struct = Struct(
        "type" / PaddedString(4, "utf8"),
        "data_size" / Int32ul,
        "flags"
        / FlagsEnum(
            Int32ul,
            master=0x00000001,
            _unknown_0=0x00000002,
            _unknown_1=0x00000004,
            _unknown_2=0x00000008,
            form_initialized=0x00000010,
            deleted=0x00000020,
            constant=0x00000040,
            fire_disabled=0x00000080,
            inaccessible=0x00000100,
            casts_shadows=0x00000200,
            persistent=0x00000400,
            initially_disabled=0x00000800,
            ignored=0x00001000,
            no_voice_filter=0x00002000,
            cannot_save=0x00004000,
            visible_when_distant=0x00008000,
            random_anim_start=0x00010000,
            dangerous=0x00020000,
            compressed=0x00040000,
            cant_wait=0x00080000,
            _unknown_3=0x00100000,
            _unknown_4=0x00200000,
            _unknown_5=0x00400000,
            _unknown_6=0x00800000,
            destructible=0x01000000,
            obstacle=0x02000000,
            navmesh_filter=0x04000000,
            navmesh_box=0x08000000,
            non_pipboy=0x10000000,
            child_can_use=0x20000000,
            navmesh_ground=0x40000000,
            _unknown_7=0x80000000,
        ),
        "id" / Int32ul,
        "revision" / Int32ul,
        "version" / Int16ul,
        "_unknown_0" / Int16ul,
        # NOTE: ignores compressed data size as it is handled by GreedyBytes
        If(lambda this: this.flags.compressed, Padding(4)),
        "data"
        / IfThenElse(
            lambda this: this.flags.compressed,
            Compressed(Bytes(lambda this: this.data_size), "zlib"),
            Bytes(lambda this: this.data_size),
        ),
        "subrecords"
        / Computed(
            lambda this: GreedyRange(FNVPlugin.subrecord_struct).parse(
                this.data, id=this.id, type=this.type
            )
        ),
    )
    """The structure for FO3/FNV records.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV records
    """

    # TODO: instead of using ``GreedyRange`` to handle parsing unknown length lists,
    # should probably use other repeaters to avoid messy construct debugging
    # (will always raise exception when expects record type to exist, but gets 0 bytes)
    group_struct = Struct(
        "type" / Const(b"GRUP"),
        "group_size" / Int32ul,
        # TODO: find a better way of lazily building ``label`` in place
        # instead of computing it later
        # NOTE: deferred until group_type is determined
        "_label" / Bytes(4),
        "group_type"
        / Enum(
            Int32sl,
            top_level=0,
            world_children=1,
            interior_cell_block=2,
            interior_cell_subblock=3,
            exterior_cell_block=4,
            exterior_cell_subblock=5,
            cell_children=6,
            topic_children=7,
            cell_persistent_children=8,
            cell_temporary_children=9,
            cell_visible_distant_children=10,
        ),
        "label"
        / Computed(
            lambda this: Switch(
                this.group_type,
                {
                    "top_level": PaddedString(4, "utf8"),
                    "world_children": FNVFormID(["WRLD"]),
                    "interior_cell_block": Int32sl,
                    "interior_cell_subblock": Int32sl,
                    "exterior_cell_block": Struct("y" / Int8sl, "x" / Int8sl),
                    "exterior_cell_subblock": Struct("y" / Int8sl, "x" / Int8sl),
                    "cell_children": FNVFormID(["CELL"]),
                    "topic_children": FNVFormID(["DIAL"]),
                    "cell_persistent_children": FNVFormID(["CELL"]),
                    "cell_temporary_children": FNVFormID(["CELL"]),
                    "cell_visible_distant_children": FNVFormID(["CELL"]),
                },
                default=GreedyBytes,
            ).parse(this._label)
        ),
        "stamp" / Int16ul,
        "_unknown_0" / Bytes(6),
        "data" / Bytes(lambda this: this.group_size - 24),
        "subgroups"
        / If(
            lambda this: (len(this.data) > 4 and this.data[:4] == b"GRUP"),
            Computed(
                lambda this: GreedyRange(
                    LazyBound(lambda: FNVPlugin.group_struct)
                ).parse(this.data)
            ),
        ),
        "records"
        / If(
            lambda this: this.subgroups is None,
            Computed(
                lambda this: GreedyRange(FNVPlugin.record_struct).parse(this.data)
            ),
        ),
    )
    """The structure for FO3/FNV groups.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV groups
    """

    plugin_struct = Struct(
        "header" / record_struct * "Plugin header record",
        "groups" / GreedyRange(group_struct) * "Plugin groups",
    )
    """The structure for FO3/FNV plugins.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV plugins
    """

    # NOTE: working record is mangaled in order to protect state during
    # subrecord parsing for record state
    __working_record = {}

    @classmethod
    def can_handle(cls, filepath: str) -> bool:
        """Determines if a given file can be handled by the plugin.

        Args:
            filepath (str): The filepath to evaluate

        Raises:
            FileNotFoundError: When the given `filepath` cannot be found

        Returns:
            bool: True if file can be handled, otherwise False
        """

        if not os.path.isfile(filepath):
            raise FileNotFoundError(f"file {filepath!r} does not exist")

        header = cls.record_struct.parse_file(filepath)

        # NOTE: must clear class working record after every "full" file parse
        # otherwise, subsequent parses will have fragmented data when trying to discover
        # and parse subrecords
        cls.__working_record = {}
        return header.type == "TES4" and header.version == 15

    @classmethod
    def parse_subrecord(
        cls,
        record_id: int,
        record_type: str,
        subrecord_type: str,
        subrecord_data: bytes,
        strict: bool = True,
    ) -> Container:
        """Parses a subrecord's data.

        Args:
            record_type (str): The parent record type
            subrecord_type (str): The subrecord type
            subrecord_data (bytes): The subrecord data to parse
            strict (bool): Defaults to True, If True, enforce strict subrecord discovery

        Returns:
            Container: The resulting parsed container
        """

        (record_type, subrecord_type) = (record_type.upper(), subrecord_type.upper())

        # handle reset of working record state
        if record_id not in cls.__working_record:
            cls.__working_record[record_id] = []

        record_subrecords = RecordMapping.get(record_type)
        if record_subrecords:
            (parsed, working_record) = record_subrecords.handle_working(
                subrecord_type,
                subrecord_data,
                cls.__working_record[record_id],
                strict=strict,
            )
            cls.__working_record[record_id].extend(working_record)
            return parsed
Example #13
0
DXGI_FORMAT = Enum(Int32ul, DXGIFormats)
"""The ``DXGI_FORMAT`` structure.

**Reference**:
    `Microsoft <https://goo.gl/zast7X>`__
"""

D3D10_RESOURCE_DIMENSION = Enum(Int32ul, D3D10ResourceDimension)
"""The ``D3D10_RESOURCE_DIMENSION`` structure.

**Reference**:
    `Microsoft <https://goo.gl/ijDpqi>`__
"""

D3D10_RESOURCE_MISC_FLAG = FlagsEnum(Int32ul, D3D10ResourceMiscFlag)
"""The ``D3D10_RESOURCE_MISC_FLAG`` structure.

**Reference**:
    `Microsoft <https://goo.gl/MazAYd>`__
"""

DDS_PIXELFORMAT = Struct(
    "dwSize" / Const(32, Int32ul),
    "dwFlags" / Default(
        FlagsEnum(
            Int32ul,
            DDPF_ALPHAPIXELS=0x00000001,
            DDPF_ALPHA=0x00000002,
            DDPF_FOURCC=0x00000004,
            DDPF_RBG=0x00000040,
Example #14
0
                          WCEMIPSV2=0x169,
                          _default_=Pass),
    "number_of_sections" / Int16ul,
    "time_stamp" / UTCTimeStamp(),
    "symbol_table_pointer" / Int32ul,
    "number_of_symbols" / Int32ul,
    "optional_header_size" / Int16ul,
    "characteristics" / FlagsEnum(
        Int16ul,
        RELOCS_STRIPPED=0x0001,
        EXECUTABLE_IMAGE=0x0002,
        LINE_NUMS_STRIPPED=0x0004,
        LOCAL_SYMS_STRIPPED=0x0008,
        AGGRESSIVE_WS_TRIM=0x0010,
        LARGE_ADDRESS_AWARE=0x0020,
        MACHINE_16BIT=0x0040,
        BYTES_REVERSED_LO=0x0080,
        MACHINE_32BIT=0x0100,
        DEBUG_STRIPPED=0x0200,
        REMOVABLE_RUN_FROM_SWAP=0x0400,
        SYSTEM=0x1000,
        DLL=0x2000,
        UNIPROCESSOR_ONLY=0x4000,
        BIG_ENDIAN_MACHINE=0x8000,
    ),

    # symbol table
    "symbol_table" / Pointer(this.symbol_table_pointer,
                             Array(this.number_of_symbols, symbol_table)))


def PEPlusField():
Example #15
0
    "EraSpecific": 128
}
"""Used by Enum substruct"""
XvdType = {"Fixed": 0, "Dynamic": 1}
"""Substruct of XvdFileHeader"""
XvdExtEntry = Struct("code" / Int32ul, "length" / Int32ul, "offset" / Int64ul,
                     "data_length" / Int32ul, "reserved" / Int32ul)

XVD_KEY_SIZE = 32
SANDBOX_ID_SIZE = 16

XVD_HEADER_SIZE = 0x1000
XvdFileHeader = Struct(
    "signature" / Bytes(0x200),  # 0x00 - 0x200
    "magic" / Bytes(8),  # 0x200
    "volume_flags" / FlagsEnum(Int32ul, **XvdVolumeFlags),  # 0x208
    "format_version" / Int32ul,  # 0x20C
    "filetime_created" / FILETIMEAdapter(),  # 0x210
    "drive_size" / Int64ul,  # 0x218
    "content_id" / UUIDAdapter(),  # 0x220
    "user_id" / UUIDAdapter(),  # 0x230
    "root_hash" / Bytes(HASH_SIZE),  # 0x240
    "xvc_hash" / Bytes(HASH_SIZE),  # 0x260
    "xvd_type" / CEnum(Int32ul, **XvdType),  # 0x280
    "content_type" / Int32ul,  # 0x284
    "embedded_xvd_length" / Int32ul,  # 0x288
    "userdata_length" / Int32ul,  # 0x28C
    "xvc_length" / Int32ul,  # 0x290
    "dynamic_header_length" / Int32ul,  # 0x294
    "block_size" / Int32ul,  # 0x298
    "ext_entry" / Array(4, XvdExtEntry),  # 0x29C
Example #16
0
    def _decode(self, obj, context, path):
        return float((obj - 7) / 2.0)

    def _encode(self, obj, context, path):
        if -3.5 <= obj <= 3.5:
            return int(obj * 2.0) + 7
        raise ValueError("Temperature offset must be between -3.5 and 3.5 (in "
                         "intervals of 0.5).")


ModeFlags = "ModeFlags" / FlagsEnum(
    Int8ub,
    AUTO=0x00,  # always True, doesnt affect building
    MANUAL=0x01,
    AWAY=0x02,
    BOOST=0x04,
    DST=0x08,
    WINDOW=0x10,
    LOCKED=0x20,
    UNKNOWN=0x40,
    LOW_BATTERY=0x80,
)


class AwayDataAdapter(Adapter):
    """ Adapter to encode and decode away data. """
    def _decode(self, obj, ctx, path):
        (day, year, hour_min, month) = obj
        year += 2000

        min = 0
        if hour_min & 0x01:
Example #17
0
            Bytes(this.numSymbols * symbol.sizeof()),
    ),


    "stringTable" / Pointer( (this.filePoimter + (this.numSymbols * symbol.sizeof()) + 0),
            ListToBytesAdapter(GreedyRange(Byte))
    ),


    "sizeOptHeader" / Int16ul,

    "flags"  / FlagsEnum(Int16ul,
        F_RELFLG    = 0x0001,
        F_EXEC      = 0x0002,
        F_LNNO      = 0x0004,
        F_LSYMS     = 0x0008,
        F_LITTLE    = 0x0100,
        F_BIG       = 0x0200,
        F_SYMMERGE  = 0x1000,
    ),

    "targetID" / Enum(Int16ul,
        TMS470          = 0x0097,
        TMS320C5400     = 0x0098,
        TMS320C6000     = 0x0099,
        TMS320C5500     = 0x009C,
        TMS320C2800     = 0x009D,
        MSP430          = 0x00A0,
        TMS320C5500plus = 0x00A1,
    ),
Example #18
0
            code_data_hash=Bytes(32),
            full_hash=Bytes(32),
            name=PascalString(Int8ub, "utf-8"),
        )
    ),
)

VersionInfo = Struct(
    target_id=Hex(Int32ub),
    se_version=PascalString(Int8ub, "utf-8"),
    _flags_len=Const(b"\x04"),
    flags=FlagsEnum(
        Int32ul,
        recovery_mode=1,
        signed_mcu=2,
        is_onboarded=4,
        trust_issuer=8,
        trust_custom_ca=16,
        hsm_initialized=32,
        pin_validated=128,
    ),
    mcu_version=PascalString(Int8ub, "utf-8"),
    mcu_hash=Optional(Bytes(32)),
)


class AppInfo(object):
    def __init__(
        self,
        name: str,
        flags: int,
        code_data_hash: bytes,
Example #19
0
    lambda obj, ctx: ctx.ports_table.index(obj))

FilesystemQueryVolumeInformationOperationType = Enum(
    Int8ul, FilesystemQueryVolumeInformationOperation)
FilesystemSetVolumeInformationOperationType = Enum(
    Int8ul, FilesystemSetVolumeInformationOperation)
FilesystemQueryInformationOperationType = Enum(
    Int8ul, FilesystemQueryInformationOperation)
FilesystemDirectoryControlOperationType = Enum(
    Int8ul, FilesysemDirectoryControlOperation)
FilesystemSetInformationOperationType = Enum(
    Int8ul, FilesystemSetInformationOperation)
FilesystemPnpOperationType = Enum(Int8ul, FilesystemPnpOperation)
FilesystemLockUnlockOperationType = Enum(Int8ul, FilesystemLockUnlockOperation)
NetworkOperationFlags = FlagsEnum(Int16ul,
                                  is_source_ipv4=1,
                                  is_dest_ipv4=2,
                                  is_tcp=4)
DetailStringInfo = ByteSwapped(
    BitStruct("is_ascii" / Bit, "char_count" / BitsInteger(15)))


def DetailString(detail_info_func):
    """Strings in the specific detail structure are described by a flags field and a length field
    """
    return IfThenElse(
        lambda ctx: detail_info_func(ctx).is_ascii,
        PaddedString(lambda ctx: detail_info_func(ctx).char_count, "ascii"),
        PaddedString(lambda ctx: detail_info_func(ctx).char_count * 2,
                     "UTF_16_le"))

Example #20
0
from construct import \
    Struct, Array, Byte, Bytes, CString, Int16ub, Int24ub, Int32ub, \
    Const, GreedyBytes, FlagsEnum, IfThenElse, Padding, Check, this, sum_
from constructutils import InliningStruct, Inline


# ref:
#   http://wiiubrew.org/wiki/FST
#   https://github.com/ihaveamac/wiiu-things/wiki/FST
_entry = InliningStruct(
    'type' / FlagsEnum(Byte, directory=0x01, special=0x02, deleted=0x80),
    'name_offset' / Int24ub,
    Inline(IfThenElse(
        this.type.directory,
        Struct(
            'parent_offset' / Int32ub,
            'next_entry_index' / Int32ub  # index of next entry not belonging to this directory anymore (i.e. index of last entry + 1)
        ),
        Struct(
            'offset_raw' / Int32ub,
            'size' / Int32ub
        )
    )),
    'flags' / FlagsEnum(Int16ub, offset_in_bytes=0x0004, hashed_meta=0x0040, hashed_content=0x0400),
    'secondary_index' / Int16ub
)

struct = Struct(
    Const(b'FST\0'),
    'offset_factor' / Int32ub,
    'num_secondary' / Int32ub,
Example #21
0
class BSAArchive(BaseArchive):
    """Archive type for BSA files.

    BSA stands for "Bethesda ? Archive".
    These archives are compressed meshes, textures and other static resources that can
    be loaded as a single file instead of a directory of files (loose files).

    There are currently 4 versions of BSA:
        - ???: Morrowind
        - 103: Oblivion
        - 104: Fallout 3, Fallout: New Vegas, and Skyrim
        - 105: Skyrim: Special Edition

    Note:
        BSA archives to not read the file data on initialization.
        Header's, records and names are read in and files are built during
        :func:`~BSAArchive.iter_files`.

    **Credit:**
        - `BAE <https://github.com/jonwd7/bae>`_
    """

    SIZE_MASK = 0x3fffffff
    COMPRESSED_MASK = 0xc0000000

    header_struct = Struct(
        "magic" / Bytes(4),
        "version" / Int32ul,
        "directory_offset" / Int32ul,
        "archive_flags" / FlagsEnum(
            Int32ul,
            directories_named=0x001,
            files_named=0x002,
            files_compressed=0x004,
            _unknown_0=0x008,
            _unknown_1=0x010,
            _unknown_2=0x020,
            xbox360_archive=0x040,
            files_prefixed=0x100,
            _unknown_4=0x200,
            _unknown_5=0x400,
        ),
        "directory_count" / Int32ul,
        "file_count" / Int32ul,
        "directory_names_length" / Int32ul,
        "file_names_length" / Int32ul,
        "file_flags" / FlagsEnum(
            Int32ul,
            nif=0x001,
            dds=0x002,
            xml=0x004,
            wav=0x008,
            mp3=0x010,
            txt=0x020,
            html=0x020,
            bat=0x020,
            scc=0x020,
            spt=0x040,
            tex=0x080,
            fnt=0x080,
            ctl=0x100,
        ),
    )
    """The structure of BSA headers.

    Returns:
        :class:`~construct.core.Struct`: The structure of BSA headers
    """

    directory_record_struct = Struct(
        "hash" / Int64ul,
        "file_count" / Int32ul,
        "_unknown_0" / If(lambda this: this._.header.version >= 105, Int32ul),
        "name_offset" / IfThenElse(lambda this: this._.header.version >= 105,
                                   Int64ul, Int32ul),
    )
    """The structure of directory records.

    Returns:
        :class:`~construct.core.Struct`: The structure of directory records
    """

    file_record_struct = Struct("hash" / Int64ul, "size" / Int32ul,
                                "offset" / Int32ul)
    """The structure of file records.

    Returns:
        :class:`~construct.core.Struct`: The structure of file records
    """

    directory_block_struct = Struct(
        "name" / If(
            lambda this: this._.header.archive_flags.directories_named,
            PascalString(VarInt, "utf8"),
        ),
        "file_records" / Array(
            lambda this: this._.directory_records[this._._index].file_count,
            file_record_struct,
        ),
    )
    """The structure of directory blocks.

    Returns:
        :class:`~construct.core.Struct`: The structure of directory blocks
    """

    archive_struct = Struct(
        "header" / header_struct,
        "directory_records" / Array(lambda this: this.header.directory_count,
                                    directory_record_struct),
        "directory_blocks" / Array(lambda this: this.header.directory_count,
                                   directory_block_struct),
        "file_names" / If(
            lambda this: this.header.archive_flags.files_named,
            Array(lambda this: this.header.file_count, CString("utf8")),
        ),
    )
    """The **partial** structure of BSA archives.

    Return:
        :class:`~construct.core.Struct`: The **partial** structure of BSA archives
    """
    @property
    def uncompressed_file_struct(self) -> Struct:
        """The uncompressed file structure for uncompressed files.

        Returns:
            :class:`~construct.core.Struct`: The uncompressed file structure for
            uncompressed files.
        """
        return Struct("data" / GreedyBytes)

    @property
    def compressed_file_struct(self) -> Struct:
        """The compressed file structure for compressed files.

        Returns:
            :class:`~construct.core.Struct`: The compressed file structure for
            compressed files.
        """
        return Struct(
            "original_size" / Int32ul,
            "data" / IfThenElse(
                self.container.header.version >= 105,
                LZ4CompressedAdapter(GreedyBytes),
                Compressed(GreedyBytes, "zlib"),
            ),
        )

    @classmethod
    def can_handle(cls, filepath: str) -> bool:
        """Determines if a given file can be handled by the current archive.

        Args:
            filepath (str): The filepath to check if can be handled
        """

        header = cls.header_struct.parse_file(filepath)
        return header.magic == b"BSA\x00" and header.version in (103, 104, 105)

    def iter_files(self) -> Generator[ArchiveFile, None, None]:
        """Iterates over the parsed data and yields instances of :class:`.ArchiveFile`.

        Yields:
            :class:`.ArchiveFile`: An file contained within the archive
        """

        file_index = 0
        file_struct = self.uncompressed_file_struct
        if self.container.header.archive_flags.files_compressed:
            file_struct = self.compressed_file_struct

        for directory_block in self.container.directory_blocks:
            # get directory path from directory block
            directory_path = PureWindowsPath(directory_block.name[:-1])
            for file_record in directory_block.file_records:
                # choose the compressed file structure if compressed mask is set
                if file_record.size > 0 and (
                        self.container.header.archive_flags.files_compressed !=
                        bool(file_record.size & self.COMPRESSED_MASK)):
                    file_struct = self.compressed_file_struct

                file_container = file_struct.parse(
                    self.content[file_record.offset:(
                        file_record.offset +
                        (file_record.size & self.SIZE_MASK))])

                yield ArchiveFile(
                    filepath=directory_path.joinpath(
                        self.container.file_names[file_index]),
                    data=file_container.data,
                )

                file_index += 1
Example #22
0

Bip32Path = Bip32PathAdapter(PrefixedArray(Byte, Int32ub))

PrefixedString = PascalString(Asn1Length, "utf8")

AppName = PrefixedString
Version = PrefixedString
Icon = Prefixed(Asn1Length, GreedyBytes)

CURVE_SEPCK256K1 = 1
CURVE_PRIME256R1 = 2
CURVE_ED25519 = 4

Curve = FlagsEnum(
    Byte, secp256k1=CURVE_SEPCK256K1, prime256r1=CURVE_PRIME256R1, ed25519=CURVE_ED25519
)

DerivationPath = Prefixed(
    Asn1Length, Struct(curve=Curve, paths=Optional(GreedyRange(Bip32Path)))
)

Dependency = Prefixed(
    Asn1Length, Struct(name=PrefixedString, version=Optional(PrefixedString))
)

Dependencies = Prefixed(Asn1Length, GreedyRange(Dependency))


class BolosTag(enum.IntEnum):
    BOLOS_TAG_APPNAME = 1
Example #23
0
# These should really be combined into a single Sequence, but using Embed on a GreedyRange containing the second
# Struct, 'report', caused some type of error I wasn't able to chase down. Also, the 'types' byte must be a raw value
# (and, subsequently, Report.Types must subclass int) because of a bug between Const & FlagsEnum:
# https://github.com/construct/construct/issues/73

admin_report = Struct(
    "admin", Const(UBInt16("length"), 13), Const(Byte("ID"), 1),
    Const(Byte("types"), 4),
    Const(PascalString("name", length_field=Byte("length"), encoding="utf8"),
          "admin"),
    Struct("version", Byte("major"), Byte("minor"), Byte("patch")))

HID_report = OptionalGreedyRange(
    Struct(
        "report", UBInt16("length"), Byte("ID"),
        FlagsEnum(Byte("types"), feature=4, output=2, input=1),
        PascalString("name", length_field=Byte("length"), encoding="utf8"),
        Array(
            lambda ctx: ctx.length - (len(ctx.name) + 1) - 4,
            BitStruct(
                "serialization", BitField("length", 6),
                Enum(BitField("type", 2), utf8=0, Uint=1, Int=2, Float=3)))))


def hexstring_to_bytearray(string):
    return bytearray([int(pair.strip(','), 16) for pair in string.split(" ")])


def serialize(data):
    if hasattr(data[0], 'version'):
        return admin_report.build(data[0]) + HID_report.build(data[1:])