@@ -219,11 +219,24 @@ class Ret2dlresolvePayload(object):
219219 elf (ELF): Binary to search
220220 symbol (str): Function to search for
221221 args (list): List of arguments to pass to the function
222+ data_addr (int|None): The address where the payload will
223+ be written to. If not provided, a suitable address will
224+ be chosen automatically (recommended).
225+ resolution_addr (int|None): The address where the location
226+ of the resolved symbol will be written to. If not provided
227+ will be equal to data_addr.
222228
223229 Returns:
224- A ``Ret2dlresolvePayload`` object which can be passed to ``rop.ret2dlresolve``
230+ A ``Ret2dlresolvePayload`` object. It can be passed to ``rop.ret2dlresolve``
231+ for automatic exploitation.
232+
233+ If that is not suitable the object generates useful values (.reloc_index
234+ and .payload) which can be used to aid manual exploitation. In this case
235+ it is recommended to set .resolution_addr to the GOT address of an easily
236+ callable function (do not set it when passing the object to
237+ rop.ret2dlresolve).
225238 """
226- def __init__ (self , elf , symbol , args , data_addr = None ):
239+ def __init__ (self , elf , symbol , args , data_addr = None , resolution_addr = None ):
227240 self .elf = elf
228241 self .elf_load_address_fixup = self .elf .address - self .elf .load_addr
229242 self .strtab = elf .dynamic_value_by_tag ("DT_STRTAB" ) + self .elf_load_address_fixup
@@ -236,6 +249,7 @@ def __init__(self, elf, symbol, args, data_addr=None):
236249 self .unreliable = False
237250
238251 self .data_addr = data_addr if data_addr is not None else self ._get_recommended_address ()
252+ self .resolution_addr = resolution_addr if resolution_addr is not None else self .data_addr
239253
240254 # Will be set when built
241255 self .reloc_index = - 1
@@ -302,11 +316,11 @@ def _build_structures(self):
302316 # ElfRel
303317 rel_addr = self .jmprel + self .reloc_index * ElfRel .size
304318 rel_type = 7
305- rel = ElfRel (r_offset = self .data_addr , r_info = (index << ELF_R_SYM_SHIFT )+ rel_type )
319+ rel = ElfRel (r_offset = self .resolution_addr , r_info = (index << ELF_R_SYM_SHIFT )+ rel_type )
306320
307321 # When a program's PIE is enabled, r_offset should be the relative address, not the absolute address
308322 if self .elf .pie :
309- 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 )
323+ 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 )
310324
311325 self .payload = fit ({
312326 symbol_name_addr - self .data_addr : symbol_name ,
@@ -325,6 +339,7 @@ def _build_structures(self):
325339 log .debug ("Symbol name addr: %s" , hex (symbol_name_addr ))
326340 log .debug ("Version index addr: %s" , hex (ver_addr ))
327341 log .debug ("Data addr: %s" , hex (self .data_addr ))
342+ log .debug ("Resolution addr: %s" , hex (self .resolution_addr ))
328343 if not self .elf .memory [ver_addr ]:
329344 log .warn ("Ret2dlresolve is likely impossible in this ELF "
330345 "(too big gap between text and writable sections).\n "
0 commit comments