From a0eeb30e0bfe6fadb73c8da6509851397a3fc5a7 Mon Sep 17 00:00:00 2001 From: Saullo Carvalho Castelo Branco Date: Thu, 11 Jun 2020 17:10:06 -0300 Subject: [PATCH] Add `executable=` argument to ELF.search (#1576) * Add `executable=` argument like `writable=` to ELF.search * Add doctest using ELF.search with `executable = True` * Fix `__next__()` issue. --- pwnlib/elf/elf.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 94c7682e1..51be856d7 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1115,8 +1115,8 @@ def libc_start_main_return(self): return_from_main = int(return_from_main[ : return_from_main.index(':') ], 16) return return_from_main - def search(self, needle, writable = False): - """search(needle, writable = False) -> generator + def search(self, needle, writable = False, executable = False): + """search(needle, writable = False, executable = False) -> generator Search the ELF's virtual address space for the specified string. @@ -1129,6 +1129,7 @@ def search(self, needle, writable = False): Arguments: needle(str): String to search for. writable(bool): Search only writable sections. + executable(bool): Search only executable sections. Yields: An iterator for each virtual address that matches. @@ -1146,11 +1147,20 @@ def search(self, needle, writable = False): >>> len(list(bash.search(b'GNU bash'))) > 0 True + + It is also possible to search for instructions in executable sections. + + >>> binary = ELF.from_assembly('nop; mov eax, 0; jmp esp; ret') + >>> jmp_addr = next(binary.search(asm('jmp esp'), executable = True)) + >>> binary.read(jmp_addr, 2) == asm('jmp esp') + True """ load_address_fixup = (self.address - self.load_addr) if writable: segments = self.writable_segments + elif executable: + segments = self.executable_segments else: segments = self.segments