# Assume a process or remote connectionp =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 libcmain =0xfeedf4celibc =0xdeadb000system =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')== libcassert 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')== libcassert 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