class TestThisExpressions(unittest.TestCase): this_example = Struct("this_example", # straight-forward usage: instead of passing (lambda ctx: ctx["length"]) use this.length UBInt8("length"), Field("value", this.length), # an example of nesting: '_' refers to the parent's scope Struct("nested", UBInt8("b1"), UBInt8("b2"), Value("b3", this.b1 * this.b2 + this._.length) ), # and conditions work as expected IfThenElse("condition", this.nested.b1 > 50, UBInt32("foo"), UBInt8("bar"), ) ) def test_parse(self): res = self.this_example.parse(six.b("\x05helloABXXXX")) expected = Container(length = 5, value = six.b('hello'), nested = Container(b1 = 65, b2 = 66, b3 = 4295), condition = 1482184792) self.assertEquals(res, expected) def test_build(self): obj = Container(length = 5, value = six.b('hello'), nested = Container(b1 = 65, b2 = 66, b3 = None), condition = 1482184792) data = self.this_example.build(obj) self.assertEquals(data, six.b("\x05helloABXXXX"))
def __init__(self): self.constructFrameParse = Struct( "parser", OptionalGreedyRange(UBInt8("packets")), Value( "checkSum", lambda ctx: str(hex((255 - sum(ctx.packets[3:])) & 0xff))[ 2:].zfill(2)[-2:]))
def __init__(self): self.constructFrameParse = Struct( "parser", OptionalGreedyRange(UBInt8("packets")), Value( "checkSum", lambda ctx: int((hex( (255 - sum(ctx.packets[3:])) & 0xffffffffffffffff)[-3:-1]), 16)))
def perf_event_header(): return Embedded(Struct(None, Enum(UNInt32("type"), MMAP = 1, LOST = 2, COMM = 3, EXIT = 4, THROTTLE = 5, UNTHROTTLE = 6, FORK = 7, READ = 8, SAMPLE = 9, MMAP2 = 10, RECORD_AUX = 11, ITRACE_START = 12, LOST_SAMPLES = 13, SWITCH = 14, SWITCH_CPU_WIDE = 15, NAMESPACES = 16, KSYMBOL = 17, BPF_EVENT = 18, CGROUP = 19, HEADER_ATTR = 64, HEADER_EVENT_TYPE = 65, TRACING_DATA = 66, HEADER_BUILD_ID = 67, FINISHED_ROUND = 68, ID_INDEX = 69, AUXTRACE_INFO = 70, AUXTRACE = 71, AUXTRACE_ERROR = 72, THREAD_MAP = 73, CPU_MAP = 74, STAT_CONFIG = 75, STAT = 76, STAT_ROUND = 77, EVENT_UPDATE = 78, TIME_CONV = 79, HEADER_FEATURE = 80, COMPRESSED = 81), Embedded(BitStruct(None, Padding(1), Enum(BitField("cpumode", 7), UNKNOWN = 0, KERNEL = 1, USER = 2, HYPERVISOR = 3, GUEST_KERNEL = 4, GUEST_USER = 5), Flag("ext_reserved"), Flag("exact_ip"), Flag("mmap_data"), Padding(5))), UNInt16("size"), If(has_sample_id_all, Pointer(lambda ctx: ctx.start + ctx.size - 8, UNInt64("end_id"))), Value("attr", lookup_event_attr)))
def perf_event_header(): return Embedded( Struct( None, Enum(UNInt32("type"), MMAP=1, LOST=2, COMM=3, EXIT=4, THROTTLE=5, UNTHROTTLE=6, FORK=7, READ=8, SAMPLE=9, MMAP2=10, TRACING_DATA=66, FINISHED_ROUND=68, ID_INDEX=69, AUXTRACE_INFO=70, AUXTRACE=71, AUXTRACE_ERROR=72), Embedded( BitStruct( None, Padding(1), Enum(BitField("cpumode", 7), UNKNOWN=0, KERNEL=1, USER=2, HYPERVISOR=3, GUEST_KERNEL=4, GUEST_USER=5), Flag("ext_reserved"), Flag("exact_ip"), Flag("mmap_data"), Padding(5))), UNInt16("size"), If( has_sample_id_all, Pointer(lambda ctx: ctx.start + ctx.size - 8, UNInt64("end_id"))), Value("attr", lookup_event_attr)))
class Bitmap(FixedObjectByteArray): classID = 13 _construct = Struct( "", UBInt32("length"), construct.String("items", lambda ctx: ctx.length * 4), # Identically named "String" class -_- ) @classmethod def from_value(cls, obj): return cls(obj.items) def to_value(self): value = self.value length = (len(value) + 3) / 4 value += "\x00" * (length * 4 - len(value)) # padding return Container(items=value, length=length) _int = Struct( "int", UBInt8("_value"), If( lambda ctx: ctx._value > 223, IfThenElse( "", lambda ctx: ctx._value <= 254, Embed( Struct( "", UBInt8("_second_byte"), Value( "_value", lambda ctx: (ctx._value - 224) * 256 + ctx._second_byte), )), Embed(Struct( "", UBInt32("_value"), )))), ) _length_run_coding = Struct( "", Embed(_int), #ERROR? Value("length", lambda ctx: ctx._value), OptionalGreedyRepeater( Struct( "data", Embed(_int), Value("data_code", lambda ctx: ctx._value % 4), Value("run_length", lambda ctx: (ctx._value - ctx.data_code) / 4), Switch( "", lambda ctx: ctx.data_code, { 0: Embed( Struct( "", StrictRepeater( get_run_length, Value("pixels", lambda ctx: "\x00\x00\x00\x00")), )), 1: Embed( Struct( "", Bytes("_b", 1), StrictRepeater( get_run_length, Value("pixels", lambda ctx: ctx._b * 4), ), )), 2: Embed( Struct( "", Bytes("_pixel", 4), StrictRepeater( get_run_length, Value("pixels", lambda ctx: ctx._pixel), ), )), 3: Embed( Struct( "", StrictRepeater( get_run_length, Bytes("pixels", 4), ), )), }), ))) @classmethod def from_byte_array(cls, bytes_): """Decodes a run-length encoded ByteArray and returns a Bitmap. The ByteArray decompresses to a sequence of 32-bit values, which are stored as a byte string. (The specific encoding depends on Form.depth.) """ runs = cls._length_run_coding.parse(bytes_) pixels = (run.pixels for run in runs.data) data = "".join(itertools.chain.from_iterable(pixels)) return cls(data) def compress(self): """Compress to a ByteArray""" raise NotImplementedError
Flag("exclude_callchain_user"), Padding(41))), UNInt32("wakeup_events"), UNInt32("bp_type"), UNInt64("config1"), If(lambda ctx: ctx.size >= perf_event_attr_sizes[1], UNInt64("config2")), If(lambda ctx: ctx.size >= perf_event_attr_sizes[2], UNInt64("branch_sample_type")), If( lambda ctx: ctx.size >= perf_event_attr_sizes[3], Embedded( Struct(None, UNInt64("sample_regs_user"), UNInt32("sample_stack_user"), UNInt32("__reserved_2")))), If(lambda ctx: ctx.size >= perf_event_attr_sizes[4], UNInt64("sample_regs_intr")), Anchor("end"), Value("perf_event_attr_size", lambda ctx: ctx.end - ctx.start), Padding(lambda ctx: ctx.size - ctx.perf_event_attr_size)) def pad(l="len"): return Padding(lambda ctx: ctx[l] - (ctx.offset - ctx.start)) def str_with_len(name): return Struct(name, UNInt32("len"), Anchor("start"), CString(name), Anchor("offset"), pad()) def feature_string(name): return If( lambda ctx: ctx._[name],
"increment statistics", UBInt32("sid"), UBInt8("count"), ), 201: Struct( "player list item", AlphaString("name"), Bool("online"), UBInt16("ping"), ), 202: Struct( "player abilities", UBInt8("flags"), Value("is_god", lambda ctx: ctx["flags"] & 1), Value("is_flying", lambda ctx: ctx["flags"] & 2), Value("can_fly", lambda ctx: ctx["flags"] & 4), Value("is_creative", lambda ctx: ctx["flags"] & 8), UBInt8("walking_speed"), UBInt8("flying_speed"), ), 203: Struct( "tab complete", AlphaString("text"), ), 204: Struct( "locale view distance", AlphaString("locale"),
), # or is this 0 terminated?! cf bogus IN here: b'A:\\RO_RES\\COLD.BIN\x00IN', ) code = OnDemand(Bytes("code", lambda ctx: ctx.len_code)) sunp_file = Struct( "sunp_file", Magic(b"SUNP BURN FILE"), Padding(2, strict=True), # guessing... ULInt32("file_size"), ULInt32("off_burnhdr1"), ULInt32("off_burnhdr2"), ULInt32("off_code"), ULInt32("unk_zero"), ULInt32("off_burnhdr3"), Value("len_code", lambda ctx: ctx.off_burnhdr3 - ctx.off_code), #Padding(472), Pointer(lambda ctx: ctx.off_burnhdr1, burnhdr1), Pointer(lambda ctx: ctx.off_burnhdr2, burnhdr2), Pointer(lambda ctx: ctx.off_code, code), Pointer(lambda ctx: ctx.off_burnhdr3, burnhdr3), ) if __name__ == '__main__': import pprint import argparse parser = argparse.ArgumentParser( description='Parse a SUNP BURN FILE (SPHOST.BRN)') parser.add_argument("filename", type=str,