From 648766b61642ad5882a5ba428336a725ade98401 Mon Sep 17 00:00:00 2001 From: Saullo Carvalho Date: Thu, 11 Jun 2020 07:11:49 -0700 Subject: [PATCH 1/3] Add `executable=` argument like `writable=` to ELF.search --- pwnlib/elf/elf.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 94c7682e1..2e064c2bc 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. @@ -1151,6 +1152,8 @@ def search(self, needle, writable = False): if writable: segments = self.writable_segments + elif executable: + segments = self.executable_segments else: segments = self.segments From 510dfc80e9a2e0ef1f4549150d922d9692f29b74 Mon Sep 17 00:00:00 2001 From: Saullo Carvalho Date: Thu, 11 Jun 2020 08:16:33 -0700 Subject: [PATCH 2/3] Add doctest using ELF.search with `executable = True` --- pwnlib/elf/elf.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index 2e064c2bc..ed9142de8 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1147,6 +1147,13 @@ def search(self, needle, writable = False, executable = 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 = binary.search(asm('jmp esp'), executable = True).__next__() + >>> binary.read(jmp_addr, 2) == asm('jmp esp') + True """ load_address_fixup = (self.address - self.load_addr) From 09605b2629d7a673dfb8feefbabe0b55c2d3b582 Mon Sep 17 00:00:00 2001 From: Saullo Carvalho Date: Thu, 11 Jun 2020 08:37:33 -0700 Subject: [PATCH 3/3] Fix `__next__()` issue. --- pwnlib/elf/elf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwnlib/elf/elf.py b/pwnlib/elf/elf.py index ed9142de8..51be856d7 100644 --- a/pwnlib/elf/elf.py +++ b/pwnlib/elf/elf.py @@ -1151,7 +1151,7 @@ def search(self, needle, writable = False, executable = False): It is also possible to search for instructions in executable sections. >>> binary = ELF.from_assembly('nop; mov eax, 0; jmp esp; ret') - >>> jmp_addr = binary.search(asm('jmp esp'), executable = True).__next__() + >>> jmp_addr = next(binary.search(asm('jmp esp'), executable = True)) >>> binary.read(jmp_addr, 2) == asm('jmp esp') True """