def compute_offset(buffer, start_offset=1, arch=None): ''' Compute the offset of your buffer given the result of make_pattern Args: buffer (string): The result of make_pattern start_offset (int): The starting offset arch (Architecture): The architecture of your system Returns: False if the offset is not found Otherwise, returns the couple (offset, padding) ''' arch = arch or local_arch() buffer = buffer.replace('(nil)', '0x0') memory = buffer.split('|') if memory[0] == 'ABCDEFGH': memory = memory[1:] memory = map(lambda x: struct.pack(arch.address_fmt, int(x, 16)), memory) memory = b''.join(memory) for i in range(len(buffer)): if memory[i:i + 10] == b'ABCDEFGH|%': if i % arch.bytes == 0: return (start_offset + i // arch.bytes, 0) else: return (start_offset + i // arch.bytes + 1, arch.bytes - i % arch.bytes) return False # not found
def __init__(self, offset, padding=0, arch=None, forbidden_bytes=b'', padding_byte=None): ''' Args: offset (int): The offset of your buffer padding (int): The needed padding arch (Architecture): The architecture forbidden_bytes (bytes): Bytes to avoid padding byte (bytes): The byte used for padding ''' self.offset = offset self.padding = padding self.arch = arch or local_arch() self.forbidden_bytes = forbidden_bytes if padding_byte and padding_byte not in self.forbidden_bytes: self.padding_byte = padding_byte elif b'\x00' not in self.forbidden_bytes: self.padding_byte = b'\x00' else: for c in range(0xff, -1, -1): byte = bytes([c]) if byte not in self.forbidden_bytes: self.padding_byte = byte break
def main(args=None): desc = 'Compute the offset of your buffer, given the result of pattern_create' parser = argparse.ArgumentParser(description=desc) parser.add_argument('buffer', metavar='BUFFER', nargs='?', help='The result of pattern_create') parser.add_argument('-s', '--start-offset', metavar='OFFSET', type=int, default=1, help='The starting offset') parser.add_argument('-a', '--arch', metavar='ARCH', help='The architecture ' '(x86_32, x86_64, arm, sparc, ...)') args = parser.parse_args(args) if not args.buffer: print('Enter the result of the format string on a pattern ' 'given by pattern_create:') args.buffer = sys.stdin.readline() if args.arch: if args.arch not in architectures.archs: print('error: unknown architecture: %s' % args.arch) exit(1) arch = architectures.archs[args.arch] else: arch = architectures.local_arch() ret = pattern.compute_offset(args.buffer, args.start_offset, arch) if ret: offset, padding = ret if padding == 0: print('Found buffer at offset %d' % offset) else: print('Found buffer at offset %d ' 'with a padding of %d bytes' % (offset, padding)) else: print('Buffer not found, look forward (or check the architecture).')