@@ -219,11 +219,24 @@ class Ret2dlresolvePayload(object):
219
219
elf (ELF): Binary to search
220
220
symbol (str): Function to search for
221
221
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.
222
228
223
229
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).
225
238
"""
226
- def __init__ (self , elf , symbol , args , data_addr = None ):
239
+ def __init__ (self , elf , symbol , args , data_addr = None , resolution_addr = None ):
227
240
self .elf = elf
228
241
self .elf_load_address_fixup = self .elf .address - self .elf .load_addr
229
242
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):
236
249
self .unreliable = False
237
250
238
251
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
239
253
240
254
# Will be set when built
241
255
self .reloc_index = - 1
@@ -302,11 +316,11 @@ def _build_structures(self):
302
316
# ElfRel
303
317
rel_addr = self .jmprel + self .reloc_index * ElfRel .size
304
318
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 )
306
320
307
321
# When a program's PIE is enabled, r_offset should be the relative address, not the absolute address
308
322
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 )
310
324
311
325
self .payload = fit ({
312
326
symbol_name_addr - self .data_addr : symbol_name ,
@@ -325,6 +339,7 @@ def _build_structures(self):
325
339
log .debug ("Symbol name addr: %s" , hex (symbol_name_addr ))
326
340
log .debug ("Version index addr: %s" , hex (ver_addr ))
327
341
log .debug ("Data addr: %s" , hex (self .data_addr ))
342
+ log .debug ("Resolution addr: %s" , hex (self .resolution_addr ))
328
343
if not self .elf .memory [ver_addr ]:
329
344
log .warn ("Ret2dlresolve is likely impossible in this ELF "
330
345
"(too big gap between text and writable sections).\n "
0 commit comments