コード例 #1
0
ファイル: hex.py プロジェクト: McLutzifer/Python
def main(args):
    if not args.data:
        print(enhex(getattr(sys.stdin, 'buffer', sys.stdin).read()))
    else:
        data = ' '.join(args.data)
        if not hasattr(data, 'decode'):
            data = data.encode('utf-8', 'surrogateescape')
        print(enhex(data))
コード例 #2
0
ファイル: plt.py プロジェクト: lovebair2022/pwntools
def emulate_plt_instructions(elf, got, address, data, targets):
    """Emulates instructions in ``data``

    Arguments:
        elf(ELF): ELF that we are emulating
        got(int): Address of the GOT, as expected in e.g. EBX
        address(int): Address of ``data`` for emulation
        data(str): Array of bytes to emulate
        targets(list): List of target addresses

    Returns:
        :class:`dict`: Map of ``{address: target}`` for each address which
            reaches one of the selected targets.
    """
    rv = {}

    # Unicorn doesn't support big-endian for everything yet.
    if elf.endian == 'big' and elf.arch == 'mips':
        data = packing.unpack_many(data, bits=32, endian='little')
        data = packing.flat(data, bits=32, endian='big')

    # Brute force addresses, assume that PLT entry points are at 4-byte aligned
    # Do not emulate more than a handful of instructions.
    for i, pc in enumerate(range(address, address + len(data), 4)):
        if log.isEnabledFor(logging.DEBUG):
            log.debug('%s %#x', fiddling.enhex(data[i * 4:(i + 1) * 4]), pc)
            log.debug(elf.disasm(pc, 4))
        target = emulate_plt_instructions_inner(elf, got, pc, data[i * 4:],
                                                targets)

        if target in targets:
            log.debug("%#x -> %#x", pc, target)
            rv[pc] = target

    return rv
コード例 #3
0
ファイル: plt.py プロジェクト: cxh852456/pwntools
def emulate_plt_instructions(elf, got, address, data, targets):
    """Emulates instructions in ``data``

    Arguments:
        elf(ELF): ELF that we are emulating
        got(int): Address of the GOT, as expected in e.g. EBX
        address(int): Address of ``data`` for emulation
        data(str): Array of bytes to emulate
        targets(list): List of target addresses

    Returns:
        :class:`dict`: Map of ``{address: target}`` for each address which
            reaches one of the selected targets.
    """
    rv = {}

    # Unicorn doesn't support big-endian for everything yet.
    if elf.endian == 'big' and elf.arch == 'mips':
        data = packing.unpack_many(data, bits=32, endian='little')
        data = packing.flat(data, bits=32, endian='big')

    # Brute force addresses, assume that PLT entry points are at 4-byte aligned
    # Do not emulate more than a handful of instructions.
    for i, pc in enumerate(range(address, address + len(data), 4)):
        if log.isEnabledFor(logging.DEBUG):
            log.debug('%s %#x', fiddling.enhex(data[i*4:(i+1) * 4]), pc)
            log.debug(elf.disasm(pc, 4))
        target = emulate_plt_instructions_inner(elf, got, pc, data[i*4:], targets)

        if target in targets:
            log.debug("%#x -> %#x", pc, target)
            rv[pc] = target

    return rv
コード例 #4
0
ファイル: libcdb.py プロジェクト: peace-maker/pwntools
def unstrip_libc(filename):
    """
    Given a path to a libc binary, attempt to download matching debug info
    and add them back to the given binary.

    This modifies the given file.

    Arguments:
        filename(str):
            Path to the libc binary to unstrip.

    Returns:
        :const:`True` if binary was unstripped, :const:`False` otherwise.

    Examples:
        >>> filename = search_by_build_id('2d1c5e0b85cb06ff47fa6fa088ec22cb6e06074e', unstrip=False)
        >>> libc = ELF(filename)
        >>> hex(libc.symbols.read)
        '0xe56c0'
        >>> 'main_arena' in libc.symbols
        False
        >>> unstrip_libc(filename)
        True
        >>> libc = ELF(filename)
        >>> hex(libc.symbols.main_arena)
        '0x1d57a0'
        >>> unstrip_libc(which('python'))
        False
        >>> filename = search_by_build_id('06a8004be6e10c4aeabbe0db74423ace392a2d6b', unstrip=True)
        >>> 'main_arena' in ELF(filename).symbols
        True
    """
    if not which('eu-unstrip'):
        log.warn_once('Couldn\'t find "eu-unstrip" in PATH. Install elfutils first.')
        return False

    libc = ELF(filename, checksec=False)
    if not libc.buildid:
        log.warn_once('Given libc does not have a buildid. Cannot look for debuginfo to unstrip.')
        return False

    for server_url in DEBUGINFOD_SERVERS:
        libc_dbg = _search_debuginfo_by_hash(server_url, enhex(libc.buildid))
        if libc_dbg:
            break
    else:
        log.warn_once('Couldn\'t find debug info for libc with build_id %s on any debuginfod server.', enhex(libc.buildid))
        return False

    # Add debug info to given libc binary inplace.
    p = process(['eu-unstrip', '-o', filename, filename, libc_dbg])
    output = p.recvall()
    p.close()

    if output:
        log.error('Failed to unstrip libc binary: %s', output)
        return False

    return True
コード例 #5
0
    def _lookup_build_id(self, lib = None):

        libbase = self.libbase

        if lib is not None:
            libbase = self.lookup(symb = None, lib = lib)

        if not libbase:
            self.status("Couldn't find libc base")
            return None

        for offset in libcdb.get_build_id_offsets():
            address = libbase + offset
            if self.leak.compare(address + 0xC, "GNU\x00"):
                return enhex(''.join(self.leak.raw(address + 0x10, 20)))
            else:
                self.status("Magic did not match")
                pass
コード例 #6
0
ファイル: dynelf.py プロジェクト: H1d3r/pwntools
    def _lookup_build_id(self, lib=None):

        libbase = self.libbase
        if not self.link_map:
            self.status("No linkmap found")
            return None

        if lib is not None:
            libbase = self.lookup(symb=None, lib=lib)

        if not libbase:
            self.status("Couldn't find libc base")
            return None

        for offset in libcdb.get_build_id_offsets():
            address = libbase + offset
            if self.leak.compare(address + 0xC, b"GNU\x00"):
                return enhex(b''.join(self.leak.raw(address + 0x10, 20)))
            else:
                self.status("Build ID not found at offset %#x" % offset)
                pass
コード例 #7
0
ファイル: corefile.py プロジェクト: x0xr00t/pwntools
    def _parse_stack(self):
        # Get a copy of the stack mapping
        stack = self.stack

        if not stack:
            return

        # If the stack does not end with zeroes, something is very wrong.
        if not stack.data.endswith('\x00' * 8):
            log.warn_once(
                "End of the stack is corrupted, skipping stack parsing (got: %s)",
                enhex(self.data[-8:]))
            return

        # AT_EXECFN is the start of the filename, e.g. '/bin/sh'
        # Immediately preceding is a NULL-terminated environment variable string.
        # We want to find the beginning of it
        if not self.at_execfn:
            address = stack.stop
            address -= 2 * self.bytes
            address -= 1
            address = stack.rfind('\x00', None, address)
            address += 1
            self.at_execfn = address

        address = self.at_execfn - 1

        # Sanity check!
        try:
            assert stack[address] == '\x00'
        except AssertionError:
            # Something weird is happening.  Just don't touch it.
            log.debug("Something is weird")
            return
        except ValueError:
            # If the stack is not actually present in the coredump, we can't
            # read from the stack.  This will fail as:
            # ValueError: 'seek out of range'
            log.debug("ValueError")
            return

        # address is currently set to the NULL terminator of the last
        # environment variable.
        address = stack.rfind('\x00', None, address)

        # We've found the beginning of the last environment variable.
        # We should be able to search up the stack for the envp[] array to
        # find a pointer to this address, followed by a NULL.
        last_env_addr = address + 1
        p_last_env_addr = stack.find(pack(last_env_addr), None, last_env_addr)
        if p_last_env_addr < 0:
            # Something weird is happening.  Just don't touch it.
            log.warn_once("Found bad environment at %#x", last_env_addr)
            return

        # Sanity check that we did correctly find the envp NULL terminator.
        envp_nullterm = p_last_env_addr + context.bytes
        assert self.unpack(envp_nullterm) == 0

        # We've successfully located the end of the envp[] array.
        #
        # It comes immediately after the argv[] array, which itself
        # is NULL-terminated.
        #
        # Now let's find the end of argv
        p_end_of_argv = stack.rfind(pack(0), None, p_last_env_addr)

        self.envp_address = p_end_of_argv + self.bytes

        # Now we can fill in the environment
        env_pointer_data = stack[self.envp_address:p_last_env_addr +
                                 self.bytes]
        for pointer in unpack_many(env_pointer_data):

            # If the stack is corrupted, the pointer will be outside of
            # the stack.
            if pointer not in stack:
                continue

            try:
                name_value = self.string(pointer)
            except Exception:
                continue

            name, value = name_value.split('=', 1)

            # "end" points at the byte after the null terminator
            end = pointer + len(name_value) + 1

            # Do not mark things as environment variables if they point
            # outside of the stack itself, or we had to cross into a different
            # mapping (after the stack) to read it.
            # This may occur when the entire stack is filled with non-NUL bytes,
            # and we NULL-terminate on a read failure in .string().
            if end not in stack:
                continue

            self.env[name] = pointer + len(name) + len('=')

        # May as well grab the arguments off the stack as well.
        # argc comes immediately before argv[0] on the stack, but
        # we don't know what argc is.
        #
        # It is unlikely that argc is a valid stack address.
        address = p_end_of_argv - self.bytes
        while self.unpack(address) in stack:
            address -= self.bytes

        # address now points at argc
        self.argc_address = address
        self.argc = self.unpack(self.argc_address)

        # we can extract all of the arguments as well
        self.argv_address = self.argc_address + self.bytes
        self.argv = unpack_many(stack[self.argv_address:p_end_of_argv])
コード例 #8
0
ファイル: hex.py プロジェクト: arthaud/python3-pwntools
def main():
    args = parser.parse_args()
    if not args.data:
        print(enhex(sys.stdin.read()))
    else:
        print(enhex(' '.join(args.data)))
コード例 #9
0
def main():
    args = parser.parse_args()
    if not args.data:
        print(enhex(sys.stdin.read()))
    else:
        print(enhex(' '.join(args.data)))