#!python
"""
This enables using radare2 in combination with pwntools

Automatic installation: via pip

Manual installation instructions:
1. Download and save as "pwntools-gdb" somewhere in your PATH - e.g. from your working directory:
    `PATH=$PWD:$PATH`

2. Run `chmod u+x pwntools-gdb`
3. In your r2script over in pwntools, start lines with "#" that you want to get executed by radare2. For instance, to set a breakpoint automatically, you would use r2script="#r2.cmd('db sym.main')"

Pip Dependencies: pwntools r2pipe

Debug with `context.log_level = 'DEBUG'` (via pwntools python script)

By ps1337 / @CaptnBanana
Based on https://gist.github.com/bannsec/43cf0f1b05ec37eb7e92a2922967bc46
"""

import argparse
import re
import subprocess
import shlex
import os

r2_python_template = """
#!/usr/bin/env python2
import os, r2pipe
r2 = r2pipe.open()

def load_modules():
    modules = r2.cmdj("dmmj")
    for module in modules:
        if '{mod_name:s}' == os.path.basename(module['file']):
            command = "oba {{addr:d}} {{file_name:s}}".format(file_name=module['file'], addr=module['addr'])
            r2.cmd(command)

load_modules()
r2.cmd('ib') # Reload the buffer info

{user_commands:s}
"""


def spawn():
    parser = argparse.ArgumentParser()
    parser.add_argument("-x", nargs=1)
    parser.add_argument("-q", nargs=1)
    args = parser.parse_args()

    gdb_script_path = args.x[0]
    binary_path = os.path.abspath(args.q[0])

    with open(gdb_script_path, "r") as f:
        gdb_script_path = f.read()

    ip, port = re.findall("target remote (.+):([0-9]+)", gdb_script_path)[0]

    # Find the user commands that start with "#"
    user_commands = '\n'.join([
        line[1:] for line in gdb_script_path.split("\n")
        if line.startswith("#")
    ])

    r2_script_file_path = args.x[0] + ".py"
    with open(r2_script_file_path, "w") as f:
        f.write(
            r2_python_template.format(mod_name=os.path.basename(binary_path),
                                      user_commands=user_commands))

    command = [
        "/usr/bin/r2", "-d", "-i", r2_script_file_path, "-e",
        "dbg.exe.path={binary_path}".format(binary_path=binary_path),
        "gdb://{ip:s}:{port:s}".format(ip=ip, port=port)
    ]

    subprocess.call(command)


def main():
    spawn()


if __name__ == '__main__':
    main()
