def create_xrf_struct(self, control_record): shift = control_record.shift Int32s, BitStructWrapper = { "big": (Int32sb, lambda x: x), "little": (Int32sl, ByteSwapped), }[self.endianness] return FocusedSeq( "data", "data" / DictSegSeq( idx_field=Int32s, subcon=BitStructWrapper( BitStruct( "block" / Default(BitsInteger(21 + shift, signed=True), 0), "is_new" / Default(Flag, False), "is_updated" / Default(Flag, False), "offset" / Default( ExprAdapter( BitsInteger(9 - shift), lambda obj, context: obj << shift, lambda obj, context: obj >> shift, ), 0), )), block_size=127, # Not counting the index field empty_item={}, check_nonempty=lambda item: any([ item.block, item.offset, item.is_new, item.is_updated, ]), ), Terminated, )
def create_ending_struct(self): return FocusedSeq( "empty", "_before_start" / Tell, Padding( lambda this: 512 - (this._before_start & 0x1ff), self.block_filler, ), "empty" / Terminated, )
#PioString = Struct( PioString = FocusedSeq( 1, "padded_length" / RepeatUntil(lambda x, lst, ctx: x != 0, Int8ul), "data" / Switch( this.padded_length[-1], { # string longer than 127 bytes, prefixed with 3 bytes length 0x40: FocusedSeq( 1, "actual_length" / ExprAdapter(Int24ul, lambda o, c: o + 4, lambda o, c: o - 4), "text" / String(this.actual_length, encoding="ascii")), # iso-8859 text with \x00 between every character (like utf-16, but its iso-8859) 0x90: FocusedSeq( 1, "actual_length" / ExprAdapter(Int24ul, lambda o, c: o + 4, lambda o, c: o - 4), "text" / ExprAdapter( String(this.actual_length, encoding="iso-8859-1"), lambda o, c: "".join(x + "\x00" for x in o), lambda o, c: o[::2])), }, default= # just ascii text FocusedSeq( 1, "actual_length" / Computed((this.padded_length[-1] - 1) // 2 - 1), "text" / String(this.actual_length, encoding="ascii"))))
from construct import FocusedSeq, Terminated from .common import SignatureAlgorithm struct = FocusedSeq('key', 'key' / SignatureAlgorithm.RSA4096.key_construct, Terminated)
DBField = Struct( "type" / DBFieldType, "value" / Switch( this.type, { "int8": Int8ub, "int16": Int16ub, "int32": Int32ub, "string": FocusedSeq( 0, PascalString(ExprAdapter(Int32ub, encoder=lambda obj, ctx: obj // 2 + 1, decoder=lambda obj, ctx: (obj - 1) * 2), encoding="utf-16-be"), Padding(2)), "binary": Prefixed(Int32ub, GreedyBytes) # parses to byte string })) class DBFieldFixedAdapter(Adapter): def __init__(self, subcon, ftype): self.ftype = ftype super().__init__(subcon) def _encode(self, obj, context): return {"type": self.ftype, "value": obj}
"entry_count" / Int16ul, # number of 4-byte values "u2" / Int16ul, # always 8191? ), Array(1004, Int32ul), Padding(20) ) ReverseIndexedEntry = FocusedSeq(1, "entry_offset" / Int16ul, "entry" / Pointer(this._._.entries_start+this.entry_offset, Switch(lambda ctx: "strange" if ctx._._.is_strange_page else ctx._._.page_type, { "block_tracks": Track, "block_artists": Artist, "block_albums": Album, "block_playlists": Playlist, "block_playlist_map": PlaylistMap, "block_artwork": Artwork, "block_colors": Color, "block_genres": Genre, "block_keys": Key, "block_labels": Label, #"strange": StrangePage, }, default = Computed("page type not implemented")), ) ) # unfortunately, the entry_enabled field contains even unexistant entries: # entry_enabled[:-1] matches revidx[:-1], # but len(entry_enabled)==16 while len(revidx)<=16 FirstReverseIndexArray = Struct( "entries" / Array(this._._.entry_count%16, ReverseIndexedEntry),
from construct import Bytes, Computed, ExprAdapter, FocusedSeq, Int8ul, Int16ul, Int24ul, Padding, Pointer, PaddedString, Restreamed, Switch, this PioString = FocusedSeq( "data", "padded_length" / Int8ul, "data" / Switch( this.padded_length, { # string longer than 127 bytes, prefixed with 3 bytes length 0x40: FocusedSeq( "text", "actual_length" / ExprAdapter(Int16ul, lambda o, c: o - 4, lambda o, c: o + 4), Padding(1), "text" / PaddedString(this.actual_length, encoding="ascii")), # utf-16 text 0x90: FocusedSeq( "text", "actual_length" / ExprAdapter(Int16ul, lambda o, c: o - 4, lambda o, c: o + 4), "text" / PaddedString(this.actual_length, "utf-16-be")), }, default= # just ascii text FocusedSeq( "text", "actual_length" / Computed((this._.padded_length - 1) // 2 - 1), "text" / PaddedString(this.actual_length, encoding="ascii")))) # parses a PioString relative to entry start using an str_idx array def OffsetPioString(index):
callStruct = NfsDiropArgs elif procedure == "getattr": callStruct = NfsFhandle elif procedure == "read": callStruct = NfsFileopArgs else: raise RuntimeError( "NFS call procedure {} not implemented".format(procedure)) return callStruct NfsDiropRes = Struct("fhandle" / NfsFhandle, "attrs" / NfsFattr) NfsFileopRes = Struct( "attrs" / NfsFattr, "data" / FocusedSeq("data", "length" / Int32ub, "data" / Bytes(this.length))) def getNfsResStruct(procedure): if procedure == "lookup": resStruct = NfsDiropRes elif procedure == "getattr": resStruct = NfsFhandle elif procedure == "read": resStruct = NfsFileopRes else: raise RuntimeError( "NFS result procedure {} not implemented".format(procedure)) return Struct("status" / NfsStatus, "content" / If(this.status == "ok", resStruct))
Select, Rebuild, Terminated, this ) from .compat import Const # RFC 4251 section 5 SshBytes = Prefixed(Int32ub, GreedyBytes) SshString = PascalString(Int32ub, 'utf8') SshMPInt = Select( Const(0, Int32ub), # zero stored as zero bytes of data FocusedSeq( 'num', 'len' / Rebuild(Int32ub, lambda ctx: int(ctx.num.bit_length() // 8 + 1)), 'num' / BytesInteger(this.len, signed=True), ), ) # RFC 4253 section 6.6 SshRSAKeyBlob = Struct( 'algo' / Const('ssh-rsa', SshString), 'e' / SshMPInt, 'n' / SshMPInt, Terminated ) # I-D.ietf-curdle-ssh-ed25519, section 4 SshEd25519KeyBlob = Struct( 'algo' / Const('ssh-ed25519', SshString),
"""AGENTC_SIGN_REQUEST flags. These are flags that can, in theory, be combined, but in practice they all conflict with each other, hence they are listed as an Enum here. """ AGENT_NO_FLAGS = 0 V1_AGENT_OLD_SIGNATURE = 1 AGENT_RSA_SHA2_256 = 2 AGENT_RSA_SHA2_512 = 4 SshAgentIdentities = FocusedSeq( 'keys', 'nkeys' / Rebuild(Int32ub, len_(this.keys)), 'keys' / Struct( 'key_blob' / SshBytes, 'comment' / SshString, )[this.nkeys], Terminated, ) SshAddRSAKey = Struct( 'n' / SshMPInt, 'e' / SshMPInt, 'd' / SshMPInt, 'iqmp' / SshMPInt, 'p' / SshMPInt, 'q' / SshMPInt, 'comment' / SshString, )