def num_attr(ctx): return ctx._.size / ctx._._.attr_size perf_file_attr = Struct( "perf_file_attr", Array( lambda ctx: num_attr(ctx), Struct("f_attr", perf_event_attr, perf_file_section("ids", id_array)))) perf_event_types = Struct("perf_file_attr", Anchor("here"), Padding(lambda ctx: ctx._.size)) perf_data = TunnelAdapter(Bytes("perf_data", lambda ctx: ctx.size), GreedyRange(perf_event())) #OnDemand(Bytes("perf_data", lambda ctx: ctx.size)) perf_file = Struct( "perf_file_header", # no support for version 1 Magic("PERFILE2"), UNInt64("size"), UNInt64("attr_size"), perf_file_section("attrs", perf_file_attr), perf_file_section("data", perf_data), perf_file_section("event_types", perf_event_types), # little endian Embedded( BitStruct(None, Flag("nrcpus"), Flag("arch"), Flag("version"),
def section_adapter(name, target): return perf_file_section( name, TunnelAdapter(String("data", lambda ctx: ctx.size), target))
"compression_methods", UBInt8("length"), # TODO: Reject packets of length 0 Array(lambda ctx: ctx.length, UBInt8("compression_methods")), ) ServerName = Struct( "", UBInt8("type"), PascalString("name", length_field=UBInt16("length")), ) SNIExtension = Struct( "", TunnelAdapter( PascalString("server_names", length_field=UBInt16("length")), TunnelAdapter(PascalString("", length_field=UBInt16("length")), GreedyRange(ServerName)), ), ) ALPNExtension = Struct( "", TunnelAdapter( PascalString("alpn_protocols", length_field=UBInt16("length")), TunnelAdapter(PascalString("", length_field=UBInt16("length")), GreedyRange(PascalString("name"))), ), ) UnknownExtension = Struct( "", PascalString("bytes", length_field=UBInt16("extensions_length")))