Beispiel #1
0
 def __str__(self):
     return '\n' \
            '\tChunk: {0}\n' \
            '\tOffset: {1:#x} ({1})\n' \
            '\tPatch: {2}\n' \
            '\tOffset: {3:#x} ({3})\n' \
            .format(util.bytes2hexstr(self.chunk), self.chunkoffset,
                    util.bytes2hexstr(self.patch), self.patchoffset)
Beispiel #2
0
 def __str__(self):
     return '\n' \
            '\tChunk: {0}\n' \
            '\tOffset: {1:#x} ({1})\n' \
            '\tPatch: {2}\n' \
            '\tOffset: {3:#x} ({3})\n' \
            .format(util.bytes2hexstr(self.chunk), self.chunkoffset,
                    util.bytes2hexstr(self.patch), self.patchoffset)
def patch(device, address, chunks):
    '''
    Writes back to the device at address, using the patches in the signature
    chunks
    '''
    success = True
    backup = device.read(address, cfg.PAGESIZE)

    for c in chunks:
        if len(cfg.patchfile) > 0:
            patch = cfg.patchfile
        else:
            patch = c['patch']
        if not patch:
            continue

        ioffset = c['internaloffset']
        poffset = c['patchoffset']
        if not poffset: 
            poffset = 0
        realaddress = address + ioffset + poffset

        device.write(realaddress, patch)
        read = device.read(realaddress, len(patch))
        if cfg.verbose:
            term.info('Data read back: ' + util.bytes2hexstr(read)) #TODO: Change to .format()
        if read != patch:
            success = False

        # Only patch once from file
        if len(cfg.patchfile) > 0:
            break

    return success, backup
def patch(device, address, chunks):
    '''
    Writes back to the device at address, using the patches in the signature
    chunks
    '''
    success = True
    backup = device.read(address, cfg.PAGESIZE)

    for c in chunks:
        if len(cfg.patchfile) > 0:
            patch = cfg.patchfile
        else:
            patch = c['patch']
        if not patch:
            continue

        ioffset = c['internaloffset']
        poffset = c['patchoffset']
        if not poffset:
            poffset = 0
        realaddress = address + ioffset + poffset

        device.write(realaddress, patch)
        read = device.read(realaddress, len(patch))
        if cfg.verbose:
            term.info('Data read back: ' +
                      util.bytes2hexstr(read))  #TODO: Change to .format()
        if read != patch:
            success = False

        # Only patch once from file
        if len(cfg.patchfile) > 0:
            break

    return success, backup
Beispiel #5
0
def dump(start, end, path):
    # Make sure that the right mode is set
    settings.memdump = True
    
    # Initialize and lower DMA shield
    if not settings.filemode:
        fw = FireWire()
        starttime = time.time()
        device_index = fw.select_device()
        # Print selection
        msg('*', 'Selected device: {0}'.format(fw.vendors[device_index]))

    # Lower DMA shield or use a file as input
    device = None
    if settings.filemode:
        device = MemoryFile(settings.filename, settings.PAGESIZE)
    else:
        elapsed = int(time.time() - starttime)
        device = fw.getdevice(device_index, elapsed)
        
    requestsize = settings.max_request_size
    size = end - start

    #filename =  'memdump_{0}-{1}.bin'.format(hex(start), hex(end))
    #path added for Pac4Mac
    filename =  path
    file = open(filename, 'wb')
    
    msg('*', 'Dumping from {0:#x} to {1:#x}, a total of {2} MiB'.format(start, end, size/settings.MiB))
    
    try:
        for i in range(start, end, requestsize):
            # Avoid accessing upper memory area if we are using FireWire
            if needtoavoid(i):
                data = b'\x00' * requestsize
            else: 
                data = device.read(i, requestsize)
            file.write(data)
            # Print status
            dumped = (i - start) // settings.MiB
            sys.stdout.write('[*] Dumping memory, {0:>4d} MiB so far'.format(dumped))
            if settings.verbose:
                sys.stdout.write('. Sample data read: {0}'.format(bytes2hexstr(data)[0:24]))
            sys.stdout.write('\r')
            sys.stdout.flush()
        file.close()
        print() # Filler
        msg('*', 'Dumped memory to file {0}'.format(filename))
        device.close()
    except KeyboardInterrupt:
        file.close()
        print()
        msg('*', 'Dumped memory to file {0}'.format(filename))
        raise KeyboardInterrupt
Beispiel #6
0
def patch(device, address, chunks):
    '''
    Writes back to the device at address, using the patches in the signature
    chunks
    '''
    success = True
    for c in chunks:
        patch = c['patch']
        if not patch:
            continue
        ioffset = c['internaloffset']
        poffset = c['patchoffset']
        if not poffset:
            poffset = 0
        realaddress = address + ioffset + poffset
        if patch:
            device.write(realaddress, patch)
            read = device.read(realaddress, len(patch))
            if settings.verbose:
                msg('*', 'Data written: 0x' + bytes2hexstr(patch))
                msg('*', 'Data read:    0x' + bytes2hexstr(read))
            if read != patch:
                success = False
    return success
Beispiel #7
0
def patch(device, address, chunks):
    '''
    Writes back to the device at address, using the patches in the signature
    chunks
    '''
    success = True
    for c in chunks:
        patch = c['patch']
        if not patch:
            continue
        ioffset = c['internaloffset']
        poffset = c['patchoffset']
        if not poffset: 
            poffset = 0
        realaddress = address + ioffset + poffset
        if patch:
            device.write(realaddress, patch)
            read = device.read(realaddress, len(patch))
            if settings.verbose:
                msg('*', 'Data written: 0x' + bytes2hexstr(patch))
                msg('*', 'Data read:    0x' + bytes2hexstr(read))
            if  read != patch:
                success = False
    return success
Beispiel #8
0
def searchanddestroy(device, target, memsize):
    '''
    Main search loop
    '''
    pageaddress = settings.startaddress
    signatures = target['signatures']

    # Add signature lengths in bytes to the dictionary, and replace integer
    # representations of the signatures and patches with bytes
    for signature in signatures:
        signature['length'] = siglen(signature['chunks'])
        offsets = signature['offsets'] # Offsets within pages
        for chunk in signature['chunks']:
            chunk['chunk'] = int2binhex(chunk['chunk'])
            try:
                chunk['patch'] = int2binhex(chunk['patch'])
            except KeyError:
                chunk['patch'] = None

    try:
        # Build a batch of read requests of the form: [(addr1, len1), ...] and
        # a corresponding match vector: [(chunks1, patchoffset1), ...]
        j = 0
        count = 0
        cand = b'\x00'
        r = []
        p = []
        while pageaddress < memsize:
            sig_len = len(signatures)
            
            for i in range(sig_len): # Iterate over signatures
                offsets = signatures[i]['offsets'] # Offsets within pages
                if isinstance(offsets, int):
                    offsets = [offsets] # Create a list if single offset
                chunks = signatures[i]['chunks'] # The chunks that is the sig
                length = signatures[i]['length'] # Sig length in bytes
                offset_len = len(offsets)
                
                for n in range(offset_len): # Iterate over offsets
                    address = pageaddress + offsets[n] + settings.PAGESIZE * j
                    r.append((address, length))
                    p.append(chunks)
                    count += 1
                    # If we have built a full vector, read from memory and
                    # compare to the corresponding signatures
                    if count == settings.vectorsize:
                        # Read data from device
                        m = 0
                        for caddr, cand  in device.readv(r):
                            if match(cand, p[m]):
                                print()
                                return (caddr, p[m])
                            m += 1                    
                        # Jump to next pages (we're finished with these)
                        mask = ~(settings.PAGESIZE - 0x01)
                        pageaddress = address & mask
                        if sig_len == i and offset_len == n:
                            pageaddress = pageaddress + settings.PAGESIZE
                            
                        # Zero out counters and vectors
                        j = 0
                        count = 0
                        r = []
                        p = []
                        
                        # Print status
                        mibaddr = pageaddress // settings.MiB
                        sys.stdout.write('[*] Searching, {0:>4d} MiB so far'.format(mibaddr))
                        if settings.verbose:
                            sys.stdout.write('. Sample data read: {0}'.format(bytes2hexstr(cand)[0:24]))
                        sys.stdout.write('\r')
                        sys.stdout.flush()
                         
            j += 1 # Increase read request count
            
    except IOError:
        print()
        fail('I/O Error, make sure FireWire interfaces are properly connected')
    except KeyboardInterrupt:
        print()
        fail('Aborted')
        raise KeyboardInterrupt
    
    # If we get here, we haven't found anything :-/
    print()    
    return (None, None)
Beispiel #9
0
 def test_bytes2hexstr(self):
     test1 = b'ABCD'
     test1_res = '0x41424344'
     self.assertEqual(bytes2hexstr(test1), test1_res)
     test2 = '41424344'
     self.assertRaises(BytesWarning, bytes2hexstr, test2)
Beispiel #10
0
 def test_bytes2hexstr(self):
     test1 = b'ABCD'
     test1_res = '0x41424344'
     self.assertEqual(bytes2hexstr(test1), test1_res)
     test2 = '41424344'
     self.assertRaises(BytesWarning, bytes2hexstr, test2)
Beispiel #11
0
def searchanddestroy(device, target, memsize):
    '''
    Main search loop
    '''
    pageaddress = settings.startaddress
    signatures = target['signatures']

    # Add signature lengths in bytes to the dictionary, and replace integer
    # representations of the signatures and patches with bytes
    for signature in signatures:
        signature['length'] = siglen(signature['chunks'])
        offsets = signature['offsets']  # Offsets within pages
        for chunk in signature['chunks']:
            chunk['chunk'] = int2binhex(chunk['chunk'])
            try:
                chunk['patch'] = int2binhex(chunk['patch'])
            except KeyError:
                chunk['patch'] = None

    try:
        # Build a batch of read requests of the form: [(addr1, len1), ...] and
        # a corresponding match vector: [(chunks1, patchoffset1), ...]
        j = 0
        count = 0
        cand = b'\x00'
        r = []
        p = []
        while pageaddress < memsize:
            sig_len = len(signatures)

            for i in range(sig_len):  # Iterate over signatures
                offsets = signatures[i]['offsets']  # Offsets within pages
                if isinstance(offsets, int):
                    offsets = [offsets]  # Create a list if single offset
                chunks = signatures[i]['chunks']  # The chunks that is the sig
                length = signatures[i]['length']  # Sig length in bytes
                offset_len = len(offsets)

                for n in range(offset_len):  # Iterate over offsets
                    address = pageaddress + offsets[n] + settings.PAGESIZE * j
                    r.append((address, length))
                    p.append(chunks)
                    count += 1
                    # If we have built a full vector, read from memory and
                    # compare to the corresponding signatures
                    if count == settings.vectorsize:
                        # Read data from device
                        m = 0
                        for caddr, cand in device.readv(r):
                            if match(cand, p[m]):
                                print()
                                return (caddr, p[m])
                            m += 1
                        # Jump to next pages (we're finished with these)
                        mask = ~(settings.PAGESIZE - 0x01)
                        pageaddress = address & mask
                        if sig_len == i and offset_len == n:
                            pageaddress = pageaddress + settings.PAGESIZE

                        # Zero out counters and vectors
                        j = 0
                        count = 0
                        r = []
                        p = []

                        # Print status
                        mibaddr = pageaddress // settings.MiB
                        sys.stdout.write(
                            '[*] Searching, {0:>4d} MiB so far'.format(
                                mibaddr))
                        if settings.verbose:
                            sys.stdout.write('. Sample data read: {0}'.format(
                                bytes2hexstr(cand)[0:24]))
                        sys.stdout.write('\r')
                        sys.stdout.flush()

            j += 1  # Increase read request count

    except IOError:
        print()
        fail('I/O Error, make sure FireWire interfaces are properly connected')
    except KeyboardInterrupt:
        print()
        fail('Aborted')
        raise KeyboardInterrupt

    # If we get here, we haven't found anything :-/
    print()
    return (None, None)