"after_name_offset" / Tell, # NOT IN THE REAL FORMAT - USED FOR BUILDING ONLY "data" / Switch( lambda this: this.name, { "Columns": FixedArray(lambda this: this.data_size, Int16ul), "ColumnCount": Int32ul, "ColumnMap": FixedArray(lambda this: this.data_size, ColumnType), "DbgHelpPath": FixedUTF16String(lambda this: this.data_size), "Logfile": FixedUTF16String(lambda this: this.data_size), "HighlightFG": Int32ul, "HighlightBG": Int32ul, "LogFont": FontStruct, "BoookmarkFont": FontStruct, # they have typo in "BoookmarkFont" lol "AdvancedMode": Int32ul, "Autoscroll": Int32ul, "HistoryDepth": Int32ul, "Profiling": Int32ul, "DestructiveFilter": Int32ul, "AlwaysOnTop": Int32ul, "ResolveAddresses": Int32ul, "SourcePath": FixedUTF16CString(lambda this: this.data_size, "data"), "SymbolPath": FixedUTF16CString(lambda this: this.data_size, "data"), "FilterRules": RulesStruct, "HighlightRules": RulesStruct }, FixedBytes(lambda this: this.data_size)), "after_data_offset" / Tell, # NOT IN THE REAL FORMAT - USED FOR BUILDING ONLY
FastCadencePeriodDivisorAndTriggerType = EmbeddedBitStruct( "status_trigger_type" / BitsInteger(1), "fast_cadence_period_divisor" / BitsInteger(7) ) UnitlessTriggerDelta = DefaultCountValidator(Int8ul, rounding=1, resolution=0.1) TriggerDelta = Struct( Switch( this.status_trigger_type, { 0: Struct( "status_trigger_delta_down" / PropertyValue, "status_trigger_delta_up" / PropertyValue ), 1: Struct( "status_trigger_delta_down" / UnitlessTriggerDelta, "status_trigger_delta_up" / UnitlessTriggerDelta ) } ) ) # TODO: message not implemented due to somewhat complicated structure and lack of examples # SensorCadence = Struct( # "sensor_setting_property_id" / Int16ul, # *FastCadencePeriodDivisorAndTriggerType, # Embedded(TriggerDelta), # "status_min_interval" / ExprAdapter(Int16ul, lambda obj, ctx: pow(2, obj), lambda obj, ctx: log(obj, 2)), # "fast_cadence_low" / PropertyValue,
ALPNExtension = Prefixed( Int16ub, Struct( Int16ub, "alpn_protocols" / GreedyRange("name" / PascalString(Int8ub), ), )) UnknownExtension = Struct("bytes" / PascalString("length" / Int16ub)) Extension = "Extension" / Struct( "type" / Int16ub, Embedded( Switch(lambda ctx: ctx.type, { 0x00: SNIExtension, 0x10: ALPNExtension, }, default=UnknownExtension))) extensions = "extensions" / Optional( Struct(Int16ub, "extensions" / GreedyRange(Extension))) ClientHello = "ClientHello" / Struct( ProtocolVersion, Random, SessionID, CipherSuites, CompressionMethods, extensions, )
def perf_event(): return Struct("perf_event", Anchor("start"), perf_event_header(), Anchor("header_end"), Switch("data", lambda ctx: ctx.type, { "MMAP": mmap(), # noqa E121 "MMAP2": mmap2(), "LOST": Struct("lost", UNInt64("id"), UNInt64("lost"), sample_id()), "COMM": Struct("comm", SNInt32("pid"), SNInt32("tid"), CString("comm"), sample_id()), "EXIT": fork_exit("exit"), "THROTTLE": throttle("throttle"), "UNTHROTTLE": throttle("unthrottle"), "FINISHED_ROUND": Pass, "FORK": fork_exit("fork"), "READ": Embedded(Struct("read_event", SNInt32("pid"), SNInt32("tid"), read_format(), sample_id())), "SAMPLE": event(), "TIME_CONV": time_conv(), "THREAD_MAP": thread_map(), # below are the so far not handled ones. Dump their # raw data only "RECORD_AUX": ignore(), "AUX": ignore(), "ITRACE_START": ignore(), "LOST_SAMPLES": ignore(), "SWITCH": ignore(), "SWITCH_CPU_WIDE": ignore(), "NAMESPACES": ignore(), "KSYMBOL": ignore(), "BPF_EVENT": ignore(), "CGROUP": ignore(), "HEADER_ATTR": ignore(), "HEADER_EVENT_TYPE": ignore(), "TRACING_DATA": ignore(), "HEADER_BUILD_ID": ignore(), "ID_INDEX": ignore(), "AUXTRACE_INFO": ignore(), "AUXTRACE": ignore(), "AUXTRACE_ERROR": ignore(), "CPU_MAP": ignore(), "STAT": ignore(), "STAT_ROUND": ignore(), "EVENT_UPDATE": ignore(), "HEADER_FEATURE": ignore(), "COMPRESSED": ignore(), }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start)))
from construct import Struct, Switch, Bytes, Int16ul, RawCopy, this from .kdbx3 import DynamicHeader as DynamicHeader3 from .kdbx3 import Body as Body3 from .kdbx4 import DynamicHeader as DynamicHeader4 from .kdbx4 import Body as Body4 KDBX = Struct( "header" / RawCopy( Struct( "magic1" / Bytes(4), "magic2" / Bytes(4), "minor_version" / Int16ul, "major_version" / Int16ul, "dynamic_header" / Switch(this.major_version, { 3: DynamicHeader3, 4: DynamicHeader4 }))), "body" / Switch(this.header.value.major_version, { 3: Body3, 4: Body4 }))
padchar=b'\x00', trimdir='right', encoding='latin1'), )) # Embedded header (aka saved chapter) header = Struct( "subtype" / Computed("savedchapter"), "data" / Struct( "header_length" / Computed(lambda ctx: ctx._._._.op - ctx._._._.start), Embedded(subheader))) # Unknown embedded structure - looks like a partial action? other = Struct( "subtype" / Computed("unknown"), "data" / Struct( Padding(4), "num_ints" / Int32ul, If(lambda ctx: ctx.num_ints < 0xff, Array(lambda ctx: ctx.num_ints, Int32ul)), Padding(12))) # Anything we don't recognize - just consume the remainder default = Struct("subtype" / Computed("default"), GreedyBytes) # Embedded structures identified by first byte (for now) embedded = "embedded" / Struct( "marker" / Peek(Int16ul), Embedded("data" / Switch(lambda ctx: ctx.marker, { 0: header, 9024: chat, 65535: other }, default=default)))
"conn_state" / EnumAdapter(BitsInteger(3), ConnState), "link_status" / EnumAdapter(BitsInteger(1), LinkStatus), "last_error" / EnumAdapter(BitsInteger(4), LastError) ) ) GatewayConfigPayload = Struct( "subopcode" / EnumAdapter(Int8ul, GatewayConfigServerSubOpcode), "payload" / Default(Switch( this.subopcode, { GatewayConfigServerSubOpcode.GATEWAY_CONFIGURATION_SET: ConfigurationSet, GatewayConfigServerSubOpcode.MTU_SIZE_SET: ConfigurationSetMtu, GatewayConfigServerSubOpcode.ETHERNET_MAC_ADDRESS_SET: ConfigurationSetMacAddr, GatewayConfigServerSubOpcode.SERVER_ADDRESS_AND_PORT_NUMBER_SET: ConfigurationSetServerAddrAndPortNr, GatewayConfigServerSubOpcode.RECONNECT_INTERVAL_SET: ConfigurationSetReconnectInterval, GatewayConfigServerSubOpcode.DNS_IP_ADDRESS_SET: ConfigurationSetDnsIpAddr, GatewayConfigServerSubOpcode.IP_ADDRESS_SET: ConfigurationSetIpAddr, GatewayConfigServerSubOpcode.GATEWAY_IP_ADDRESS_SET: ConfigurationSetGatewayIpAddr, GatewayConfigServerSubOpcode.NETMASK_SET: ConfigurationSetNetmask, GatewayConfigServerSubOpcode.GATEWAY_CONFIGURATION_STATUS: ConfigurationStatus, GatewayConfigServerSubOpcode.GATEWAY_PACKETS_STATUS: PacketsStatus, }, ), None) ) GatewayConfigMessage = Struct( "opcode" / Const(GatewayConfigServerOpcode.OPCODE, Opcode(GatewayConfigServerOpcode)), "params" / GatewayConfigPayload ) # fmt: on
'length' / Int16ub, 'data' / Bytes(lambda ctx: ctx.length) ) alfred_push_data = Struct( 'transaction_id' / Int16ub, 'sequence_number' / Int16ub, 'alfred_data' / Array(1, alfred_data_block) ) alfred_packet = Struct( 'alfred_tlv' / alfred_tlv, 'packet_body' / Switch(lambda ctx: ctx.alfred_tlv.type, { 0: alfred_push_data, 1: alfred_announce_master, 2: alfred_request, 3: alfred_status_end, 4: alfred_status_error, 5: alfred_mode_switch }) ) socket_address = '/var/run/alfred.sock' request = alfred_packet.build({ 'alfred_tlv': { 'type': 2, 'version': 0, 'length': 3, }, 'packet_body': { 'requested_type': 65,
} # Metadata subconstruct. entity_metadata = MetadataAdapter( Struct( "metadata", RepeatUntil( lambda obj, context: obj["peeked"] == 0x7f, Struct( "data", BitStruct( "id", BitField("data_type", 3), # first BitField("identifier", 5), # second ), Switch("value", lambda context: context["id"]["data_type"], metadata_switch), Peek(SBInt8("peeked")), ), ), Const(UBInt8("terminator"), 0x7f), ), ) # The actual packet list. packets = { 0: Struct( "keep alive", SBInt32("pid"), ), 1: Struct(
Rename("header", tcp_header), HexDumpAdapter( Field( "next", lambda ctx: ctx["_"]["header"].payload_length - ctx[ "header"].header_length)), ) layer4_udp = Struct( "layer4_udp", Rename("header", udp_header), HexDumpAdapter(Field("next", lambda ctx: ctx["header"].payload_length)), ) layer3_payload = Switch("next", lambda ctx: ctx["header"].protocol, { "TCP": layer4_tcp, "UDP": layer4_udp, }, default=Pass) layer3_ipv4 = Struct( "layer3_ipv4", Rename("header", ipv4_header), layer3_payload, ) layer3_ipv6 = Struct( "layer3_ipv6", Rename("header", ipv6_header), layer3_payload, )
ProtocolVersion, Random, SessionID, CipherSuites, CompressionMethods, UBInt16("extensions_length"), Bytes("extensions_bytes", lambda ctx: ctx.extensions_length), ) ServerHello = Struct("ServerHello", ProtocolVersion, Random, SessionID, UBInt16("cipher_suite"), UBInt8("compression_method")) Handshake = Struct( "handshake", UBInt8("handshake_type"), UBInt24("length"), Switch("handshake_struct", lambda ctx: ctx.handshake_type, { 1: ClientHello, 2: ServerHello })) Alert = Struct("alert", UBInt8("alert_level"), UBInt8("alert_description")) TLSPlaintext = Struct( "TLSPlaintext", UBInt8("content_type"), ProtocolVersion, UBInt16("length"), Switch("content", lambda ctx: ctx.content_type, { 21: Alert, 22: Handshake })) ECPointFormat = Struct( "ec_point_format", UBInt8("ec_point_format_length"), Array(lambda ctx: ctx.ec_point_format_length, UBInt8("ec_point_format")))
) SessionID = Struct( "session_id", PrefixedBytes("session_id"), ) CompressionMethods = Struct( "compression_methods", SizeAtLeast(UBInt8("length"), min_size=1), Array(lambda ctx: ctx.length, UBInt8("compression_methods"))) HostName = PrefixedBytes("hostname", UBInt16("length")) ServerName = Struct( "server_name", EnumClass(UBInt8("name_type"), enums.NameType), Switch("name", lambda ctx: ctx.name_type, {enums.NameType.HOST_NAME: HostName})) ServerNameList = TLSPrefixedArray("server_name_list", ServerName) ClientCertificateURL = Struct( "client_certificate_url", # The "extension_data" field of this extension SHALL be empty. ) SignatureAndHashAlgorithm = Struct( "algorithms", EnumClass(UBInt8("hash"), enums.HashAlgorithm), EnumClass(UBInt8("signature"), enums.SignatureAlgorithm), ) SupportedSignatureAlgorithms = TLSPrefixedArray(
"Length" / Int24ub, "CertData" / Bytes(this.Length) ) PreCert = Struct( "IssuerKeyHash" / Bytes(32), "TBSCertificateLength" / Int24ub, "TBSCertificate" / Bytes(this.TBSCertificateLength) ) TimestampedEntry = Struct( "Timestamp" / Int64ub, "LogEntryType" / Enum(Int16ub, X509LogEntryType=0, PrecertLogEntryType=1), "Entry" / Switch(this.LogEntryType, { "X509LogEntryType": Certificate, "PrecertLogEntryType": PreCert }), "Extensions" / CtExtensions ) MerkleTreeLeaf = Struct( "Version" / Byte, "MerkleLeafType" / Byte, "TimestampedEntry" / TimestampedEntry ) HashAlgorithm = Enum(Byte, none=0, md5=1, sha1=2, sha224=3, sha256=4, sha384=5, sha512=6) SignatureAlgorithm = Enum(Byte, anonymous=0, rsa=1, dsa=2, ecdsa=3) SignatureAndHashAlgorithm = Struct(
def __setup_constructors(self): '''Set endianness and create transport-specific constructors.''' # Set endianness of constructors before using them. self._set_endian('little') self.__Length = Int32ul self.__Type = Enum( Int32ul, Undefined=0x00000000, InitCommand=0x00000001, InitCommandAck=0x00000002, InitEvent=0x00000003, InitEventAck=0x00000004, InitFail=0x00000005, Command=0x00000006, Response=0x00000007, Event=0x00000008, StartData=0x00000009, Data=0x0000000A, Cancel=0x0000000B, EndData=0x0000000C, Ping=0x0000000D, Pong=0x0000000E, ) self.__Header = Struct( 'Length' / self.__Length, 'Type' / self.__Type, ) self.__Param = Range(0, 5, self._Parameter) self.__EventParam = Range(0, 3, self._Parameter) self.__PacketBase = Struct( Embedded(self.__Header), 'Payload' / Bytes( lambda ctx, h=self.__Header: ctx.Length - h.sizeof()), ) self.__Packet = ExprAdapter( self.__PacketBase, encoder=lambda obj, ctx, h=self.__Header: Container( Length=len(obj.Payload) + h.sizeof(), **obj ), decoder=lambda obj, ctx: obj, ) # Yet another arbitrary string type. Max-length CString utf8-encoded self.__PTPIPString = ExprAdapter( RepeatUntil( lambda obj, ctx, lst: six.unichr(obj) in '\x00' or len(lst) == 40, Int16ul ), encoder=lambda obj, ctx: [] if len(obj) == 0 else[ord(c) for c in six.text_type(obj)]+[0], decoder=lambda obj, ctx: u''.join( [six.unichr(o) for o in obj] ).split('\x00')[0], ) # PTP/IP packets # Command self.__ProtocolVersion = Struct( 'Major' / Int16ul, 'Minor' / Int16ul, ) self.__InitCommand = Embedded(Struct( 'InitiatorGUID' / Array(16, Int8ul), 'InitiatorFriendlyName' / self.__PTPIPString, 'InitiatorProtocolVersion' / self.__ProtocolVersion, )) self.__InitCommandACK = Embedded(Struct( 'ConnectionNumber' / Int32ul, 'ResponderGUID' / Array(16, Int8ul), 'ResponderFriendlyName' / self.__PTPIPString, 'ResponderProtocolVersion' / self.__ProtocolVersion, )) # Event self.__InitEvent = Embedded(Struct( 'ConnectionNumber' / Int32ul, )) # Common to Events and Command requests self.__Reason = Enum( # TODO: Verify these codes... Int32ul, Undefined=0x0000, RejectedInitiator=0x0001, Busy=0x0002, Unspecified=0x0003, ) self.__InitFail = Embedded(Struct( 'Reason' / self.__Reason, )) self.__DataphaseInfo = Enum( Int32ul, Undefined=0x00000000, In=0x00000001, Out=0x00000002, ) self.__Command = Embedded(Struct( 'DataphaseInfo' / self.__DataphaseInfo, 'OperationCode' / self._OperationCode, 'TransactionID' / self._TransactionID, 'Parameter' / self.__Param, )) self.__Response = Embedded(Struct( 'ResponseCode' / self._ResponseCode, 'TransactionID' / self._TransactionID, 'Parameter' / self.__Param, )) self.__Event = Embedded(Struct( 'EventCode' / self._EventCode, 'TransactionID' / self._TransactionID, 'Parameter' / self.__EventParam, )) self.__StartData = Embedded(Struct( 'TransactionID' / self._TransactionID, 'TotalDataLength' / Int64ul, )) # TODO: Fix packing and unpacking dataphase data self.__Data = Embedded(Struct( 'TransactionID' / self._TransactionID, 'Data' / Bytes( lambda ctx: ctx._.Length - self.__Header.sizeof() - self._TransactionID.sizeof() ), )) self.__EndData = Embedded(Struct( 'TransactionID' / self._TransactionID, 'Data' / Bytes( lambda ctx: ctx._.Length - self.__Header.sizeof() - self._TransactionID.sizeof() ), )) self.__Cancel = Embedded(Struct( 'TransactionID' / self._TransactionID, )) # Convenience construct for parsing packets self.__PacketPayload = Debugger(Struct( 'Header' / Embedded(self.__Header), 'Payload' / Embedded(Switch( lambda ctx: ctx.Type, { 'InitCommand': self.__InitCommand, 'InitCommandAck': self.__InitCommandACK, 'InitEvent': self.__InitEvent, 'InitFail': self.__InitFail, 'Command': self.__Command, 'Response': self.__Response, 'Event': self.__Event, 'StartData': self.__StartData, 'Data': self.__Data, 'EndData': self.__EndData, }, default=Pass, )) ))
LUA_TNIL=0, LUA_TBOOLEAN=1, LUA_TLIGHTUSERDATA=2, LUA_TNUMBER=3, LUA_TSTRING=4, LUA_TTABLE=5, LUA_TFUNCTION=6, LUA_TUSERDATA=7, LUA_TTHREAD=8, ) Constant = Struct( "data_type" / LuaDatatype, "data" / Switch( this.data_type, { "LUA_INIL": Pass, "LUA_TBOOLEAN": Flag, "LUA_TNUMBER": LazyBound(lambda: LuaNumber), "LUA_TSTRING": String })) Constants = Struct( "sizek" / Int32ul, "constant" / Array(this.sizek, Constant), ) LineInfo = Struct("sizelineinfo" / Int32ul, "lineinfo" / Array(this.sizelineinfo, Int32ul)) LocVar = Struct("varname" / String, "startpc" / Int32ul, "endpc" / Int32ul) LocVars = Struct("sizelocvars" / Int32ul,
_MATCH_ORDERS = cStruct("limit" / Int16ul) _CONSUME_EVENTS = cStruct("limit" / Int16ul) _CANCEL_ORDER = cStruct( "side" / Int32ul, # Enum "order_id" / KEY, "open_orders" / Bytes(32), "open_orders_slot" / Int8ul, ) _CANCEL_ORDER_BY_CLIENTID = cStruct("client_id" / Int64ul) INSTRUCTIONS_LAYOUT = cStruct( "version" / Const(_VERSION, Int8ul), "instruction_type" / Int32ul, "args" / Switch( lambda this: this.instruction_type, { InstructionType.InitializeMarket: _INITIALIZE_MARKET, InstructionType.NewOrder: _NEW_ORDER, InstructionType.MatchOrder: _MATCH_ORDERS, InstructionType.ConsumeEvents: _CONSUME_EVENTS, InstructionType.CancelOrder: _CANCEL_ORDER, InstructionType.SettleFunds: Pass, # Empty list InstructionType.CancelOrderByClientID: _CANCEL_ORDER_BY_CLIENTID, }, ), )
"url" / GreedyString(encoding="ascii")) UnencryptedTLMFrame = Struct( "voltage" / Int16ub, "temperature" / Int16ul, "advertising_count" / Int32ub, "seconds_since_boot" / Int32ub, ) EncryptedTLMFrame = Struct("encrypted_data" / Array(12, Byte), "salt" / Int16ul, "mic" / Int16ul) EddystoneTLMFrame = Struct( "tlm_version" / Byte, "data" / Switch( lambda ctx: ctx.tlm_version, { EDDYSTONE_TLM_UNENCRYPTED: UnencryptedTLMFrame, EDDYSTONE_TLM_ENCRYPTED: EncryptedTLMFrame, })) EddystoneEIDFrame = Struct("tx_power" / Int8sl, "eid" / Array(8, Byte)) ServiceData = Struct( "service_identifier" / OneOf(Bytes(2), [EDDYSTONE_UUID, ESTIMOTE_UUID]), "frame_type" / Byte, "frame" / Switch( lambda ctx: ctx.service_identifier, { # eddystone frames EDDYSTONE_UUID: Switch( lambda ctx: ctx.frame_type, {
INITIALIZE_LAYOUT = Struct( "node" / PUBLIC_KEY_LAYOUT, "authorized_voter" / PUBLIC_KEY_LAYOUT, "authorized_withdrawer" / PUBLIC_KEY_LAYOUT, "commission" / Int8ul, ) INSTRUCTIONS_LAYOUT = Struct( "instruction_type" / Int32ul, "args" / Switch( lambda this: this.instruction_type, { InstructionType.INITIALIZE: INITIALIZE_LAYOUT, InstructionType.AUTHORIZE: Pass, # TODO InstructionType.VOTE: Pass, # TODO InstructionType.WITHDRAW: Pass, # TODO InstructionType.UPDATE_VALIDATOR_IDENTITY: Pass, # TODO InstructionType.UPDATE_COMMISSION: Pass, # TODO InstructionType.VOTE_SWITCH: Pass, # TODO InstructionType.AUTHORIZE_CHECKED: Pass, # TODO }, ), ) def initialize(params: InitializeParams) -> TransactionInstruction: """Creates a transaction instruction to initialize a new stake.""" data = INSTRUCTIONS_LAYOUT.build( dict( instruction_type=InstructionType.INITIALIZE, args=dict(
Embedded("action"/Switch(lambda ctx: ctx.type, { "interact": actions.interact, "move": actions.move, "stop": actions.stop, "stance": actions.stance, "guard": actions.guard, "follow": actions.follow, "formation": actions.formation, "waypoint": actions.waypoint, "give_attribute": actions.give_attribute, "add_attribute": actions.add_attribute, "ai_waypoint": actions.ai_waypoint, "ai_interact": actions.ai_interact, "ai_move": actions.ai_move, "ai_queue": actions.ai_queue, "save": actions.save, "chapter": actions.chapter, "ai_command": actions.ai_command, "spec": actions.spec, "build": actions.build, "game": actions.game, "patrol": actions.patrol, "wall": actions.wall, "delete": actions.delete, "attackground": actions.attackground, "repair": actions.repair, "release": actions.release, "togglegate": actions.togglegate, "flare": actions.flare, "order": actions.order, "droprelic": actions.droprelic, "gatherpoint": actions.gatherpoint, "townbell": actions.townbell, "resign": actions.resign, "tribute": actions.tribute, "queue": actions.queue, "multiqueue": actions.multiqueue, "research": actions.research, "sell": actions.sell, "buy": actions.buy, "backtowork": actions.backtowork, "de": actions.de, "postgame": actions.postgame }, default=Struct( "unk_action"/Computed(lambda ctx: ctx._.type), "bytes"/Bytes(lambda ctx: ctx._._.length - 1) ))),
unit_action = Struct( "type" / Int16ul, "data" / If( lambda ctx: ctx.type > 0, Struct( "state" / IfThenElse( lambda ctx: find_version(ctx) in [Version.AOK, Version.AOC], Byte, Int32ul), "target_object_pointer" / Int32sl, "target_object_pointer2" / Int32sl, "target_object_id" / Int32sl, "target_object_id_2" / Int32sl, "position" / vector, "timer" / Float32l, "target_moved_state" / Byte, "task_id" / Int16ul, "sub_action_value" / Byte, "sub_actions" / LazyBound(lambda x: action_list), "sprite_id" / Int16sl, Embedded("additional" / Switch(lambda ctx: ctx._.type, { 1: move_to, 3: enter, 9: attack, 21: make }, default=Pass))))) action_list = "action_list" / Struct("actions" / RepeatUntil( lambda x, lst, ctx: lst[-1].type == 0, unit_action)) action = "action" / Struct( Embedded(base_moving), "waiting" / Byte, "command_flag" / Byte, "selected_group_info" / If(lambda ctx: find_version(ctx) != Version.AOK, Int16ul), "actions" / action_list) base_combat = "base_combat" / Struct( Embedded(action), "formation_id" / Byte, "formation_row" / Byte, "formation_col" / Byte, "attack_timer" / Float32l, "capture_flag" / Byte,
DebugPayload = Struct( "subopcode" / EnumAdapter(Int8ul, DebugSubOpcode), "data" / Default(Switch( this.subopcode, { DebugSubOpcode.RSSI_THRESHOLD_SET: RssiThreshold, DebugSubOpcode.RSSI_THRESHOLD_STATUS: RssiThreshold, DebugSubOpcode.RADIO_TEST: RadioTest, DebugSubOpcode.TIMESLOT_TX_POWER_SET: TxPower, DebugSubOpcode.TIMESLOT_TX_POWER_STATUS: TxPower, DebugSubOpcode.SOFTDEVICE_TX_POWER_SET: TxPower, DebugSubOpcode.SOFTDEVICE_TX_POWER_STATUS: TxPower, DebugSubOpcode.UPTIME_STATUS: UptimeStatus, DebugSubOpcode.LAST_SW_FAULT_STATUS: LastFault, DebugSubOpcode.SYSTEM_STATS_STATUS: SystemStats, DebugSubOpcode.LAST_MALLOC_FAULT_STATUS: LastFault, DebugSubOpcode.LAST_FDS_FAULT_STATUS: LastFault, DebugSubOpcode.BYTES_BEFORE_GARBAGE_COLLECTOR_STATUS: GarbageCollector, DebugSubOpcode.PROVISIONED_APP_VERSION_STATUS: AppVersion, DebugSubOpcode.FULL_FIRMWARE_VERSION_STATUS: FirmwareVersion, DebugSubOpcode.IV_INDEX_STATUS: IvIndex, DebugSubOpcode.GARBAGE_COLLECTOR_COUNTER_STATUS: GarbageCollectorCounter, DebugSubOpcode.ARAP_LIST_SIZE_STATUS: ArapSize, DebugSubOpcode.ARAP_LIST_CONTENT_GET: ArapContentGet, DebugSubOpcode.ARAP_LIST_CONTENT_STATUS: ArapContent, }, ), None) ) DebugMessage = Struct(
LightCTLRangeStatus = Struct("status" / StatusCodeAdapter, Embedded(LightCTLRange)) LightCTLMessage = SwitchStruct( "opcode" / Opcode(LightCTLOpcode), "params" / Switch( this.opcode, { LightCTLOpcode.LIGHT_CTL_GET: LightCTLGet, LightCTLOpcode.LIGHT_CTL_SET: LightCTLSet, LightCTLOpcode.LIGHT_CTL_SET_UNACKNOWLEDGED: LightCTLSet, LightCTLOpcode.LIGHT_CTL_STATUS: LightCTLStatus, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_GET: LightCTLGet, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_RANGE_GET: LightCTLGet, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_RANGE_STATUS: LightCTLRangeStatus, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_SET: LightCTLTemperatureSet, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_SET_UNACKNOWLEDGED: LightCTLTemperatureSet, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_STATUS: LightCTLTemperatureStatus, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_DEFAULT_GET: LightCTLGet, LightCTLOpcode.LIGHT_CTL_TEMPERATURE_DEFAULT_STATUS: LightCTLDefault, }, )) LightCTLSetupMessage = SwitchStruct( "opcode" / Opcode(LightCTLSetupOpcode), "params" / Switch( this.opcode, {
hashlib.sha512(b'\xff' * 8 + hashlib.sha512( context._.header.value.dynamic_header.master_seed.data + context.transformed_key + b'\x01').digest()).digest(), context._.header.data, hashlib.sha256).digest() # --------------- KDF Params / Plugin Data ---------------- VariantDictionaryItem = Struct( "type" / Byte, "key" / Prefixed(Int32ul, GreedyString('utf-8')), "value" / Prefixed( Int32ul, Switch( this.type, { 0x04: Int32ul, 0x05: Int64ul, 0x08: Flag, 0x0C: Int32sl, 0x0D: Int64sl, 0x42: GreedyBytes, 0x18: GreedyString('utf-8') })), "next_byte" / Peek(Byte)) # new dynamic dictionary structure added in KDBX4 VariantDictionary = Struct( "version" / Bytes(2), "dict" / DynamicDict( 'key', RepeatUntil(lambda item, a, b: item.next_byte == 0x00, VariantDictionaryItem)), Padding(1) * "null padding") # -------------------- Dynamic Header --------------------
EnergyInAPeriodOfDay, PropertyID.RELATIVE_DEVICE_RUNTIME_IN_A_GENERIC_LEVEL_RANGE: RelativeRuntimeInAGenericLevelRange, PropertyID.RELATIVE_EXPOSURE_TIME_IN_AN_ILLUMINANCE_RANGE: RelativeValueInAnIlluminanceRange, PropertyID.RELATIVE_RUNTIME_IN_A_CORRELATED_COLOR_TEMPERATURE_RANGE: LuminousEnergy, PropertyID.RELATIVE_RUNTIME_IN_A_DEVICE_OPERATING_TEMPERATURE_RANGE: RelativeValueInATemperatureRange, PropertyID.RELATIVE_RUNTIME_IN_AN_INPUT_CURRENT_RANGE: RelativeValueInACurrentRange, PropertyID.RELATIVE_RUNTIME_IN_AN_INPUT_VOLTAGE_RANGE: RelativeValueInAVoltageRange, PropertyID.SHORT_CIRCUIT_EVENT_STATISTICS: EventStatistics, PropertyID.TIME_SINCE_MOTION_SENSED: TimeSecond16, PropertyID.TIME_SINCE_PRESENCE_DETECTED: TimeSecond16, PropertyID.TOTAL_DEVICE_ENERGY_USE: Energy, PropertyID.TOTAL_DEVICE_OFF_ON_CYCLES: Count24, PropertyID.TOTAL_DEVICE_POWER_ON_CYCLES: Count24, PropertyID.TOTAL_DEVICE_POWER_ON_TIME: TimeHour24, PropertyID.TOTAL_DEVICE_RUNTIME: TimeHour24, PropertyID.TOTAL_LIGHT_EXPOSURE_TIME: TimeHour24, PropertyID.TOTAL_LUMINOUS_ENERGY: LuminousEnergy, PropertyID.PRECISE_TOTAL_DEVICE_ENERGY_USE: PreciseEnergy, } PropertyValue = Switch(this.sensor_setting_property_id, PropertyDict, default=Array(this.length, Byte)) # fmt: off
AUTO_RESUME_TIMER = 0xFF72 class AutoResumeTimerAdapter(Adapter): def _decode(self, obj, context, path): return timedelta(milliseconds=obj) def _encode(self, obj, context, path): return int(obj.total_seconds() * 1000) # fmt: off LightExtendedControllerPropertyValue = Switch( this.id, { LightExtendedControllerProperty.AUTO_RESUME_MODE: Flag, LightExtendedControllerProperty.AUTO_RESUME_TIMER: AutoResumeTimerAdapter(Int24ul), } ) LightExtendedControllerPropertyGet = Struct( "id" / EnumAdapter(Int16ul, LightExtendedControllerProperty), ) LightExtendedControllerPropertySet = Struct( "id" / EnumAdapter(Int16ul, LightExtendedControllerProperty), "value" / LightExtendedControllerPropertyValue, ) LightExtendedControllerPropertyStatus = Struct( "id" / EnumAdapter(Int16ul, LightExtendedControllerProperty),
def _encode(self, obj, ctx): x = obj.encode('utf16') + '\x00\x00' return Container(length=len(x), value=x) VBString = VBStringAdapter() SomeKindOfEnumMaybe = Struct( Padding(16), # XXX: almost certainly useful somehow Int64ul ) TaggedData = Struct( 'tag'/Int16ul, 'value'/Switch(this.tag, { 3: Int32sl, 5: Float64l, 7: Int64ul, # timestamp? 8: VBString, 9: SomeKindOfEnumMaybe, 11: Const(b'\x00' * 2), # null? 35: Const(b'\x00' * 6), # EOF }) ) # Specialization for loading float data faster TaggedFloat64 = ExprAdapter( Struct(Const('tag'/Int16ul, 5), 'value'/Float64l), encoder=lambda obj, ctx: Container(tag=obj.tag, value=obj.value), decoder=lambda obj, ctx: obj.value) DataList = Struct( 'size'/Int64ul, OnDemand(Array(lambda ctx: ctx.size, TaggedFloat64)), Const('\xc0\xff\xee\x01') # XXX: probably useful )
) thread_group_snapshot = Struct( predefined_name_substruct, 'obj' / Struct('tgs_id' / Int64ul, 'tgs_name' / Padded(16, CString('utf8')), 'tgs_flags' / Int64ul), ) type_array_pad0 = Struct( 'flags_type' / Computed(lambda ctx: (ctx._.flags >> 32) & 0xffffffff), 'type' / Computed(lambda ctx: kcdata_types_enum.decmapping[ctx.flags_type]), 'count' / Computed(lambda ctx: ctx._.flags & 0xffffffff), 'name' / Computed(lambda ctx: predefined_names[ctx.type]), 'obj' / Array( this.count, LazyBound(lambda: Switch(lambda ctx: ctx.type, kcdata_types_structures, default=GreedyBytes))), ) type_array_pad4 = Struct( 'flags_type' / Computed(lambda ctx: (ctx._.flags >> 32) & 0xffffffff), 'type' / Computed(lambda ctx: kcdata_types_enum.decmapping[ctx.flags_type]), 'count' / Computed(lambda ctx: ctx._.flags & 0xffffffff), 'name' / Computed(lambda ctx: predefined_names[ctx.type]), 'obj' / Array( this.count, LazyBound(lambda: Switch(lambda ctx: ctx.type, kcdata_types_structures, default=GreedyBytes))), Padding(4), )
def _decode(self, obj, context, path): if int(obj.data_type) == 9: obj.data_type = LuaDatatype.parse(b'\x03') obj.data = float(obj.data) return obj def _encode(self, obj, context, path): return obj Constant = ConstantAdapter( Struct( "data_type" / LuaDatatypeAdapter(Byte), "data" / Switch( this.data_type, { "LUA_TNIL": Pass, "LUA_TBOOLEAN": Flag, "LUA_TNUMBER": LazyBound(lambda: LuaNumber), "LUA_TSTRING": String, "LUA_MIDATA": Int32ul }))) Constants = Struct("sizek" / Int32ul, "constant" / Array(this.sizek, Constant)) LineInfo = Struct("sizelineinfo" / Int32ul, "lineinfo" / Array(this.sizelineinfo, Int32ul)) LocVar = Struct("varname" / String, "startpc" / Int32ul, "endpc" / Int32ul) LocVars = Struct("sizelocvars" / Int32ul, "loc_var" / Array(this.sizelocvars, LocVar)) UpValues = Struct('sizeupvalues' / Int32ul,
} # Metadata subconstruct. metadata = MetadataAdapter( Struct( "metadata", RepeatUntil( lambda obj, context: obj["peeked"] == 0x7f, Struct( "data", BitStruct( "id", BitField("first", 3), BitField("second", 5), ), Switch("value", lambda context: context["id"]["first"], metadata_switch), Peek(UBInt8("peeked")), ), ), Const(UBInt8("terminator"), 0x7f), ), ) # Build faces, used during dig and build. faces = { "noop": -1, "-y": 0, "+y": 1, "-z": 2, "+z": 3, "-x": 4, "+x": 5,
) SceneSetupWithValidation = Struct( "scene_number" / ExprValidator(Int16ul, obj_ > 0), ) SceneSetup = Struct( "scene_number" / Int16ul ) SceneMessage = Struct( "opcode" / Opcode(SceneOpcode), "params" / Switch( this.opcode, { SceneOpcode.SCENE_GET: SceneGet, SceneOpcode.SCENE_RECALL: SceneRecall, SceneOpcode.SCENE_RECALL_UNACKNOWLEDGED: SceneRecall, SceneOpcode.SCENE_STATUS: SceneStatus, SceneOpcode.SCENE_REGISTER_GET: SceneRegisterGet, SceneOpcode.SCENE_REGISTER_STATUS: SceneRegisterStatus, SceneOpcode.SCENE_STORE: SceneSetupWithValidation, SceneOpcode.SCENE_STORE_UNACKNOWLEDGED: SceneSetupWithValidation, SceneOpcode.SCENE_DELETE: SceneSetup, SceneOpcode.SCENE_DELETE_UNACKNOWLEDGED: SceneSetup, } ) ) # fmt: on