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)))
class TestOptionalGreedyRange(unittest.TestCase): def setUp(self): self.c = OptionalGreedyRange(UBInt8("foo")) def test_trivial(self): pass def test_empty_parse(self): self.assertEqual(self.c.parse(b""), []) def test_parse(self): self.assertEqual(self.c.parse(b"\x01\x02"), [1, 2]) def test_empty_build(self): self.assertEqual(self.c.build([]), b"") def test_build(self): self.assertEqual(self.c.build([1, 2]), b"\x01\x02")
class TestOptionalGreedyRange(unittest.TestCase): def setUp(self): self.c = OptionalGreedyRange(UBInt8("foo")) def test_trivial(self): pass def test_empty_parse(self): self.assertEqual(self.c.parse(six.b("")), []) def test_parse(self): self.assertEqual(self.c.parse(six.b("\x01\x02")), [1, 2]) def test_empty_build(self): self.assertEqual(self.c.build([]), six.b("")) def test_build(self): self.assertEqual(self.c.build([1, 2]), six.b("\x01\x02"))
def __init__(self): self.constructFrame = Struct( 'parser', OptionalGreedyRange( Struct( 'packets', UBInt8('header'), UBInt16('plen'), UBInt8('functype'), UBInt64('nodeid'), UBInt8('sum'), )))
def __init__(self): self.constructFrame = Struct( "parser", OptionalGreedyRange( Struct( "packets", UBInt8("header"), UBInt16("plen"), UBInt8("dir"), ULInt64("nodeid"), UBInt16("funcid"), Array( lambda ctx: (ctx.plen - 1 - 8 - 2) / 8, Struct( "datas", ULInt16("type"), ULInt16("unit"), LFloat32("value"), )), UBInt8("sum"), # UBInt8("simulation") ), ), OptionalGreedyRange(UBInt8("leftovers"), ), )
class InstantSoupData(object): # common server = Struct("server", CString("server_id"), PrefixedArray(CString('channels'), UBInt8("num_channels"))) # structures from rfc opt_client_nick = CString('nickname') opt_client_membership = PrefixedArray(server, UBInt8("num_servers")) opt_server = Struct("opt_server", UBInt16("port")) opt_server_channels = Struct( "opt_server_channels", PrefixedArray(CString("channels"), UBInt8("num_channels"))) opt_server_invite = Struct( "opt_server_invite", CString("channel_id"), PrefixedArray(CString("client_id"), UBInt8("num_clients"))) # option fields option = Struct( "option", Enum(UBInt8("option_id"), CLIENT_NICK_OPTION=0x01, CLIENT_MEMBERSHIP_OPTION=0x02, SERVER_OPTION=0x10, SERVER_CHANNELS_OPTION=0x11, SERVER_INVITE_OPTION=0x12), Switch( "option_data", lambda ctx: ctx["option_id"], { "CLIENT_NICK_OPTION": opt_client_nick, "CLIENT_MEMBERSHIP_OPTION": opt_client_membership, "SERVER_OPTION": opt_server, "SERVER_CHANNELS_OPTION": opt_server_channels, "SERVER_INVITE_OPTION": opt_server_invite })) # the peer pdu itself peer_pdu = Struct("peer_pdu", CString('id'), OptionalGreedyRange(option)) command = PascalString("command", length_field=UBInt32("length"), encoding='utf8')
struct_set_brightness = Struct("set_brighthess", UBInt8("value_type"), UBInt8("value")) struct_power_source_control = Struct("power_source_control", UBInt8("boost1"), UBInt8("boost2"), UBInt8("charger1"), UBInt8("charger2")) struct_autofeed = Struct("autofeed", UBInt8("af_type"), SBInt16("steps")) struct_event_list = Struct("event_list", UBInt16("size"), OptionalGreedyRange(Struct("event", UBInt8("device"), UBInt8("event"), UBInt8("type")))) struct_new_tag = Struct("new_tag", SBInt16("timeout")) struct_initialize_ok = Struct("init_ok", UBInt8("response_code"), UBInt8("protocol_size"), Array(lambda ctx: ctx.protocol_size, UBInt8("protocols")), Array(12, UBInt8("model")), Embed(struct_tag_sn), Array(3, UBInt8("build")), UBInt8("watchdog"), UBInt32("free_ram"), UBInt32("free_print_mem"), UBInt32("free_page_mem"), UBInt8("machine_type")
CELL_MEASURE_REPORT = Struct("cell_measure_report", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt32("interval"), UBInt8("opcode")) CELL_MEASURE_REQUEST = Struct("cell_measure_request", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt8("opcode"), UBInt32("interval"), Rename("options", OptionalGreedyRange(OPTIONS))) CELL_MEASURE_RESPONSE = Struct("cell_measure_response", Rename("options", OptionalGreedyRange(OPTIONS))) MAC_PRBS_REQUEST = Struct("mac_prbs_request") MAC_PRBS_REPORT = Struct("mac_prbs_report", UBInt8("dl_prbs_total"), UBInt32("dl_prbs_used"), UBInt8("ul_prbs_total"), UBInt32("ul_prbs_used")) EP_MAC_PRBS_REQUEST = 0x0101 EP_MAC_PRBS_REPORT = 0x0102 CELL_MEASURE_TYPES = {EP_MAC_PRBS_REPORT: MAC_PRBS_REPORT}
AlphaString("line2"), AlphaString("line3"), AlphaString("line4"), ), 255: Struct( "error", AlphaString("message"), ), } packet_stream = Struct( "packet_stream", OptionalGreedyRange( Struct( "full_packet", UBInt8("header"), Switch("payload", lambda context: context["header"], packets), ), ), OptionalGreedyRange(UBInt8("leftovers"), ), ) def parse_packets(bytestream): """ Opportunistically parse out as many packets as possible from a raw bytestream. Returns a tuple containing a list of unpacked packet containers, and any leftover unparseable bytes. """
UnknownExtension = Struct( "", PascalString("bytes", length_field=UBInt16("extensions_length"))) Extension = Struct( "Extension", UBInt16("type"), Embed( Switch("", lambda ctx: ctx.type, { 0x00: SNIExtension, 0x10: ALPNExtension }, default=UnknownExtension))) extensions = TunnelAdapter( PascalString("extensions", length_field=UBInt16("extensions_length")), OptionalGreedyRange(Extension)) ClientHello = Struct( "ClientHello", ProtocolVersion, Random, SessionID, CipherSuites, CompressionMethods, extensions, ) ServerHello = Struct( "ServerHello", ProtocolVersion, Random,
def ssexy_linux(fname, *eips): import elf32 from construct import Struct, ULInt32, ULInt16, ULInt8, Array, CString from construct import OptionalGreedyRange # assume low-endian binary elf32_rel = Struct('elf32_rel', ULInt32('r_offset'), ULInt32('r_info')) ELF32_R_SYM = lambda x: x.r_info >> 8 ELF32_R_TYPE = lambda x: x.r_info & 0xff R_386_PC32 = 2 elf32_sym = Struct('elf32_sym', ULInt32('st_name'), ULInt32('st_value'), ULInt32('st_size'), ULInt8('st_info'), ULInt8('st_other'), ULInt16('st_shndx')) elf = elf32.elf32_file.parse_stream(file(fname, 'rb')) # retrieve section by name elf32_section = lambda elf, name: [ x for x in elf.sections if x.name == name ][0] # for now we assume that all code is in the .text section code_section = [x for x in elf.sections if x.name == '.text'] if not len(code_section): raise Exception('your binary doesn\'t have a .text section..') relocs = [x.data.value for x in elf.sections if x.name == '.rel.dyn'] if not len(relocs): raise Exception('no relocs available, compile with -pie') # read all relocations relocs = Array(len(relocs[0]) / elf32_rel.sizeof(), elf32_rel).parse(relocs[0]) # now get the offsets of the relocations relocs = set([x.r_offset for x in relocs]) imports = {} # a list of addresses that were used. addresses = [] # a list of all m128 values we use m128s = [] # a list of all dword values we use m32s = [] instructions = pyasm2.block() # get string at offset dynstr = lambda x: CString(None).parse( elf32_section(elf, '.dynstr').data.value[x:]) # read the symbol table imports = OptionalGreedyRange(elf32_sym).parse( elf32_section(elf, '.dynsym').data.value) # resolve relocations section = elf32_section(elf, '.rel.dyn') relocates = {} for x in xrange(0, section.size, elf32_rel.sizeof()): x = elf32_rel.parse(section.data.value[x:x + elf32_rel.sizeof()]) # relocation to fixup addresses to imports if ELF32_R_TYPE(x) == R_386_PC32: relocates[x.r_offset] = dynstr(imports[ELF32_R_SYM(x)].st_name) # walk each section, find those that are executable and disassemble those section = elf32_section(elf, '.text') g = distorm3.DecomposeGenerator(section.addr, section.data.value, distorm3.Decode32Bits) for instr in g: # useless instruction? if str(instr) in ('NOP', 'ADD [EAX], AL', 'LEA ESI, [ESI]', 'INT 3') or str(instr)[:2] == 'DB': continue # a jump to one of the imports? #if instr.mnemonic == 'JMP' and instr.operands[0].type == \ # distorm3.OPERAND_ABSOLUTE_ADDRESS and \ # instr.operands[0].disp in imports: # iat_label[instr.address] = imports[instr.operands[0].disp] # continue # quite hackery, but when the jumps with thunk address have been # processed, we can be fairly sure that there will be no (legit) # code anymore. #if len(iat_label): # break #print str(instr) #print str(instr) # convert the instruction from distorm3 format to pyasm2 format. instr = distorm3_to_pyasm2(instr) # we create the block already here, otherwise our `labelnr' is # not defined. #block = pyasm2.block(pyasm2.Label('%08x' % instr.address), instr) offset_flat = None addr = instr.address # now we check if this instruction has a relocation inside it # not a very efficient way, but oke. reloc = instr.length > 4 and relocs.intersection( range(instr.address, instr.address + instr.length - 3)) if reloc: # make an immediate with `addr' set to True enable_addr = lambda x: Immediate(int(x), addr=True) # TODO support for two relocations in one instruction # (displacement *and* immediate) reloc = reloc.pop() if not hasattr(instr, 'op1'): instr.op1, instr.op2 = None, None # there is only one operand, that's easy if not instr.op2: #sys.stderr.write('reloc in op1 %s??\n' % instr.op1) if isinstance(instr.op1, pyasm2.MemoryAddress): # special occassion, this memory addres is an import if instr.op1.reg1 is None and \ instr.op1.reg2 is None and \ int(instr.op1.disp) in imports: instr.op1 = imports[int(instr.op1.disp)] else: addresses.append(int(instr.op1.disp)) # change the displacement to a label #instr.op1 = str(instr.op1).replace('0x', # '__lbl_00') instr.op1 = enable_addr(instr.op1) elif isinstance(instr.op1, pyasm2.Immediate): addresses.append(int(instr.op1)) offset_flat = int(instr.op1) #instr.op1 = str(instr.op1).replace('0x', # 'offset flat:__lbl_00') # if the second operand is an immediate and the relocation is # in the last four bytes of the instruction, then this # immediate is the reloc. Otherwise, if the second operand is # a memory address, then it's the displacement. elif isinstance(instr.op2, pyasm2.Immediate) and reloc == \ instr.address + instr.length - 4: # keep this address addresses.append(int(instr.op2)) # make a label from this address # TODO: fix this horrible hack offset_flat = int(instr.op2) #instr.op2 = pyasm2.Label('offset flat:__lbl_%08x' % # int(instr.op2), prepend=False) elif isinstance(instr.op2, pyasm2.MemoryAddress) and \ reloc == instr.address + instr.length - 4: addresses.append(int(instr.op2.disp)) # change the displacement to a label instr.op2 = enable_addr(instr.op2) #instr.op2 = str(instr.op2).replace('0x', '__lbl_00') #sys.stderr.write('reloc in op2 memaddr %s\n' % # str(instr.op2)) # the relocation is not inside the second operand, it must be # inside the first operand after all. elif isinstance(instr.op1, pyasm2.MemoryAddress): addresses.append(int(instr.op1.disp)) instr.op1 = enable_addr(instr.op1) #instr.op1 = str(instr.op1).replace('0x', '__lbl_00') #sys.stderr.write('reloc in op1 memaddr %s\n' % # str(instr.op1)) elif isinstance(instr.op1, pyasm2.Immediate): addresses.append(int(instr.op1)) instr.op1 = enable_addr(instr.op1) #instr.op1 = '__lbl_%08x' % int(instr.op1) #sys.stderr.write('reloc in op1 imm %s\n' % instr.op1) else: sys.stderr.write('Invalid Relocation!\n') #print instr m32len = len(m32s) instr = translate.Translater(instr, m128s, m32s).translate() if offset_flat: encode_offset_flat = lambda x: str(x).replace( '0x', 'offset flat:__lbl_') if isinstance( x, (int, long, pyasm2.imm )) and int(x) == offset_flat or isinstance( x, pyasm2.mem) and x.disp == offset_flat else x if isinstance(instr, pyasm2.block): for x in instr.instructions: x.op1 = encode_offset_flat(x.op1) x.op2 = encode_offset_flat(x.op2) else: x.op1 = encode_offset_flat(x.op1) x.op2 = encode_offset_flat(x.op2) # update stuff m32s = m32s[:m32len] + [ x.replace('0x%08x' % offset_flat, 'offset flat:__lbl_%08x' % offset_flat) for x in m32s[m32len:] ] instructions += pyasm2.block(pyasm2.Label('%08x' % addr), instr) # remove any addresses that are from within the current section newlist = addresses[:] for i in xrange(len(addresses)): if addresses[i] >= code_section[0].addr and addresses[i] < \ code_section[0].addr + code_section[0].size: newlist[i] = None addresses = filter(lambda x: x is not None, newlist) # walk over each instruction, if it has references, we update them for instr in instructions.instructions: # we can skip labels if isinstance(instr, pyasm2.Label): continue # check for references to imports if isinstance(instr, pyasm2.RelativeJump): # not very good, but for now (instead of checking relocs) we check # if the index is in the iat tabel.. #if int(instr.lbl.index, 16) in iat_label: #instr.lbl.index = iat_label[int(instr.lbl.index, 16)] #instr.lbl.prepend = False continue program = ['.file "ssexy.c"', '.intel_syntax noprefix'] # we walk over each section, if a reference to this section has been found # then we will dump the entire section as bytecode.. with matching labels for section in elf.sections: base = section.addr data = section.data.value addr = set(range(base, base + section.size)).intersection(addresses) if addr: # create a header for this section program.append('.section %s' % section.name) # for now we do it the easy way.. one line and label per byte, lol for addr in xrange(section.size): program.append('__lbl_%08x: .byte 0x%02x' % (base + addr, ord(data[addr]))) # empty line.. program.append('') # now we define all xmm's etc we gathered program.append('.align 4') program += m32s program.append('.align 16') program += m128s # time to define 'main' program.append('.text') program.append('.globl Main') program.append('.type Main, @function') OEP = elf.entry # f****d up shit relocates = dict( ('jmp __lbl_%08x' % k, 'jmp ' + v) for k, v in relocates.items()) eips = ['__lbl_%08x' % x for x in eips] # append each instruction for instr in instructions.instructions: # if this is an label, we want a colon as postfix if isinstance(instr, pyasm2.Label): program.append(str(instr) + ':') # if OEP is at this address, we will also add the `_main' label if str(instr) == '__lbl_%08x' % OEP: program.append('Main:') # we have to initialize the stack register, so.. # for now we assume esp gpr is stored as first gpr in xmm7 program.append('movd xmm7, esp') # if the label is in the list of addresses to which we have to add # an "movd xmm7, esp" instruction, then add it (e.g. callback # function for pthread_create) if str(instr) in eips: program.append('movd xmm7, esp') else: # TODO: fix this terrible hack as well program.append( str(instr).replace('byte', 'byte ptr').replace( 'word', 'word ptr').replace('retn', 'ret').replace( '__lbl_00400000', '0x400000').replace('oword ptr', '')) if program[-1] in relocates: program[-1] = relocates[program[-1]] print '\n'.join(program)
), MetaField("data", lambda context: context["length"]), ), } packets_by_name = { "ping": 0, "disconnect": 255, } infinipacket_parser = Struct( "parser", OptionalGreedyRange( Struct( "packets", Peek(UBInt8("header")), Embed(Switch("packet", lambda context: context["header"], packets)), ), ), OptionalGreedyRange(UBInt8("leftovers"), ), ) def parse_packets(bytestream): container = infinipacket_parser.parse(bytestream) l = [(i.header, i.payload) for i in container.packets] leftovers = "".join(chr(i) for i in container.leftovers) if DUMP_ALL_PACKETS: for packet in l:
def setUp(self): self.c = OptionalGreedyRange(UBInt8("foo"))
E_TRIG = Struct("e_trig", UBInt16("action"), UBInt8("opcode")) HELLO = Struct("hello", UBInt32("padding")) CAPS_REQUEST = Struct("caps_request", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt8("opcode"), UBInt32("dummy")) CAPS_RESPONSE = Struct( "caps_response", BitStruct("flags", Padding(29), Bit("handover"), Bit("ue_measure"), Bit("ue_report")), Rename("options", OptionalGreedyRange(OPTIONS))) RAN_MAC_SLICE_REQUEST = Struct("ran_mac_slice_request", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt8("opcode"), Bytes("plmn_id", 4), UBInt8("dscp"), Bytes("padding", 3)) SET_RAN_MAC_SLICE_REQUEST = Struct( "set_ran_mac_slice_request", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt8("opcode"),
ASSOC_RESPONSE = Struct("assoc_response", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), Bytes("sta", 6)) NETWORKS = Struct("networks", Bytes("bssid", 6), Bytes("ssid", WIFI_NWID_MAXSIZE + 1)) ADD_LVAP = Struct( "add_lvap", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id"), BitStruct("flags", Padding(13), Bit("set_mask"), Bit("associated"), Bit("authenticated")), UBInt16("assoc_id"), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band"), UBInt8("supported_band"), Bytes("sta", 6), Bytes("encap", 6), Bytes("bssid", 6), Bytes("ssid", WIFI_NWID_MAXSIZE + 1), Rename("networks", OptionalGreedyRange(NETWORKS))) DEL_LVAP = Struct("del_lvap", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("sta", 6), UBInt8("csa_switch_mode"), UBInt8("csa_switch_count"), UBInt8("csa_switch_channel")) STATUS_LVAP = Struct( "status_lvap", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), BitStruct("flags", Padding(13), Bit("set_mask"), Bit("associated"), Bit("authenticated")), UBInt16("assoc_id"), Bytes("wtp", 6), Bytes("sta", 6), Bytes("encap", 6), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band"), UBInt8("supported_band"), Bytes("bssid", 6), Bytes("ssid", WIFI_NWID_MAXSIZE + 1), Rename("networks", OptionalGreedyRange(NETWORKS)))
"coords", UBInt32("x"), UBInt32("y"), UBInt32("z"), ), } # Metadata subconstruct. metadata = Struct( "metadata", OptionalGreedyRange( Struct( "data", BitStruct( "id", BitField("first", 3), BitField("second", 5), ), Switch("value", lambda context: context["id"]["first"], metadata_switch), ), ), Const(UBInt8("terminator"), 0x7f), ) # Build faces, used during dig and build. faces = { "noop": -1, "-y": 0, "+y": 1, "-z": 2, "+z": 3,
def greedy_string(name): """ Variable-length string field. """ return Rename(name, StringAdapter(OptionalGreedyRange(Field(None, 1))))
# Struct, 'report', caused some type of error I wasn't able to chase down. Also, the 'types' byte must be a raw value # (and, subsequently, Report.Types must subclass int) because of a bug between Const & FlagsEnum: # https://github.com/construct/construct/issues/73 admin_report = Struct( "admin", Const(UBInt16("length"), 13), Const(Byte("ID"), 1), Const(Byte("types"), 4), Const(PascalString("name", length_field=Byte("length"), encoding="utf8"), "admin"), Struct("version", Byte("major"), Byte("minor"), Byte("patch"))) HID_report = OptionalGreedyRange( Struct( "report", UBInt16("length"), Byte("ID"), FlagsEnum(Byte("types"), feature=4, output=2, input=1), PascalString("name", length_field=Byte("length"), encoding="utf8"), Array( lambda ctx: ctx.length - (len(ctx.name) + 1) - 4, BitStruct( "serialization", BitField("length", 6), Enum(BitField("type", 2), utf8=0, Uint=1, Int=2, Float=3))))) def hexstring_to_bytearray(string): return bytearray([int(pair.strip(','), 16) for pair in string.split(" ")]) def serialize(data): if hasattr(data[0], 'version'): return admin_report.build(data[0]) + HID_report.build(data[1:]) return HID_report.build(data)
UBInt32("cumulative_drops"), EpochTimeStampAdapter(UBInt32("timestamp_seconds")), UBInt32("timestamp_microseconds"), HexDumpAdapter(Field("data", lambda ctx: ctx.included_length)), # 24 being the static length of the packet_record header Padding(lambda ctx: ctx.record_length - ctx.included_length - 24), ) datalink_type = Enum( UBInt32("datalink"), IEEE802dot3=0, IEEE802dot4=1, IEEE802dot5=2, IEEE802dot6=3, ETHERNET=4, HDLC=5, CHARSYNC=6, IBMCHANNEL=7, FDDI=8, OTHER=9, UNASSIGNED=10, ) snoop_file = Struct( "snoop", Magic("snoop\x00\x00\x00"), UBInt32("version"), # snoop v1 is deprecated datalink_type, OptionalGreedyRange(packet_record), )
def __init__(self): self.constructFrameParse = Struct( "parser", OptionalGreedyRange(UBInt8("packets")), )
from construct import Struct, UBInt8, UBInt16, OptionalGreedyRange, Container #OptionalGreedyRange(subcon) berguna agar field tersebut berupa optional yang artinya boleh kosong kalau error juga akan diisi kongong mo_payload = Struct('mo_payload', UBInt8('destination'), UBInt8('flags'), UBInt16('msg_id'), OptionalGreedyRange(UBInt8("payload"))) payload = "Ini pesannya" a = Container(destination=1, msg_id=1, flags=1, payload=payload) print "a : ", a #build b = mo_payload.build(a) print "b : ", b #parse c = mo_payload.parse(b) print "c : ", c print "====================================" #lihat isi payload "ini pesannya hilang karna yang diutuhkan adalah Unsign bigendianes Integer 8 bit" #maka bisa dengan bantuan fungsi ord yang mengubah character dalam bentuk angka print "payload dlm bentuk symbol ASCII = ", payload print "len = ", len(payload) payload = map(ord, payload) print "payload dikonversi dari symbol ke integer= ", payload print "len = ", len(payload) hexa = map(hex, payload) print "dalam bentuk hexa(16) = ", hexa print "len dalam bentuk hexa(16) = ", len(hexa)
def packet_stream_print_header(context): #if context["header"] not in [28, 31, 32, 33, 34, 35]: #log.msg("packet_stream_print_header %s" % context["header"]) return context["header"] def print_and_return(pv, rv): log.msg("packet_stream_print_header %s" % pv) return rv packet_stream = Struct( "packet_stream", OptionalGreedyRange( Struct( "full_packet", UBInt8("header"), Switch("payload", packet_stream_print_header, packets), ), ), OptionalGreedyRange(UBInt8("leftovers"), ), ) def parse_packets(bytestream): """ Opportunistically parse out as many packets as possible from a raw bytestream. Returns a tuple containing a list of unpacked packet containers, and any leftover unparseable bytes. """