Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resolution_addr parameter to Ret2dlresolvePayload #2430

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ The table below shows which release corresponds to each branch, and what date th

## 4.14.0 (`dev`)

- [#2430][2430] Add resolution_addr parameter to Ret2dlresolvePayload
- [#2371][2371] Add functions for retrieving process mappings
- [#2360][2360] Add offline parameter for `search_by_hash` series function
- [#2356][2356] Add local libc database provider for libcdb
Expand All @@ -91,6 +92,7 @@ The table below shows which release corresponds to each branch, and what date th
- [#2382][2382] added optional port, gdb_args and gdbserver_args parameters to gdb.debug()
- [#2435][2435] Speed up gdbserver handshake in gdb.debug()

[2430]: https://github.com/Gallopsled/pwntools/pull/2430
[2371]: https://github.com/Gallopsled/pwntools/pull/2371
[2360]: https://github.com/Gallopsled/pwntools/pull/2360
[2356]: https://github.com/Gallopsled/pwntools/pull/2356
Expand Down
23 changes: 19 additions & 4 deletions pwnlib/rop/ret2dlresolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,24 @@ class Ret2dlresolvePayload(object):
elf (ELF): Binary to search
symbol (str): Function to search for
args (list): List of arguments to pass to the function
data_addr (int|None): The address where the payload will
be written to. If not provided, a suitable address will
be chosen automatically (recommended).
resolution_addr (int|None): The address where the location
of the resolved symbol will be written to. If not provided
will be equal to data_addr.

Returns:
A ``Ret2dlresolvePayload`` object which can be passed to ``rop.ret2dlresolve``
A ``Ret2dlresolvePayload`` object. It can be passed to ``rop.ret2dlresolve``
for automatic exploitation.

If that is not suitable the object generates useful values (.reloc_index
and .payload) which can be used to aid manual exploitation. In this case
it is recommended to set .resolution_addr to the GOT address of an easily
callable function (do not set it when passing the object to
rop.ret2dlresolve).
"""
def __init__(self, elf, symbol, args, data_addr=None):
def __init__(self, elf, symbol, args, data_addr=None, resolution_addr=None):
self.elf = elf
self.elf_load_address_fixup = self.elf.address - self.elf.load_addr
self.strtab = elf.dynamic_value_by_tag("DT_STRTAB") + self.elf_load_address_fixup
Expand All @@ -236,6 +249,7 @@ def __init__(self, elf, symbol, args, data_addr=None):
self.unreliable = False

self.data_addr = data_addr if data_addr is not None else self._get_recommended_address()
self.resolution_addr = resolution_addr if resolution_addr is not None else self.data_addr

# Will be set when built
self.reloc_index = -1
Expand Down Expand Up @@ -302,11 +316,11 @@ def _build_structures(self):
# ElfRel
rel_addr = self.jmprel + self.reloc_index * ElfRel.size
rel_type = 7
rel = ElfRel(r_offset=self.data_addr, r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
rel = ElfRel(r_offset=self.resolution_addr, r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)

# When a program's PIE is enabled, r_offset should be the relative address, not the absolute address
if self.elf.pie:
rel = ElfRel(r_offset=self.data_addr - (self.elf.load_addr + self.elf_load_address_fixup), r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)
rel = ElfRel(r_offset=self.resolution_addr - (self.elf.load_addr + self.elf_load_address_fixup), r_info=(index<<ELF_R_SYM_SHIFT)+rel_type)

self.payload = fit({
symbol_name_addr - self.data_addr: symbol_name,
Expand All @@ -325,6 +339,7 @@ def _build_structures(self):
log.debug("Symbol name addr: %s", hex(symbol_name_addr))
log.debug("Version index addr: %s", hex(ver_addr))
log.debug("Data addr: %s", hex(self.data_addr))
log.debug("Resolution addr: %s", hex(self.resolution_addr))
if not self.elf.memory[ver_addr]:
log.warn("Ret2dlresolve is likely impossible in this ELF "
"(too big gap between text and writable sections).\n"
Expand Down