Example #1
0
def get_user_definition(settings):
    if (
        settings.system_options.user_code_length_6
        or settings.system_options.user_code_length_flexible
    ):
        code = ExprAdapter(
            Bytes(3),
            lambda obj, path: binascii.hexlify(obj)
            .decode()
            .rstrip("0")
            .replace("a", "0")
            or None,
            lambda obj, path: binascii.unhexlify(obj.replace("0", "a")),
        )
    else:
        code = ExprAdapter(
            Bytes(3),
            lambda obj, path: binascii.hexlify(obj)
            .decode()
            .rstrip("0")
            .replace("a", "0")[:4]
            or None,
            lambda obj, path: binascii.unhexlify((obj + obj[:2]).replace("0", "a")),
        )

    return Struct(
        "code" / code,
        "options"
        / BitsSwapped(
            BitStruct(
                "type" / Enum(BitsInteger(2), FullMaster=0x3, Master=0x2, Regular=0x0),
                "duress" / Flag,
                "bypass" / Flag,
                "arm_only" / Flag,
                "stay_instant_arming" / Flag,
                "force_arming" / Flag,
                "all_subsystems" / Flag,
            )
        ),
        "partitions" / BitsSwapped(Bitwise(StatusFlags(8))),
        "access" / BitStruct("level" / Nibble, "schedule" / Nibble),
        "access_options" / Bytes(1),
        "card_serial_number" / Bytes(3),
    )
Example #2
0
class USBTokenPacket(USBPacket):
    """ Class representing a token packet. """

    FIELDS = {'crc5', 'crc_valid'}

    DATA_FORMAT = BitsSwapped(
        BitStruct(
            "device_address" / BitsInteger(7),
            "endpoint_number" / BitsInteger(4),
            "crc5" / BitsInteger(5),
        ))

    def validate(self):
        #parsed = self.parse_data()
        # TODO: validate crc5
        pass

    def generate_summary(self):
        return "{} token".format(self.pid.summarize())

    def summarize_data(self, summary_length_bytes=8):
        # NOTE: summary_length_bytes is ignored for a token packet.
        return "address={}, endpoint=0x{:02x}, direction={}".format(
            self.device_address, self.endpoint_number, self.direction)

    def get_detail_fields(self):

        fields = {
            'Length': '{} bytes'.format(len(self.get_raw_data())),
            'PID': '{} (0x{:02x})'.format(self.pid.name, self.pid.value),
            'Device': '0x{:02x}'.format(self.device_address),
            'Endpoint': '0x{:02x}'.format(self.endpoint_number),
            'CRC5': '0x{:02x}'.format(self.crc5)
        }

        return [(self.generate_summary(), fields)]

    def get_raw_data(self):
        # device_address, endpoint, and crc5 are included in self.data.
        return b''.join([bytes([self.pid]), self.data])
Example #3
0
class USBStartOfFrame(USBPacket):
    """ Class representing a USB start-of-frame (pseudo) packet. """

    FIELDS = {'frame_number', 'crc5', 'crc_valid'}

    DATA_FORMAT = BitsSwapped(
        BitStruct(
            "frame_number" / BitsInteger(11),
            "crc5" / BitsInteger(5),
        ))

    def validate(self):
        #parsed = self.parse_data()
        # TODO: validate crc5
        pass

    def generate_summary(self):
        return "{}".format(self.pid.summarize())

    def summarize_data(self, summary_length_bytes=8):
        # NOTE: summary_length_bytes is ignored for a token packet.
        return "frame={}".format(self.frame_number)

    def get_detail_fields(self):

        fields = {
            'Length': '{} bytes'.format(len(self.get_raw_data())),
            'PID': '{} (0x{:02x})'.format(self.pid.name, self.pid.value),
            'Frame Number': '{:0d}'.format(self.frame_number),
            'CRC5': '0x{:02x}'.format(self.crc5)
        }

        return [(self.generate_summary(), fields)]

    def get_raw_data(self):
        # frame number, and crc5 are included in self.data.
        return b''.join([bytes([self.pid]), self.data])
Example #4
0
 "system_options" / BitsSwapped(
     BitStruct(
         Embedded(
             Struct(  # EVO section data 3030
                 "pgm1_smoke" / Flag,
                 "no_bell_cut_off" / Flag,
                 "daylight_saving_time" / Flag,
                 "shabbat_feature" / Flag,
                 "battery_charge_current" / Flag,
                 "ac_failure_not_displayed_as_trouble" / Flag,
                 "clear_bell_limit_trouble" / Flag,
                 "combus_speed" / Flag,
             )),
         "partitions" / StatusFlags(8),  # EVO section data 3031
         "siren_output_partition" /
         StatusFlags(8),  # EVO section data 3032
         Embedded(
             Struct(  # EVO section data 3033
                 "multiple_actions_user_menu" / Flag,
                 "user_code_length_flexible" / Flag,
                 "user_code_length_6" / Flag,
                 "power_save_mode" / Flag,
                 "bypass_not_displayed_when_armed" / Flag,
                 "trouble_latch" / Flag,
                 "eol_resistor_on_harwire_zones" / Flag,
                 "atz" / Flag,
             )),
         Embedded(
             Struct(  # EVO section data 3034
                 "wireless_transmitter_supervision_options" /
                 BitsInteger(2),
                 "generate_supervision_failure_on_bypassed_wireless_zone"
                 / Flag,
                 "restrict_arming_on_wireless_transmitter_supervision_failure"
                 / Flag,
                 "tamper_recognition_options" / BitsInteger(2),
                 "generate_tamper_if_detected_on_bypassed_zone" /
                 Flag,
                 "restrict_arming_on_tamper" / Flag,
             )),
         Embedded(
             Struct(  # EVO section data 3035
                 "restrict_arming_on_ac_failure" / Flag,
                 "restrict_arming_on_battery_failure" / Flag,
                 "restrict_arming_on_bell_or_aux_failure" / Flag,
                 "restrict_arming_on_tlm_failure" / Flag,
                 "restrict_arming_on_module_troubles" / Flag,
                 "account_number_transmission" / Flag,
                 "transmit_zone_status_on_serial_port" / Flag,
                 "serial_port_baud_rate_57600" / Flag,
             )),
         Embedded(
             Struct(  # EVO section data 3036
                 "telephone_line_monitoring" / BitsInteger(2),
                 "dialer_reporting" / Flag,
                 "dialing_method" / Flag,
                 "pulse_ratio" / Flag,
                 "busy_tone_detection" / Flag,
                 "switch_to_pulse_dialing" / Flag,
                 "bell_siren_upon_communication_failure" / Flag,
             )),
         Embedded(
             Struct(  # EVO section data 3037
                 "call_back" / Flag,
                 "automatic_event_buffer_transmission" / Flag,
                 "autotest_report_transmission_options" /
                 BitsInteger(2),
                 "keypad_beep_on_successful_arming_disarming_report"
                 / Flag,
                 "alternate_dialing" / Flag,
                 "dial_tone_delay" / Flag,
                 "report_zone_restore" / Flag,
             )),
         Embedded(
             Struct(  # EVO section data 3038
                 "access_control_feature" / Flag,
                 "log_request_for_exit" / Flag,
                 "log_door_left_open_restore" / Flag,
                 "log_door_forced_restore" / Flag,
                 "bulglar_alarm_on_forced_door" / Flag,
                 "skip_exit_delay_when_arming_with_access_card" /
                 Flag,
                 "bulglar_alarm_on_door_left_open" / Flag,
                 "who_has_access_during_clock_loss" / Flag,
             )),
     )),
Example #5
0
    class Reparsed(Adapter):
        """Bytes <---> Parsed subcon result
        Takes in bytes and reparses it with subcon_out"""

        def _decode(self, data, con, path):
            return subcon_out.parse(data, **con)

        def _encode(self, obj, con, path):
            return subcon_out.build(obj, **con)

    return Reparsed


# is the payload compressed?
CompressionFlags = BitsSwapped(
    BitStruct("compression" / Flag, Padding(8 * 4 - 1))
)


# -------------------- Key Computation --------------------
def aes_kdf(key, rounds, key_composite):
    """Set up a context for AES128-ECB encryption to find transformed_key"""

    cipher = AES.new(key, AES.MODE_ECB)

    # get the number of rounds from the header and transform the key_composite
    transformed_key = key_composite
    for _ in range(0, rounds):
        transformed_key = cipher.encrypt(transformed_key)

    return hashlib.sha256(transformed_key).digest()
Example #6
0
            "ItemIDList" / GreedyRange(
                Struct(
                    "ItemIDSize" / Int16ul,
                    "Data" / Bytes(this.ItemIDSize - 2),
                )), "TerminalID" / Int16ul)),
)

ShellLinkHeader = "ShellLinkHeader" / Struct(
    "HeaderSize" / Int32ul, "LinkCLSID" / Bytes(16), "LinkFlags" / BitsSwapped(
        BitStruct("HasLinkTargetIDList" / Flag, "HasLinkInfo" / Flag,
                  "HasName" / Flag, "HasRelativePath" / Flag, "HasWorkingDir" /
                  Flag, "HasArguments" / Flag, "HasIconLocation" / Flag,
                  "IsUnicode" / Flag, "ForceNoLinkInfo" / Flag,
                  "HasExpString" / Flag, "RunInSeparateProcess" / Flag,
                  "Unused1" / Flag, "HasDarwinID" / Flag, "RunAsUser" / Flag,
                  "HasExpIcon" / Flag, "NoPidlAlias" / Flag, "Unused2" / Flag,
                  "RunWithShimLayer" / Flag, "ForceNoLinkTrack" / Flag,
                  "EnableTargetMetadata" / Flag, "DisableLinkPathTracking" /
                  Flag, "DisableKnownFolderTracking" / Flag,
                  "DisableKnownFolderAlias" / Flag, "AllowLinkToLink" / Flag,
                  "UnaliasOnSave" / Flag, "PreferEnvironmentPath" / Flag,
                  "KeepLocalIDListForUNCTarget" / Flag, Flag, Flag, Flag, Flag,
                  Flag)),
    "FileAttributes" / BitsSwapped(
        BitStruct(
            "FILE_ATTRIBUTE_READONLY" / Flag, "FILE_ATTRIBUTE_READONLY" / Flag,
            "FILE_ATTRIBUTE_SYSTEM" / Flag, "Reserved1" / Flag,
            "FILE_ATTRIBUTE_DIRECTORY" / Flag, "FILE_ATTRIBUTE_ARCHIVE" / Flag,
            "Reserved2" / Flag, "FILE_ATTRIBUTE_NORMAL" / Flag,
            "FILE_ATTRIBUTE_TEMPORARY" / Flag, "FILE_ATTRIBUTE_SPARSE_FILE" /
            Flag, "FILE_ATTRIBUTE_REPARSE_POINT" / Flag,
Example #7
0
QUEUE_HEADER_LAYOUT = cStruct(
    Padding(5),
    "account_flags" / ACCOUNT_FLAGS_LAYOUT,
    "head" / Int32ul,
    Padding(4),
    "count" / Int32ul,
    Padding(4),
    "next_seq_num" / Int32ul,
    Padding(4),
)

REQUEST_FLAGS_LAYOUT = BitsSwapped(  # Swap to little endian
    BitStruct(
        "new_order" / Flag,
        "cancel_order" / Flag,
        "bid" / Flag,
        "post_only" / Flag,
        "ioc" / Flag,
        Const(0, BitsInteger(3)),  # Padding
    ))

REQUEST_LAYOUT = cStruct(
    "request_flags" / REQUEST_FLAGS_LAYOUT,
    "open_order_slot" / Int8ul,
    "fee_tier" / Int8ul,
    Padding(5),
    "max_base_size_or_cancel_id" / Int64ul,
    "native_quote_quantity_locked" / Int64ul,
    "order_id" / Bytes(16),
    "open_orders" / Bytes(32),
    "client_order_id" / Int64ul,
Example #8
0
        zones = list([i in obj for i in range(1, 193)])

        return self.subcon._build(zones, stream, context, path)


PerformZoneAction = Struct(
    "fields" / RawCopy(
        Struct(
            "po" / Struct("command" / Const(0xd0, Int8ub)),
            "packet_length" / Rebuild(
                Int8ub, lambda this: this._root._subcons.fields.sizeof() + this
                ._root._subcons.checksum.sizeof()),
            "flags" / ZoneFlagBitStruct,
            "operation" / ZoneActionBitOperation,
            "_not_used" / Padding(2),
            "zones" / ZoneAdapter(BitsSwapped(Bitwise(Array(192, Flag)))),
        )), "checksum" / Checksum(
            Bytes(1), lambda data: calculate_checksum(data), this.fields.data))

PerformZoneActionResponse = Struct(
    "fields" / RawCopy(
        Struct(
            "po" / BitStruct(
                "command" / Const(0xd, Nibble), "status" /
                Struct("reserved" / Flag, "alarm_reporting_pending" / Flag,
                       "Winload_connected" / Flag, "NeWare_connected" / Flag)),
            "packet_length" / Rebuild(
                Int8ub, lambda this: this._root._subcons.fields.sizeof() + this
                ._root._subcons.checksum.sizeof()),
            "flags" / ZoneFlagBitStruct,
            "operation" / ZoneActionBitOperation,
Example #9
0
# RAY Yield Farming
STAKE_INFO_LAYOUT = Struct(
    "state" / Int64ul, "nonce" / Int64ul, "poolLpTokenAccount" / Bytes(32),
    "poolRewardTokenAccount" / Bytes(32), "owner" / Bytes(32),
    "feeOwner" / Bytes(32), "feeY" / Int64ul, "feeX" / Int64ul,
    "totalReward" / Int64ul, "rewardPerShareNet" / BytesInteger(16),
    "lastBlock" / Int64ul, "rewardPerBlock" / Int64ul)

# Serum Open Orders Book
ACCOUNT_FLAGS_LAYOUT = BitsSwapped(  # Swap to little endian
    BitStruct(
        "initialized" / Flag,
        "market" / Flag,
        "open_orders" / Flag,
        "request_queue" / Flag,
        "event_queue" / Flag,
        "bids" / Flag,
        "asks" / Flag,
        Const(0, BitsInteger(57)),  # Padding
    ))

# Serum Open Orders Book
OPEN_ORDERS_LAYOUT = Struct(
    Padding(5),
    "account_flags" / ACCOUNT_FLAGS_LAYOUT,
    "market" / Bytes(32),
    "owner" / Bytes(32),
    "base_token_free" / Int64ul,
    "base_token_total" / Int64ul,
    "quote_token_free" / Int64ul,
Example #10
0
    "Filler_42" / SwappedField,  # 685
    "A Date" / SwappedField,
    "Filler_44" / SwappedField,
    DELISTING_DATE / DateShort,
    "Filler_46" / SwappedField,
    "Filler_47" / SwappedField,
    "Filler_48" / SwappedField,
    "Filler_49" / SwappedField,
    "Filler_50" / SwappedField,
    "Filler_51" / SwappedField,
    "Filler_52" / SwappedField,
    "Filler_53" / SwappedField,
    "Filler_54" / SwappedField,
    "Filler_55" / SwappedField,
    "Filler_56" / SwappedField,
    "Filler_57" / SwappedField,
    "Filler_58" / SwappedField,
    "Filler_59" / SwappedField,
    "Filler_60" / SwappedField,
    "Filler_61" / SwappedField,
    "Filler_62" / SwappedField,
    "Filler_63" / SwappedField,
    "Filler_64" / SwappedField,
    "Filler_65" / SwappedField,
    "Filler_66" / SwappedField,
    "Filler_67" / SwappedField,
    "Space" / Bytes(396),
    "Length" / Int32ul)
SymbolConstruct = Struct("Header" / Bytes(0x4A0),
                         "Entries" / GreedyRange(BitsSwapped(EntryChunk)))
Example #11
0
    HIGH,
    LOW,
    FUT,
    RESERVED,
    MICRO_SEC,
    MILLI_SEC,
    SECOND,
    MINUTE,
    HOUR,
    AUX_1,
    AUX_2,
    TERMINATOR,
)


SwappedField = BitsSwapped(FormatField("<", "f"))

DateShort=BitsSwapped(BitStruct(
    MINUTE / BitsInteger(length=6),  # 38
    HOUR / BitsInteger(length=5),  # 43
    DAY / RevBitsInteger(length=5),  # Bit 48 Byte 6
    MONTH / RevBitsInteger(length=4),  # 52
    YEAR / RevBitsInteger(length=12),
))

Date=BitStruct(
    FUT / BitsInteger(length=1),  # 1
    RESERVED / BitsInteger(length=5),  # 6
    MICRO_SEC / BitsInteger(length=10),  # Bit 16 byte 2
    MILLI_SEC / BitsInteger(length=10),  # 26
    SECOND / BitsInteger(length=6),  # Bit 32 Byte 4
Example #12
0
class SymbolConstructFast:
    header = "Header" / Bytes(0x4A0)
    entry_chunk = BitsSwapped(EntryChunk)

    @classmethod
    def parse(self, bin):
        binentries = bin[0x4A0:]
        num_bytes = len(binentries)
        numits, offset = divmod(num_bytes, 0x488)  # bytes
        result = {}
        result["Header"] = self.header.parse(bin[0:0x4A0])
        result["Entries"] = []
        start = 0x4A0 - offset
        numits = numits + 1
        result["Entries"].append(self.entry_chunk.parse(bin[0x4A0:]))
        entrybin = bin[start:]
        for i in range(numits):
            result["Entries"].append([
                self.entry_chunk.parse(entrybin[(i * 40):(i * 40 + 40)]),
                self.entry_chunk.parse(entrybin[(2 * i * 40):(2 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(3 * i * 40):(3 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(4 * i * 40):(4 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(5 * i * 40):(5 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(6 * i * 40):(6 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(7 * i * 40):(7 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(8 * i * 40):(8 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(9 * i * 40):(9 * i * 40 +
                                                              40)]),
                self.entry_chunk.parse(entrybin[(10 * i * 40):(10 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(11 * i * 40):(11 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(12 * i * 40):(12 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(13 * i * 40):(13 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(14 * i * 40):(14 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(15 * i * 40):(15 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(16 * i * 40):(16 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(17 * i * 40):(17 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(18 * i * 40):(18 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(19 * i * 40):(19 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(20 * i * 40):(20 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(21 * i * 40):(21 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(22 * i * 40):(22 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(23 * i * 40):(23 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(24 * i * 40):(24 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(25 * i * 40):(25 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(26 * i * 40):(26 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(27 * i * 40):(27 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(28 * i * 40):(28 * i * 40 +
                                                               40)]),
                self.entry_chunk.parse(entrybin[(29 * i * 40):(29 * i * 40 +
                                                               40)]),
            ])

        return result
Example #13
0
    def scan(self, data, file, options, expire_at):
        with io.BytesIO(data) as lnk_io:
            lnk_data = lnk_io.read()

        UnicodeString = "UnicodeString" / Struct(
            "Length" / Int32ul,
            "Characters" / StringEncoded(Bytes(this.Length * 2), "utf16"))

        LinkTargetIDList = "LinkTargetIDList" / Struct(
            "IDListSize" / Int16ul, "ItemID" / GreedyRange(
                Struct(
                    "ItemIDSize" / Int16ul,
                    "Data" / Bytes(this.ItemIDSize - 2),
                )), "TerminalID" / Int16ul)

        TypedPropertyValue = "TypedPropertyValue" / Struct(
            "Type" / Enum(Int16ul,
                          VT_EMPTY=0x0000,
                          VT_NULL=0x0001,
                          VT_I2=0x0002,
                          VT_I4=0x0003,
                          VT_R4=0x0004,
                          VT_R8=0x0005,
                          VT_CY=0x0006,
                          VT_DATE=0x0007,
                          VT_BSTR=0x0008,
                          VT_ERROR=0x000A,
                          VT_BOOL=0x000B,
                          VT_DECIMAL=0x000E,
                          VT_I1=0x0010,
                          VT_UI1=0x0011,
                          VT_UI2=0x0012,
                          VT_UI4=0x0013,
                          VT_I8=0x0014,
                          VT_UI8=0x0015,
                          VT_INT=0x0016,
                          VT_UINT=0x0017,
                          VT_LPSTR=0x001E,
                          VT_LPWSTR=0x001F,
                          VT_FILETIME=0x0040,
                          VT_BLOB=0x0041,
                          VT_STREAM=0x0042,
                          VT_STORAGE=0x0043,
                          VT_STREAMED_Object=0x0044,
                          VT_STORED_Object=0x0045,
                          VT_BLOB_Object=0x0046,
                          VT_CF=0x0047,
                          VT_CLSID=0x0048,
                          VT_VERSIONED_STREAM=0x0049,
                          VT_I2_2=0x1002,
                          VT_I4_2=0x1003,
                          VT_R4_2=0x1004,
                          VT_R8_2=0x1005,
                          VT_CY_2=0x1006,
                          VT_DATE_2=0x1007,
                          VT_BSTR_2=0x1008,
                          VT_ERROR_2=0x100A,
                          VT_BOOL_2=0x100B,
                          VT_VARIANT_2=0x100C,
                          VT_I1_2=0x1010,
                          VT_UI1_2=0x1011,
                          VT_UI2_2=0x1012,
                          VT_UI4_2=0x1013,
                          VT_I8_2=0x1014,
                          VT_UI8_2=0x1015,
                          VT_LPSTR_2=0x101E,
                          VT_LPWSTR_2=0x101F,
                          VT_FILETIME_2=0x1040,
                          VT_CF_2=0x1047,
                          VT_CLSID_2=0x1048,
                          VT_I2_3=0x2002,
                          VT_I4_3=0x2003,
                          VT_R4_3=0x2004,
                          VT_R8_3=0x2005,
                          VT_CY_3=0x2006,
                          VT_DATE_3=0x2007,
                          VT_BSTR_3=0x2008,
                          VT_ERROR_3=0x200A,
                          VT_BOOL_3=0x200B,
                          VT_VARIANT_3=0x200C,
                          VT_DECIMAL_3=0x200E,
                          VT_I1_3=0x2010,
                          VT_UI1_3=0x2011,
                          VT_UI2_3=0x2012,
                          VT_UI4_3=0x2013,
                          VT_INT_3=0x2016,
                          VT_UINT_3=0x2017),
            "Padding" / Bytes(2),
            # "Value" / If(this.Type=='VT_LPWSTR', UnicodeString)
        )

        ExtraData = "ExtraData" / Struct(
            "BlockSize" / Int32ul,
            "BlockSignature" / Int32ul,
            "ConsoleDataBlock" / If(
                this.BlockSignature == 0xA0000002,
                Struct(
                    "FileAttributes" / Enum(Int16ul,
                                            FOREGROUND_BLUE=0x001,
                                            FOREGROUND_GREEN=0x002,
                                            FOREGROUND_RED=0x004,
                                            FOREGROUND_INTENSITY=0x008,
                                            BACKGROUND_BLUE=0x010,
                                            BACKGROUND_GREEN=0x020,
                                            BACKGROUND_RED=0x040,
                                            BACKGROUND_INTENSITY=0x0080),
                    "PopupFillAttributes" / Enum(Int16ul,
                                                 FOREGROUND_BLUE=0x001,
                                                 FOREGROUND_GREEN=0x002,
                                                 FOREGROUND_RED=0x004,
                                                 FOREGROUND_INTENSITY=0x008,
                                                 BACKGROUND_BLUE=0x010,
                                                 BACKGROUND_GREEN=0x020,
                                                 BACKGROUND_RED=0x040,
                                                 BACKGROUND_INTENSITY=0x0080),
                    "ScreenBufferSizeX" / Int16ul, "ScreenBufferSizeY" /
                    Int16ul, "WindowSizeX" / Int16ul, "WindowSizeY" / Int16ul,
                    "WindowOriginX" / Int16ul, "WindowOriginY" / Int16ul,
                    "Unused1" / Bytes(4), "Unused2" / Bytes(4), "FontSize" /
                    Int32ul, "FontFamily" / Enum(Int32ul,
                                                 FF_DONTCARE=0x0000,
                                                 FF_ROMAN=0x0010,
                                                 FF_SWISS=0x0020,
                                                 FF_MODERN=0x0030,
                                                 FF_SCRIPT=0x0040,
                                                 FF_DECORATIVE=0x0050,
                                                 TMPF_NONE=0x0000,
                                                 TMPF_FIXED_PITCH=0x0001,
                                                 TMPF_VECTOR=0x0002,
                                                 TMPF_TRUETYPE=0x0004,
                                                 TMPF_DEVICE=0x0004),
                    "FontWeight" / Int32ul, "FaceName" / Bytes(64),
                    "CursorSize" / Int32ul, "FullScreen" / Int32ul,
                    "QuickEdit" / Int32ul, "InsertMode" / Int32ul,
                    "AutoPosition" / Int32ul, "HistoryBufferSize" / Int32ul,
                    "NumberOfHistoryBuffers" / Int32ul,
                    "HistoryNoDup" / Int32ul, "ColorTable" / Bytes(64))),
            "ConsoleFEDataBlock" / If(this.BlockSignature == 0xA0000004,
                                      Struct("CodePage" / Int32ul)),
            "DarwinDataBlock" / If(
                this.BlockSignature == 0xA0000006,
                Struct("TargetAnsi" / CString("utf8"),
                       "TargetUnicode" / CString("utf16"))),
            "EnvironmentVariableDataBlock" / If(
                this.BlockSignature == 0xA0000001,
                Struct("TargetAnsi" / CString("utf8"),
                       "TargetUnicode" / CString("utf16"))),
            "IconEnvironmentDataBlock" / If(
                this.BlockSignature == 0xA0000007,
                Struct("TargetAnsi" / CString("utf8"),
                       "TargetUnicode" / CString("utf16"))),
            "KnownFolderDataBlock" /
            If(this.BlockSignature == 0xA000000B,
               Struct(
                   "KnownFolderID" / Bytes(16),
                   "Offset" / Int32ul,
               )),
            "PropertyStoreDataBlock" / If(
                this.BlockSignature == 0xA0000009,
                Struct("PropertyStore" / Struct(
                    # "StoreSize" / Int32ul,
                    "SerializedPropertyStorage" / Struct(
                        "StorageSize" / Int32ul,
                        "Version" / Int32ul,
                        "FormatID" / Bytes(16),
                        "StringName" / IfThenElse(
                            this.FormatID ==
                            b'\xd5\xcd\xd5\x05\x2e\x9c\x10\x1b\x93\x97\x08\x00\x2b\x2c\xf9\xae',
                            Struct("ValueSize" / Int32ul, "NameSize" / Int32ul,
                                   "Reserved" / Bytes(1),
                                   "Name" / CString("utf16"),
                                   "TypedPropertyValue" / TypedPropertyValue),
                            Struct("ValueSize" / Int32ul, "Id" / Int32ul,
                                   "Reserved" / Bytes(1),
                                   "TypedPropertyValue" / TypedPropertyValue)),
                    )))),
            "ShimDataBlock" / If(this.BlockSignature == 0xA0000008,
                                 Struct("LayerName" / CString("utf16"))),
            "SpecialFolderDataBlock" / If(
                this.BlockSignature == 0xA0000005,
                Struct(
                    "SpecialFolderID" / Int32ul,
                    "Offset" / Int32ul,
                    "LinkTargetIDList" / LinkTargetIDList,
                )),
            "TrackerDataBlock" / If(
                this.BlockSignature == 0xA0000003,
                Struct("Length" / Int32ul, "Version" / Int32ul,
                       "MachineID" / Bytes(16), "Droid" / Bytes(32),
                       "DroidBirth" / Bytes(32))),
            "VistaAndAboveIDListDataBlock" / If(
                this.BlockSignature == 0xA000000C,
                Struct(
                    "ItemIDList" / GreedyRange(
                        Struct(
                            "ItemIDSize" / Int16ul,
                            "Data" / Bytes(this.ItemIDSize - 2),
                        )), "TerminalID" / Int16ul)),
        )

        ShellLinkHeader = "ShellLinkHeader" / Struct(
            "HeaderSize" / Int32ul, "LinkCLSID" / Bytes(16),
            "LinkFlags" / BitsSwapped(
                BitStruct(
                    "HasLinkTargetIDList" / Flag, "HasLinkInfo" / Flag,
                    "HasName" / Flag, "HasRelativePath" / Flag, "HasWorkingDir"
                    / Flag, "HasArguments" / Flag, "HasIconLocation" / Flag,
                    "IsUnicode" / Flag, "ForceNoLinkInfo" / Flag,
                    "HasExpString" / Flag, "RunInSeparateProcess" / Flag,
                    "Unused1" / Flag, "HasDarwinID" / Flag, "RunAsUser" / Flag,
                    "HasExpIcon" / Flag, "NoPidlAlias" / Flag, "Unused2" /
                    Flag, "RunWithShimLayer" / Flag, "ForceNoLinkTrack" / Flag,
                    "EnableTargetMetadata" / Flag, "DisableLinkPathTracking" /
                    Flag, "DisableKnownFolderTracking" / Flag,
                    "DisableKnownFolderAlias" / Flag, "AllowLinkToLink" / Flag,
                    "UnaliasOnSave" / Flag, "PreferEnvironmentPath" / Flag,
                    "KeepLocalIDListForUNCTarget" / Flag, Flag, Flag, Flag,
                    Flag, Flag)),
            "FileAttributes" / BitsSwapped(
                BitStruct(
                    "FILE_ATTRIBUTE_READONLY" / Flag, "FILE_ATTRIBUTE_READONLY"
                    / Flag, "FILE_ATTRIBUTE_SYSTEM" / Flag, "Reserved1" / Flag,
                    "FILE_ATTRIBUTE_DIRECTORY" / Flag, "FILE_ATTRIBUTE_ARCHIVE"
                    / Flag, "Reserved2" / Flag, "FILE_ATTRIBUTE_NORMAL" / Flag,
                    "FILE_ATTRIBUTE_TEMPORARY" / Flag,
                    "FILE_ATTRIBUTE_SPARSE_FILE" / Flag,
                    "FILE_ATTRIBUTE_REPARSE_POINT" / Flag,
                    "FILE_ATTRIBUTE_COMPRESSED" / Flag,
                    "FILE_ATTRIBUTE_OFFLINE" / Flag,
                    "FILE_ATTRIBUTE_NOT_CONTENT_INDEXED" / Flag,
                    "FILE_ATTRIBUTE_ENCRYPTED" / Flag, Flag, Flag, Flag, Flag,
                    Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                    Flag, Flag, Flag)), "CreationTime" / Bytes(8),
            "AccessTime" / Bytes(8), "WriteTime" / Bytes(8),
            "FileSize" / Int32ul, "IconIndex" / Int32sl, "ShowCommand" / Enum(
                Int32ul,
                SW_HIDE=0x00000000,
                SW_NORMAL=0x00000001,
                SW_SHOWMINIMIZED=0x00000002,
                SW_SHOWMAXIMIZED=0x00000003,
                SW_SHOWNOACTIVATE=0x00000004,
                SW_SHOW=0x00000005,
                SW_MINIMIZE=0x00000006,
                SW_SHOWMINNOACTIVE=0x00000007,
                SW_SHOWNA=0x00000008,
                SW_RESTORE=0x00000009,
                SW_SHOWDEFAULT=0x0000000a,
            ), "HotKey" / Struct("LowByte" / Int8ul, "HighByte" / Int8ul),
            "Reserved1" / Bytes(2), "Reserved2" / Bytes(4),
            "Reserved3" / Bytes(4))

        CommonNetworkRelativeLink = "CommonNetworkRelativeLink" / Struct(
            "CommonNetworkRelativeLinkSize" / Int32ul,
            "CommonNetworkRelativeLinkFlags" / BitsSwapped(
                BitStruct("ValidDevice" / Flag, "ValideNetType" / Flag, Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag)),
            "NetNameOffset" / Int32ul,
            "DeviceNameOffset" / Int32ul,
            "NetworkProviderType" / If(
                this.CommonNetworkRelativeLinkFlags.ValideNetType,
                Enum(Int32ul,
                     WNNC_NET_AVID=0x001A0000,
                     WNNC_NET_DOCUSPACE=0x001B0000,
                     WNNC_NET_MANGOSOFT=0x001C0000,
                     WNNC_NET_SERNET=0x001D0000,
                     WNNC_NET_RIVERFRONT1=0X001E0000,
                     WNNC_NET_RIVERFRONT2=0x001F0000,
                     WNNC_NET_DECORB=0x0020000,
                     WNNC_NET_PROTSTOR=0x00210000,
                     WNNC_NET_FJ_REDIR=0x00220000,
                     WNNC_NET_DISTINCT=0x00230000,
                     WNNC_NET_TWINS=0x00240000,
                     WNNC_NET_RDR2SAMPLE=0x00250000,
                     WNNC_NET_CSC=0x00260000,
                     WNNC_NET_3IN1=0x00270000,
                     WNNC_NET_EXTENDNET=0x00290000,
                     WNNC_NET_STAC=0x002A0000,
                     WNNC_NET_FOXBAT=0x002B0000,
                     WNNC_NET_YAHOO=0x002C0000,
                     WNNC_NET_EXIFS=0x002D0000,
                     WNNC_NET_DAV=0x002E0000,
                     WNNC_NET_KNOWARE=0x002F0000,
                     WNNC_NET_OBJECT_DIRE=0x00300000,
                     WNNC_NET_MASFAX=0x00310000,
                     WNNC_NET_HOB_NFS=0x00320000,
                     WNNC_NET_SHIVA=0x00330000,
                     WNNC_NET_IBMAL=0x00340000,
                     WNNC_NET_LOCK=0x00350000,
                     WNNC_NET_TERMSRV=0x00360000,
                     WNNC_NET_SRT=0x00370000,
                     WNNC_NET_QUINCY=0x00380000,
                     WNNC_NET_OPENAFS=0x00390000,
                     WNNC_NET_AVID1=0X003A0000,
                     WNNC_NET_DFS=0x003B0000,
                     WNNC_NET_KWNP=0x003C0000,
                     WNNC_NET_ZENWORKS=0x003D0000,
                     WNNC_NET_DRIVEONWEB=0x003E0000,
                     WNNC_NET_VMWARE=0x003F0000,
                     WNNC_NET_RSFX=0x00400000,
                     WNNC_NET_MFILES=0x00410000,
                     WNNC_NET_MS_NFS=0x00420000,
                     WNNC_NET_GOOGLE=0x00430000)),
            If(this.NetNameOffset > 0x00000014,
               "NetNameOffsetUnicode" / Int32ul),
            If(this.NetNameOffset > 0x00000014,
               "DeviceNameOffsetUnicode" / Int32ul),
            "NetName" / CString("utf8"),
            If(this.NetNameOffset > 0x00000014,
               "DeviceName" / CString("utf8")),
            If(this.NetNameOffset > 0x00000014,
               "NetNameUnicode" / CString("utf16")),
        )

        LinkInfo = "LinkInfo" / Struct(
            "LinkInfoSize" / Int32ul,
            "LinkInfoHeaderSize" / Int32ul,
            "LinkInfoFlags" / BitsSwapped(
                BitStruct("VolumeIDAndLocalBasePath" / Flag,
                          "CommonNetworkRelativeLinkAndPathSuffix" / Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag, Flag,
                          Flag, Flag, Flag)),
            "VolumeIDOffset" / Int32ul,
            "LocalBasePathOffset" / Int32ul,
            "CommonNetworkRelativeLinkOffset" / Int32ul,
            "CommonPathSuffixOffset" / Int32ul,
            "LocalBasePathOffsetUnicode" /
            If(this.LinkInfoHeaderSize >= 0x24, Int32ul),
            "CommonPathSuffixOffsetUnicode" /
            If(this.LinkInfoHeaderSize >= 0x24, Int32ul),
            "VolumeID" / Struct(
                "VolumeIDSize" / Int32ul,
                "DriveType" / Enum(Int32ul,
                                   DRIVE_UNKNOWN=0x00000000,
                                   DRIVE_NO_ROOT_DIR=0x00000001,
                                   DRIVE_REMOVABLE=0x00000002,
                                   DRIVE_FIXED=0x00000003,
                                   DRIVE_REMOTE=0x00000004,
                                   DRIVE_CDROM=0x00000005,
                                   DRIVE_RAMDISK=0x00000006),
                "DriveSerialNumber" / Int32ul,
                "VolumeLabelOffset" / Int32ul,
                "VolumeLabelOffsetUnicode" /
                If(this.VolumeLabelOffset == 0x14, Int32ul),
                "Data" / CString("utf8"),
            ),
            "LocalBasePath" /
            If(this.LinkInfoFlags.VolumeIDAndLocalBasePath, CString("utf8")),
            "CommonNetworkRelativeLink" /
            If(this.CommonNetworkRelativeLinkOffset,
               CommonNetworkRelativeLink),
            "CommonPathSuffix" / CString("utf8"),
            "LocalBasePathUnicode" /
            If(this.LinkInfoHeaderSize == 0x24,
               If(this.LocalBasePathOffsetUnicode, CString("utf16"))),
            "CommonPathSuffixUnicode" /
            If(this.LinkInfoHeaderSize == 0x24,
               If(this.CommonPathSuffixOffsetUnicode, CString("utf16"))),
        )

        header = ShellLinkHeader.parse(lnk_data)
        offset = header.HeaderSize

        try:
            if header.LinkFlags.HasLinkTargetIDList:
                linktargetidlist = LinkTargetIDList.parse(data[offset:])
                offset += linktargetidlist.IDListSize + 2
        except:
            self.flags.append("Unable to parse LinkTargetIDList")

        try:
            if header.LinkFlags.HasLinkInfo:
                linkinfo = LinkInfo.parse(data[offset:])
                if linkinfo.VolumeID.DriveType:
                    self.event['DriveType'] = linkinfo.VolumeID.DriveType
                if linkinfo.VolumeID.DriveSerialNumber:
                    self.event["DriveSerialNumber"] = '{0:x}'.format(
                        linkinfo.VolumeID.DriveSerialNumber)
                if linkinfo.VolumeID.Data:
                    self.event["VolumeLabel"] = linkinfo.VolumeID.Data
                if linkinfo.LocalBasePath:
                    self.event["LocalBasePath"] = linkinfo.LocalBasePath
                if linkinfo.CommonNetworkRelativeLink:
                    commonnetworkrelativelink = CommonNetworkRelativeLink.parse(
                        data[offset +
                             linkinfo.CommonNetworkRelativeLinkOffset:])
                    self.event["NetName"] = commonnetworkrelativelink.NetName
                offset += linkinfo.LinkInfoSize
        except:
            self.flags.append("Unable to parse LinkInfo")

        StringData = "StringData" / Struct(
            "CountCharacters" / Int16ul, "String" /
            IfThenElse(header.LinkFlags.IsUnicode,
                       StringEncoded(Bytes(this.CountCharacters * 2), "utf16"),
                       StringEncoded(Bytes(this.CountCharacters), "utf8")))

        try:
            if header.LinkFlags.HasName:
                NAME_STRING = StringData.parse(data[offset:])
                self.event["NAME_STRING"] = NAME_STRING.String
                if header.LinkFlags.IsUnicode:
                    offset += (len(NAME_STRING.String) * 2 + 2)
                else:
                    offset += (len(NAME_STRING.String) + 2)
        except:
            self.flags.append("Unable to parse NAME_STRING")

        try:
            if header.LinkFlags.HasRelativePath:
                RELATIVE_PATH = StringData.parse(data[offset:])
                self.event["RELATIVE_PATH"] = RELATIVE_PATH.String
                if header.LinkFlags.IsUnicode:
                    offset += (len(RELATIVE_PATH.String) * 2 + 2)
                else:
                    offset += (len(RELATIVE_PATH.String) + 2)
        except:
            self.flags.append("Unable to parse RELATIVE_PATH")

        try:
            if header.LinkFlags.HasWorkingDir:
                WORKING_DIR = StringData.parse(data[offset:])
                self.event["WORKING_DIR"] = WORKING_DIR.String
                if header.LinkFlags.IsUnicode:
                    offset += (len(WORKING_DIR.String) * 2 + 2)
                else:
                    offset += (len(WORKING_DIR.String) + 2)
        except:
            self.flags.append("Unable to parse WORKING_DIR")

        try:
            if header.LinkFlags.HasArguments:
                COMMAND_LINE_ARGUMENTS = StringData.parse(data[offset:])
                self.event[
                    "COMMAND_LINE_ARGUMENTS"] = COMMAND_LINE_ARGUMENTS.String
                if header.LinkFlags.IsUnicode:
                    offset += (len(COMMAND_LINE_ARGUMENTS.String) * 2 + 2)
                else:
                    offset += (len(COMMAND_LINE_ARGUMENTS.String) + 2)
        except:
            self.flags.append("Unable to parse COMMAND_LINE_ARGUMENTS")

        try:
            if header.LinkFlags.HasIconLocation:
                ICON_LOCATION = StringData.parse(data[offset:])
                self.event["ICON_LOCATION"] = ICON_LOCATION.String
                if header.LinkFlags.IsUnicode:
                    offset += (len(ICON_LOCATION.String) * 2 + 2)
                else:
                    offset += (len(ICON_LOCATION.String) + 2)
        except:
            self.flags.append("Unable to parse ICON_LOCATION")

        try:
            blocksize = True
            while blocksize:
                try:
                    extradata = ExtraData.parse(data[offset:])
                    blocksize = extradata.BlockSize
                except:
                    break

                try:
                    if extradata.IconEnvironmentDataBlock:
                        self.event[
                            "IconTarget"] = extradata.IconEnvironmentDataBlock.TargetAnsi
                except:
                    self.flags.append(
                        "Unable to parse IconEnvironmentDataBlock")

                if extradata.TrackerDataBlock:
                    self.event[
                        "MachineID"] = extradata.TrackerDataBlock.MachineID.strip(
                            b'\x00')
                    self.event["MAC"] = str(
                        uuid.UUID(bytes_le=extradata.TrackerDataBlock.
                                  Droid[16:])).split('-')[-1]

                offset += extradata.BlockSize
        except:
            self.flags.append("Unable to parse ExtraDataBlock")