예제 #1
0
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'))
예제 #2
0
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"))
예제 #3
0
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"),
예제 #4
0
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),
예제 #5
0
    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
예제 #6
0
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(
예제 #7
0
# 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,
예제 #8
0
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)