def str_with_len(name): return Struct(name, UNInt32("len"), Anchor("start"), CString(name), Anchor("offset"), pad())
def string_list(name, extra = Pass): return PrefixedArray(Struct(name, UNInt32("len"), Anchor("start"), CString(name), Anchor("offset"), pad(), extra), UNInt32("nr"))
def build_id(): return Struct("build_id", Anchor("start"), UNInt32("type"), UNInt16("misc"), UNInt16("size"), SNInt32("pid"), HexDumpAdapter(String("build_id", 24)), CString("filename"), Anchor("offset"), pad("size"))
def mmap(): return Struct("mmap", SNInt32("pid"), SNInt32("tid"), UNInt64("addr"), UNInt64("len"), UNInt64("pgoff"), Anchor("start_of_filename"), CString("filename"), Anchor("end_of_filename"), # hack for now. this shouldn't be needed. If(lambda ctx: True, # XXX Embedded(Pointer(lambda ctx: ctx.size + ctx.start - sample_id_size(ctx), sample_id()))))
def RRName(name): ''' A Resource Record Name structure. Supports DNS pointer compression through the MovingPointer class ''' return Struct( name, Anchor('_start'), Union( 'length_or_offset', UBInt8('length'), # regular label UBInt16('offset'), # compression pointer ), IfThenElse( 'name', this.length_or_offset.length & 0xc0 == 0xc0, # compression pointer MovingPointer( lambda ctx: ctx.length_or_offset.offset & ~0xc000, Label(name), offset=1, whence=os.SEEK_CUR, ), # regular label MovingPointer(this._start, Label(name)), ), )
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() }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start)))
def event(): return Embedded( Struct( "event", If(lambda ctx: sample_type(ctx).identifier, UNInt64("identifier")), If(lambda ctx: sample_type(ctx).ip, UNInt64("ip")), If(lambda ctx: sample_type(ctx).tid, Embedded(Struct("tid", SNInt32("pid"), SNInt32("tid")))), If(lambda ctx: sample_type(ctx).time, UNInt64("time")), If(lambda ctx: sample_type(ctx).addr, UNInt64("addr")), If(lambda ctx: sample_type(ctx).id, UNInt64("id")), If(lambda ctx: sample_type(ctx).stream_id, UNInt64("stream_id")), If(lambda ctx: sample_type(ctx).cpu, Embedded(Struct("cpu", UNInt32("cpu"), UNInt32("res")))), If(lambda ctx: sample_type(ctx).period, UNInt64("period")), If(lambda ctx: sample_type(ctx).read, read_format()), If( lambda ctx: sample_type(ctx).callchain, Struct("callchain", UNInt64("nr"), Array(lambda ctx: ctx.nr, UNInt64("caller")))), If( lambda ctx: sample_type(ctx).raw, Struct("raw", UNInt32("size"), Bytes("raw", lambda ctx: ctx.size))), If( lambda ctx: sample_type(ctx).branch_stack, Struct( "branch_stack", UNInt64("nr"), Array( lambda ctx: ctx.nr, Struct( "branch", UNInt64("from"), UNInt64("to"), # Little-Endian! BitStruct("flags", Padding(4), Flag("abort"), Flag("in_tx"), Flag("predicted"), Flag("mispred"), Padding(64 - 1 * 8)))))), If( lambda ctx: sample_type(ctx).regs_user, Struct("regs_user", Enum(UNInt64("abi"), NONE=0, ABI_32=1, ABI_64=2), Array(lambda ctx: hweight64(ctx), UNInt64("reg")))), If( lambda ctx: sample_type(ctx).stack_user, Struct("stack_user", UNInt64("size"), Bytes("data", lambda ctx: ctx.size), UNInt64("dyn_size"))), If(lambda ctx: sample_type(ctx).weight, UNInt64("weight")), If(lambda ctx: sample_type(ctx).data_src, UNInt64("data_src")), If(lambda ctx: sample_type(ctx).transaction, UNInt64("transaction")), If( lambda ctx: sample_type(ctx).regs_intr, Struct("regs_intr", Enum(UNInt64("abi"), NONE=0, ABI_32=1, ABI_64=2), Array(lambda ctx: hweight64(ctx), UNInt64("reg")))), Anchor("end_event"), Padding(lambda ctx: max(0, ctx.size - ctx.end_event))))
"SAMPLE": event() }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start))) def perf_event_seq(attr): return GreedyRange(perf_event(attr)) perf_event_attr_sizes = (64, 72, 80, 96, 104) perf_event_attr = Struct( "perf_event_attr", Anchor("start"), Enum(UNInt32("type"), HARDWARE=0, SOFTWARE=1, TRACEPOINT=2, HW_CACHE=3, RAW=4, BREAKPOINT=5), UNInt32("size"), UNInt64("config"), UNInt64("sample_period_freq"), # must be in LE order, original is a u64 # each byte is reversed BitStruct("sample_type", Flag("cpu"), Flag("id"), Flag("callchain"), Flag("read"), Flag("addr"), Flag("time"), Flag("tid"), Flag("ip"), Flag("data_src"), Flag("weight"), Flag("stack_user"),
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)))
"STAT_ROUND": ignore(), "EVENT_UPDATE": ignore(), "HEADER_FEATURE": ignore(), "COMPRESSED": ignore(), }), Anchor("end"), Padding(lambda ctx: ctx.size - (ctx.end - ctx.start))) def perf_event_seq(attr): return GreedyRange(perf_event(attr)) perf_event_attr_sizes = (64, 72, 80, 96, 104) perf_event_attr = Struct("perf_event_attr", Anchor("start"), Enum(UNInt32("type"), HARDWARE = 0, SOFTWARE = 1, TRACEPOINT = 2, HW_CACHE = 3, RAW = 4, BREAKPOINT = 5), UNInt32("size"), UNInt64("config"), UNInt64("sample_period_freq"), # must be in LE order, original is a u64 # each byte is reversed BitStruct("sample_type", Flag("cpu"), Flag("id"),
def ResourceRecord(name): return Struct( name, Embed(RRNAME), TYPE, CLASS, TTL, RDLENGTH, RDATA, ) # The DNS packet header itself, combining all of the above DNSHeader = Struct( 'DNSHeader', Anchor('packet_start'), UBInt16('identification'), BitStruct( 'flags_and_codes', Enum( BitField('qr', 1), # query/response QUERY=0, RESPONSE=1, ), Nibble('opcode'), # opcode Enum( Flag('aa'), # authoritative answer NON_AUTHORITATIVE=0, AUTHORITATIVE=1, ), Enum(