# Assume a process or remote connection p = process('./pwnme')
# Declare a function that takes a single address, and # leaks at least one byte at that address. defleak(address): data = p.read(address, 4) log.debug("%#x => %s" % (address, (data or'').encode('hex'))) return data
# For the sake of this example, let's say that we # have any of these pointers. One is a pointer into # the target binary, the other two are pointers into libc main = 0xfeedf4ce libc = 0xdeadb000 system = 0xdeadbeef
# With our leaker, and a pointer into our target binary, # we can resolve the address of anything. # # We do not actually need to have a copy of the target # binary for this to work. d = DynELF(leak, main) assert d.lookup(None, 'libc') == libc assert d.lookup('system', 'libc') == system
# However, if we *do* have a copy of the target binary, # we can speed up some of the steps. d = DynELF(leak, main, elf=ELF('./pwnme')) assert d.lookup(None, 'libc') == libc assert d.lookup('system', 'libc') == system
# Alternately, we can resolve symbols inside another library, # given a pointer into it. d = DynELF(leak, libc + 0x1234) assert d.lookup('system') == system