Пример #1
0
def DirEntry(name):
    return Struct(
        name,
        Bytes("name", 8),
        Bytes("extension", 3),
        BitStruct("attributes", Flag("unused"), Flag("device"),
                  Flag("archive"), Flag("subDirectory"), Flag("volumeLabel"),
                  Flag("system"), Flag("hidden"), Flag("readonly")),
        # reserved
        Padding(10),
        ULInt16("timeRecorded"),
        ULInt16("dateRecorded"),
        ULInt16("firstCluster"),
        ULInt32("fileSize"))
Пример #2
0
def send_packet(srv, opcode_, *fields):
    class C:
        opcode = opcode_

    ms = [ULInt16("opcode")]

    for macro, value in fields:
        setattr(C, macro.name, value)
        ms.append(macro)

    d = Struct("packet", *ms)
    d.build_stream(C, srv)
Пример #3
0
    def __init__(self, tps, tps_page, encoding=None, check=False):
        self.tps = tps
        self.check = check
        self.tps_page = tps_page
        self.encoding = encoding
        global record_encoding
        record_encoding = encoding
        self.__records = []

        if self.tps_page.hierarchy_level == 0:
            if self.tps_page.ref in self.tps.cache_pages:
                self.__records = tps.cache_pages[self.tps_page.ref]
            else:
                data = self.tps.read(
                    self.tps_page.size - PAGE_HEADER_STRUCT.sizeof(),
                    self.tps_page.ref * 0x100 + self.tps.header.size +
                    PAGE_HEADER_STRUCT.sizeof())

                if self.tps_page.uncompressed_size > self.tps_page.size:
                    data = self.__uncompress(data)

                    if self.check:
                        check_value('record_data.size',
                                    len(data) + PAGE_HEADER_STRUCT.sizeof(),
                                    tps_page.uncompressed_size)

                record_data = b''
                pos = 0
                record_size = 0
                record_header_size = 0

                while pos < len(data):
                    byte_counter = data[pos]
                    pos += 1
                    if (byte_counter & 0x80) == 0x80:
                        record_size = data[pos + 1] * 0x100 + data[pos]
                        pos += 2
                    if (byte_counter & 0x40) == 0x40:
                        record_header_size = data[pos + 1] * 0x100 + data[pos]
                        pos += 2
                    byte_counter &= 0x3F
                    new_data_size = record_size - byte_counter
                    record_data = record_data[:byte_counter] + data[
                        pos:pos + new_data_size]
                    self.__records.append(
                        TpsRecord(
                            record_header_size,
                            ULInt16('data_size').build(record_size) +
                            record_data))
                    pos += new_data_size

                if self.tps.cached and self.tps_page.ref not in tps.cache_pages:
                    tps.cache_pages[self.tps_page.ref] = self.__records
Пример #4
0
def dispatch(stream, protodef):
    opcode = ULInt16("opcode").parse_stream(stream)

    if opcode in protodef:
        func, macro = protodef[opcode]
        data = macro.parse_stream(stream)
        func(data)
    else:
        data = ''
        pktlen = packet_lengths.get(opcode, -1)

        if pktlen > 0:
            data = stream.read(pktlen - 2)
        elif pktlen == -1:
            datadef = Struct(
                "data", ULInt16("length"),
                MetaField("ignore", lambda ctx: ctx["length"] - 4))
            data = datadef.parse_stream(stream)

        netlog.warning('UNIMPLEMENTED opcode={:04x} data={}'.format(
            opcode, data))
Пример #5
0
 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"), ),
     )
Пример #6
0
def Fat16Header(name):
    return Struct(name, Bytes("jumpInstruction", 3),
                  Bytes("creatingSystemId", 8), ULInt16("sectorSize"),
                  Byte("sectorsPerCluster"), ULInt16("reservedSectorCount"),
                  Byte("fatCount"), ULInt16("rootdirEntryCount"),
                  ULInt16("sectorCount_small"), Byte("mediaId"),
                  ULInt16("sectorsPerFat"), ULInt16("sectorsPerTrack"),
                  ULInt16("sideCount"), ULInt32("hiddenSectorCount"),
                  ULInt32("sectorCount_large"), Byte("physicalDriveNumber"),
                  Byte("currentHead"), Byte("extendedBootSignature"),
                  Bytes("volumeId", 4), Bytes("volumeLabel", 11),
                  Const(Bytes("fsType", 8), "FAT16   "),
                  Bytes("bootCode", 448),
                  Const(Bytes("bootSectorSignature", 2), "\x55\xaa"))
Пример #7
0
 def sendCommand(self, buf):
     '''
     Sends a command to the robot
     :param buf: serialized robot command
     '''
     num = sum(map(lambda x: int(struct.unpack('<B', x)[0]), buf))
     chksum = ULInt16("checksum").build(num)
     retry = True
     while retry:
         super(RobotSerial, self).write(buf)
         super(RobotSerial, self).write(chksum)
         super(RobotSerial, self).flushInput()
         response = _robotResponse.parse(super(RobotSerial, self).read())
         if response.success:
             retry = False
             sleep(2)
Пример #8
0
def FatEntry(name):
    return Enum(ULInt16(name),
                free_cluster=0x0000,
                bad_cluster=0xfff7,
                last_cluster=0xffff,
                _default_=Pass)
Пример #9
0
def convert_file(mavlink_file, pcap_file):
    # the whole file is read in a bunch - room for improvement...
    data = mavlink_file.read()

    i = 0
    done = False
    skipped_char = None
    junk = ''
    cnt_ok = 0
    cnt_junk = 0
    cnt_crc = 0

    while not done:
        i += 1
        # look for potential start of frame
        next_sof = find_next_frame(data)
        if next_sof > 0:
            print "skipped " + str(next_sof) + " bytes"
            if write_junk:
                if skipped_char != None:
                    junk = skipped_char + data[:next_sof]
                    skipped_char = None
                write_packet(i, junk, 0x03, len(junk))
            data = data[next_sof:]
            data[:6]
            cnt_junk += 1

        # assume, our 0xFE was the start of a packet
        header = parse_header(data)
        payload_len = header['plength']
        pkt_length = 6 + payload_len + 2
        try:
            pkt_crc = ULInt16('crc').parse(data[pkt_length - 2:pkt_length])
        except FieldError:
            # ups, no more data
            done = True
            continue

        # peek for the next SOF
        try:
            cc = mavutil.x25crc(data[1:6 + payload_len])
            cc.accumulate(chr(MAVLINK_MESSAGE_CRCS[header['msgid']]))
            x25_crc = cc.crc
            if x25_crc != pkt_crc:
                crc_flag = 0x1
            else:
                crc_flag = 0
            next_magic = data[pkt_length]
            if chr(MAVLINK_MAGIC) != next_magic:
                # damn, retry
                print "packet %d has invalid length, crc error: %d" % (
                    i, crc_flag)

                # skip one char to look for a new SOF next round, stow away skipped char
                skipped_char = data[0]
                data = data[1:]
                continue

            # we can consider it a packet now
            pkt = data[:pkt_length]
            write_packet(i, pkt, crc_flag, len(pkt))
            print "packet %d ok, crc error: %d" % (i, crc_flag)
            data = data[pkt_length:]

            if crc_flag:
                cnt_crc += 1
            else:
                cnt_ok += 1

        except IndexError:
            # ups, no more packets
            done = True
    print "converted %d valid packets, %d crc errors, %d junk fragments (total %f%% of junk)" % (
        cnt_ok, cnt_crc, cnt_junk, 100. * float(cnt_junk + cnt_crc) /
        (cnt_junk + cnt_ok + cnt_crc))
Пример #10
0
import struct
from hfs import HFSVolume, HFSFile
from keystore.keybag import Keybag
from structs import HFSPlusVolumeHeader, kHFSPlusFileRecord, getString
from construct import Struct, ULInt16, ULInt32, String
from Crypto.Cipher import AES
from construct.macros import ULInt64, Padding
from structs import kHFSRootParentID
import hashlib
"""
iOS >= 4 raw images
http://opensource.apple.com/source/xnu/xnu-1699.22.73/bsd/hfs/hfs_cprotect.c
http://opensource.apple.com/source/xnu/xnu-1699.22.73/bsd/sys/cprotect.h
"""

cp_root_xattr = Struct("cp_root_xattr", ULInt16("major_version"),
                       ULInt16("minor_version"), ULInt64("flags"),
                       ULInt32("reserved1"), ULInt32("reserved2"),
                       ULInt32("reserved3"), ULInt32("reserved4"))

cprotect_xattr = Struct("cprotect_xattr", ULInt16("xattr_major_version"),
                        ULInt16("xattr_minor_version"), ULInt32("flags"),
                        ULInt32("persistent_class"), ULInt32("key_size"),
                        String("persistent_key", length=0x28))

cprotect4_xattr = Struct(
    "cprotect_xattr", ULInt16("xattr_major_version"),
    ULInt16("xattr_minor_version"), ULInt32("flags"),
    ULInt32("persistent_class"), ULInt32("key_size"), Padding(20),
    String("persistent_key", length=lambda ctx: ctx["key_size"]))
Пример #11
0
    >>> sng = SONG.parse(raw_input)
    >>> build_output = SONG.build(sng)
    >>> build_output == raw_input
    True
"""

from construct import Struct, If, Array, PrefixedArray, Padding, \
    SLInt8, ULInt16, SLInt16, ULInt32, SLInt32, LFloat32, LFloat64, String


def array(struct):
    """Standard prefixed arrays."""
    return PrefixedArray(struct, ULInt32('count'))


BEAT = Struct('ebeats', LFloat32('time'), ULInt16('measure'), ULInt16('beat'),
              ULInt32('phraseIteration'), ULInt32('mask'))

PHRASE = Struct('phrases', SLInt8('solo'), SLInt8('disparity'),
                SLInt8('ignore'), Padding(1), ULInt32('maxDifficulty'),
                ULInt32('phraseIterationLinks'),
                String('name', 32, padchar='\x00'))

CHORD_TEMPLATE = Struct('chordTemplates', ULInt32('mask'), SLInt8('fret0'),
                        SLInt8('fret1'), SLInt8('fret2'), SLInt8('fret3'),
                        SLInt8('fret4'), SLInt8('fret5'), SLInt8('finger0'),
                        SLInt8('finger1'), SLInt8('finger2'),
                        SLInt8('finger3'), SLInt8('finger4'),
                        SLInt8('finger5'), Array(6, SLInt32('notes')),
                        String('chordName', 32, padchar='\x00'))
Пример #12
0
"""
TPS File Page
"""

from warnings import warn

from construct import Array, Byte, Struct, ULInt16, ULInt32

from .utils import check_value

# Page header
PAGE_HEADER_STRUCT = Struct(
    'page',
    ULInt32('offset'),
    # size - total size with header
    ULInt16('size'),
    ULInt16('uncompressed_size'),
    # ??? self.uncompressed_unabridged_size strange value
    ULInt16('uncompressed_unabridged_size'),
    ULInt16('record_count'),
    Byte('hierarchy_level'),
)


class TpsPage:
    def __init__(self, tps, ref, parent_ref, check=False):
        self.tps = tps
        self.__ref = ref
        self.parent_ref = parent_ref
        self.check = check
        self.__page_child_ref = []
Пример #13
0
                          Bytes('data', lambda ctx: ctx['data_size'] - 9))

METADATA_RECORD_DATA = Struct('field_metadata', Byte('metadata_type'),
                              ULInt32('metadata_record_count'),
                              ULInt32('metadata_record_last_access'))

TABLE_DEFINITION_RECORD_DATA = Struct(
    'table_definition',
    Bytes('table_definition_bytes', lambda ctx: ctx['data_size'] - 5))

INDEX_RECORD_DATA = Struct('field_index',
                           Bytes('data', lambda ctx: ctx['data_size'] - 10),
                           ULInt32('record_number'))

RECORD_STRUCT = Struct(
    'record', ULInt16('data_size'), Peek(Byte('first_byte')),
    Embed(
        IfThenElse(
            'record_type', lambda ctx: ctx['first_byte'] == 0xFE,
            Embed(
                Struct(
                    'record',
                    RECORD_TYPE,
                    String('table_name',
                           lambda ctx: ctx['data_size'] - 5,
                           encoding=record_encoding),
                    UBInt32('table_number'),
                )),
            Embed(
                Struct(
                    'record', UBInt32('table_number'), RECORD_TYPE,
Пример #14
0
    FLOAT=0x8,
    DOUBLE=0x9,
    DECIMAL=0x0A,
    STRING=0x12,
    CSTRING=0x13,
    PSTRING=0x14,
    # compound data structure
    GROUP=0x16,
    # LIKE (inherited data type)
)

TABLE_DEFINITION_FIELD_STRUCT = Struct(
    'record_table_definition_field',
    FIELD_TYPE_STRUCT,
    # data offset in record
    ULInt16('offset'),
    CString('name'),
    ULInt16('array_element_count'),
    ULInt16('size'),
    # 1, if fields overlap (OVER attribute), or 0
    ULInt16('overlaps'),
    # record number
    ULInt16('number'),
    If(lambda x: x['type'] == 'STRING', ULInt16('array_element_size')),
    If(lambda x: x['type'] == 'STRING', ULInt16('template')),
    If(lambda x: x['type'] == 'CSTRING', ULInt16('array_element_size')),
    If(lambda x: x['type'] == 'CSTRING', ULInt16('template')),
    If(lambda x: x['type'] == 'PSTRING', ULInt16('array_element_size')),
    If(lambda x: x['type'] == 'PSTRING', ULInt16('template')),
    If(lambda x: x['type'] == 'PICTURE', ULInt16('array_element_size')),
    If(lambda x: x['type'] == 'PICTURE', ULInt16('template')),
Пример #15
0
    def __init__(self,
                 filename,
                 encoding=None,
                 password=None,
                 cached=True,
                 check=False,
                 current_tablename=None,
                 date_fieldname=None,
                 time_fieldname=None,
                 decryptor_class=TpsDecryptor):
        self.filename = filename
        self.encoding = encoding
        self.password = password
        self.cached = cached
        self.check = check
        self.current_table_number = None
        # Name part before .tps
        self.name = os.path.basename(filename)
        self.name = text_type(os.path.splitext(self.name)[0]).lower()
        if date_fieldname is not None:
            self.date_fieldname = date_fieldname
        else:
            self.date_fieldname = []
        if time_fieldname is not None:
            self.time_fieldname = time_fieldname
        else:
            self.time_fieldname = []
        self.cache_pages = {}

        if not os.path.isfile(self.filename):
            raise FileNotFoundError(self.filename)

        self.file_size = os.path.getsize(self.filename)

        # Check file size
        if check:
            if self.file_size & 0x3F != 0:
                # TODO check translate
                warn('File size is not a multiple of 64 bytes.',
                     RuntimeWarning)

        with open(self.filename, mode='r+b') as tpsfile:
            self.tps_file = mmap.mmap(tpsfile.fileno(), 0)

            self.decryptor = decryptor_class(self.tps_file, self.password)

            try:
                # TPS file header
                header = Struct(
                    'header',
                    ULInt32('offset'),
                    ULInt16('size'),
                    ULInt32('file_size'),
                    ULInt32('allocated_file_size'),
                    Const(Bytes('top_speed_mark', 6), b'tOpS\x00\x00'),
                    UBInt32('last_issued_row'),
                    ULInt32('change_count'),
                    ULInt32('page_root_ref'),
                    Array(lambda ctx: (ctx['size'] - 0x20) / 2 / 4,
                          ULInt32('block_start_ref')),
                    Array(lambda ctx: (ctx['size'] - 0x20) / 2 / 4,
                          ULInt32('block_end_ref')),
                )

                self.header = header.parse(self.read(0x200))
                self.pages = TpsPagesList(self,
                                          self.header.page_root_ref,
                                          check=self.check)
                self.tables = TpsTablesList(self,
                                            encoding=self.encoding,
                                            check=self.check)
                self.set_current_table(current_tablename)
            except adapters.ConstError:
                print('Bad cryptographic keys.')
Пример #16
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
Пример #17
0
from six import text_type
from construct import adapters, Array, Byte, Bytes, Const, LFloat32, LFloat64, Struct, SLInt16, SLInt32, UBInt32, \
    ULInt8, ULInt16, ULInt32

from .tpscrypt import TpsDecryptor
from .tpstable import TpsTablesList
from .tpspage import TpsPagesList
from .tpsrecord import TpsRecordsList
from .utils import check_value

# Date structure
DATE_STRUCT = Struct(
    'date_struct',
    Byte('day'),
    Byte('month'),
    ULInt16('year'),
)

# Time structure
TIME_STRUCT = Struct('time_struct', Byte('centisecond'), Byte('second'),
                     Byte('minute'), Byte('hour'))


class TPS:
    """
    TPS file
    """
    def __init__(self,
                 filename,
                 encoding=None,
                 password=None,
Пример #18
0
        try:
            forms = self.pokemon_forms[ context['national_id'] ]
        except KeyError:
            return None

        return forms.index(obj) << 3



# 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'),
Пример #19
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)
Пример #20
0
from construct import (ULInt8, ULInt16, ULInt32, ULInt64,
                       Embed, Struct, Enum, Array,
                       PascalString, Switch, Container)

ENCODING = 'utf-8'
BASE_SIZE = 26

# pylint: disable=bad-continuation,invalid-name

timestamp = Embed(Struct('time',
    ULInt32('secs'),
    ULInt32('usecs')
))


snaptype = Enum(ULInt16('type'),
    Base=0,
    Header=1,
    WireChunk=2,
    SampleFormat=3,
    ServerSettings=4,
    Time=5,
    Request=6,
    Ack=7,
    Command=8,
    Hello=9,
    Map=10,
    String=11
)

Пример #21
0
def GUID(name):
    return Struct(name,
        ULInt32("Data1"),
        ULInt16("Data2"),
        ULInt16("Data3"),
        String("Data4", 8))
Пример #22
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"),
Пример #23
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(
    "health_format",
Пример #24
0
 def add_definition(self, definition):
     portion_number = ULInt16('portion_number').parse(definition[:2])
     self.definition_bytes[portion_number] = definition[2:]
Пример #25
0
from keystore.keybag import Keybag
from structs import HFSPlusVolumeHeader, kHFSPlusFileRecord, getString
from construct import Struct, ULInt16,ULInt32, String
from Crypto.Cipher import AES
from construct.macros import ULInt64, Padding
from structs import kHFSRootParentID
import hashlib

"""
iOS >= 4 raw images
http://opensource.apple.com/source/xnu/xnu-1699.22.73/bsd/hfs/hfs_cprotect.c
http://opensource.apple.com/source/xnu/xnu-1699.22.73/bsd/sys/cprotect.h
"""

cp_root_xattr = Struct("cp_root_xattr",
    ULInt16("major_version"),
    ULInt16("minor_version"),
    ULInt64("flags"),
    ULInt32("reserved1"),
    ULInt32("reserved2"),
    ULInt32("reserved3"),
    ULInt32("reserved4")
)

cprotect_xattr = Struct("cprotect_xattr",
    ULInt16("xattr_major_version"),
    ULInt16("xattr_minor_version"),
    ULInt32("flags"),
    ULInt32("persistent_class"),
    ULInt32("key_size"),
    String("persistent_key", length=0x28)