stringmessage = Struct('string', PascalString('string', length_field=ULInt16('string_length')) ) request = Struct('request', Struct('request_type', Embed(snaptype)) ) server_settings = Struct('settings', ULInt32('buffer_ms'), ULInt32('latency'), ULInt16('volume'), ULInt8('mute') ) sample_format = Struct('sample', ULInt32('rate'), ULInt16('bits'), ULInt16('channels'), ULInt16('sample_size'), ULInt16('frame_size') ) header = Struct('header', PascalString('codec', length_field=ULInt16('codec_length')), PascalString('header', length_field=ULInt32('header_length'))
from construct import Struct, ULInt8, ULInt24, BitStruct, Enum, BitField, Padding RPLIDAR_CMD_SYNC_BYTE = 0XA5 RPLIDAR_CMDFLAG_HAS_PAYLOAD = 0X80 RPLIDAR_ANS_SYNC_BYTE1 = 0XA5 RPLIDAR_ANS_SYNC_BYTE2 = 0X5A RPLIDAR_ANS_PKTFLAG_LOOP = 0X1 RPLIDAR_ANS_HEADER_SIZE_MASK = 0x3FFFFFFF RPLIDAR_ANS_HEADER_SUBTYPE_SHIFT = 30 rplidar_cmd_format = Struct( "cmd_format", ULInt8("sync_byte"), # Must be RPLIDAR_CMD_SYNC_BYTE ULInt8("cmd_flag")) rplidar_response_header_format = Struct( "ans_header", ULInt8("sync_byte_1"), # Must be RPLIDAR_ANS_SYNC_BYTE1 ULInt8("sync_byte_2"), # Must be RPLIDAR_ANS_SYNC_BYTE2 # _u32 size_q30_subtype; // see _u32 size:30; _u32 subType:2; # The size will contain the majority of the bytes, the subtype # is only 2 bits with either SINGLE or MULTI response currently available ULInt24("size"), BitStruct( "subtype_mode", Enum(BitField("mode", 2), SINGLE=0x0, MULTI=0x1, _default_="RESERVED"), Padding(6)), ULInt8("type"))
from construct import Struct, ULInt8, ULInt16, CString, Flag, Padding __all__ = ["Arm", "Claw", "Move", "Rotate"] _commandIds = {"Arm": 1, "Claw": 2, "Move": 3, "Rotate": 4} _armProtocol = Struct( "ArmProtocol", ULInt8("commandId"), Padding(1), #Padding zeros for 8 bits ULInt16("centimeters"), ) _clawProtocol = Struct( "ClawProtocol", ULInt8("commandId"), Padding(1), #Padding zeros for 8 bits ULInt16("centimeters"), ) _moveProtocol = Struct( "MoveProtocol", ULInt8("commandId"), ULInt8("direction"), ULInt16("centimeters"), ) _rotateProtocol = Struct( "RotateProtocol", ULInt8("commandId"), ULInt8("direction"),
from construct import ULInt32, LFloat32, ULInt8 from construct import Embed from construct import Array, Struct, Container # from construct.debug import Probe from pox.ethanol.ssl_message.msg_core import msg_default from pox.ethanol.ssl_message.msg_core import field_intf_name from pox.ethanol.ssl_message.msg_core import field_station from pox.ethanol.ssl_message.msg_core import field_mac_addr from pox.ethanol.ssl_message.msg_common import MSG_TYPE, VERSION from pox.ethanol.ssl_message.msg_common import send_and_receive_msg, len_of_string iw_bitrates = Struct( 'iw_bitrates', LFloat32("bitrate"), ULInt8('is_short'), # this is a boolean coded as a byte ) iw_bands = Struct( 'iw_bands', Embed(field_intf_name), ULInt32('band'), ULInt32('num_bitrates'), # Probe(), Array(lambda ctx: ctx.num_bitrates, iw_bitrates), ) msg_tx_bitrates = Struct( 'msg_tx_bitrates', Embed(msg_default), # default fields Embed(field_intf_name),
def __iter__(self): table_definition = self.tables.get_definition( self.current_table_number) for page_ref in self.pages.list(): if self.pages[page_ref].hierarchy_level == 0: for record in TpsRecordsList(self, self.pages[page_ref], encoding=self.encoding, check=self.check): if record.type == 'DATA' and record.data.table_number == self.current_table_number: check_value('table_record_size', len(record.data.data), table_definition.record_size) # TODO convert name to string fields = {"b':RecNo'": record.data.record_number} for field in table_definition.record_table_definition_field: field_data = record.data.data[field. offset:field.offset + field.size] value = '' if field.type == 'BYTE': value = ULInt8('byte').parse(field_data) elif field.type == 'SHORT': value = SLInt16('short').parse(field_data) elif field.type == 'USHORT': value = ULInt16('ushort').parse(field_data) elif field.type == 'DATE': value = self.to_date(field_data) elif field.type == 'TIME': value = self.to_time(field_data) elif field.type == 'LONG': #TODO if field.name.decode(encoding='cp437').split( ':')[1].lower() in self.date_fieldname: if SLInt32('long').parse(field_data) == 0: value = None else: value = date.fromordinal( 657433 + SLInt32('long').parse(field_data)) elif field.name.decode(encoding='cp437').split( ':')[1].lower() in self.time_fieldname: s, ms = divmod( SLInt32('long').parse(field_data), 100) value = str('{}.{:03d}'.format( time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(s)), ms)) else: value = SLInt32('long').parse(field_data) elif field.type == 'ULONG': value = ULInt32('ulong').parse(field_data) elif field.type == 'FLOAT': value = LFloat32('float').parse(field_data) elif field.type == 'DOUBLE': value = LFloat64('double').parse(field_data) elif field.type == 'DECIMAL': # TODO BCD if field_data[0] & 0xF0 == 0xF0: sign = -1 field_data = bytearray(field_data) field_data[0] &= 0x0F else: sign = 1 value = sign * int(hexlify( field_data)) / 10**field.decimal_count elif field.type == 'STRING': value = text_type( field_data, encoding=self.encoding).strip() elif field.type == 'CSTRING': value = text_type( field_data, encoding=self.encoding).strip() elif field.type == 'PSTRING': value = text_type( field_data[1:field_data[0] + 1], encoding=self.encoding).strip() else: # GROUP=0x16 # raise ValueError #TODO pass fields[text_type(field.name)] = value # print(fields) yield fields
RPLIDAR_RESP_MEASUREMENT_CHECKBIT = 0x1 << 0 RPLIDAR_RESP_MEASUREMENT_ANGLE_SHIFT = 1 ## #As defined by Figure 9. in "rplidar_interface_protocol_en.pdf" ## rplidar_response_device_measurement_format = Struct( "measurement_format", BitStruct("byte0", BitField("quality", 6), Flag("syncbit_inverse"), Flag("syncbit")), BitStruct( "byte1", BitField("angle_low", 7), Const(Flag("check_bit"), 1) # Must be set to 1 ), ULInt8("angle_high"), ULInt16("distance_q2")) ## # As defined by Figure 12. in "rplidar_interface_protocol_en.pdf" ## rplidar_response_device_info_format = Struct("info_format", ULInt8("model"), ULInt8("firmware_minor"), ULInt8("firmware_major"), ULInt8("hardware"), String("serial_number", 16)) ## # As defined by Figure 14. in "rplidar_interface_protocol_en.pdf" ## rplidar_response_device_health_format = Struct(
# And here we go. # Docs: http://projectpokemon.org/wiki/Pokemon_NDS_Structure pokemon_struct = Struct('pokemon_struct', # Header ULInt32('personality'), # XXX aughgh http://bulbapedia.bulbagarden.net/wiki/Personality Padding(2), ULInt16('checksum'), # XXX should be checked or calculated # Block A ULInt16('national_id'), ULInt16('held_item_id'), ULInt16('original_trainer_id'), ULInt16('original_trainer_secret_id'), ULInt32('exp'), ULInt8('happiness'), ULInt8('ability_id'), # XXX needs to match personality + species BitStruct('markings', Padding(2), Flag('diamond'), Flag('star'), Flag('heart'), Flag('square'), Flag('triangle'), Flag('circle'), ), Enum( ULInt8('original_country'), jp=1, us=2, fr=3,
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)