Skip to content

Commit

Permalink
Added support for passing addr_list for analyzing
Browse files Browse the repository at this point in the history
  • Loading branch information
chanijindal1 committed Dec 18, 2024
1 parent cfb62ec commit 143ed5c
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
17 changes: 17 additions & 0 deletions angrop/gadget_finder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,23 @@ def _initialize_gadget_analyzer(self):
def analyze_gadget(self, addr):
return self.gadget_analyzer.analyze_gadget(addr)

def analyze_gadget_list(self, addr_list, processes=4, show_progress=True):
gadgets = []

initargs = (self.gadget_analyzer,)
iterable = addr_list
if show_progress:
iterable = tqdm.tqdm(iterable=iterable, smoothing=0, total=len(addr_list),
desc="ROP", maxinterval=0.5, dynamic_ncols=True)

with Pool(processes=processes, initializer=_set_global_gadget_analyzer, initargs=initargs) as pool:
it = pool.imap_unordered(run_worker, iterable, chunksize=1)
for gadget in it:
if gadget is not None:
gadgets.append(gadget)

return sorted(gadgets, key=lambda x: x.addr)

def get_duplicates(self):
"""
return duplicates that have been seen at least twice
Expand Down
21 changes: 19 additions & 2 deletions angrop/rop.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,26 @@ def analyze_gadget(self, addr):
self._screen_gadgets()
return g

def analyze_gadget_list(self, addr_list, processes=4, show_progress=True):
"""
Analyzes a list of addresses to identify ROP gadgets.
Saves rop gadgets in self.rop_gadgets
Saves syscall gadgets in self.syscall_gadgets
Saves stack pivots in self.stack_pivots
:param processes: number of processes to use
:param show_progress: whether or not to show progress bar
"""

self._all_gadgets = self.gadget_finder.analyze_gadget_list(
addr_list, processes=processes, show_progress=show_progress)
self._screen_gadgets()
return self.rop_gadgets

def find_gadgets(self, processes=4, show_progress=True):
"""
Finds all the gadgets in the binary by calling analyze_gadget on every address near a ret.
Saves gadgets in self._gadgets
Saves rop gadgets in self.rop_gadgets
Saves syscall gadgets in self.syscall_gadgets
Saves stack pivots in self.stack_pivots
:param processes: number of processes to use
"""
Expand All @@ -117,7 +133,8 @@ def find_gadgets(self, processes=4, show_progress=True):
def find_gadgets_single_threaded(self, show_progress=True):
"""
Finds all the gadgets in the binary by calling analyze_gadget on every address near a ret
Saves gadgets in self.gadgets
Saves rop gadgets in self.rop_gadgets
Saves syscall gadgets in self.syscall_gadgets
Saves stack pivots in self.stack_pivots
"""
self._all_gadgets, self._duplicates = self.gadget_finder.find_gadgets_single_threaded(
Expand Down
14 changes: 14 additions & 0 deletions tests/test_find_gadgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,27 @@ def test_gadget_timeout():
gadget = rop.analyze_gadget(0x4005d5)
assert gadget

def local_multiprocess_analyze_gadget_list():
# pylint: disable=pointless-string-statement
proj = angr.Project(os.path.join(tests_dir, "x86_64", "datadep_test"), auto_load_libs=False)
rop = proj.analyses.ROP()
"""
0x4006d8, 0x400864 good gadgets
0x4005d8 bad instruction
"""
gadgets = rop.analyze_gadget_list([0x4006d8, 0x4005d8, 0x400864])
assert len(gadgets[1]) == 2
assert gadgets[0].addr == 0x4006d8
assert gadgets[1].addr == 0x400864

def run_all():
functions = globals()
all_functions = {x:y for x, y in functions.items() if x.startswith('test_')}
for f in sorted(all_functions.keys()):
if hasattr(all_functions[f], '__call__'):
all_functions[f]()
local_multiprocess_find_gadgets()
local_multiprocess_analyze_gadget_list()

if __name__ == "__main__":
logging.getLogger("angrop.rop").setLevel(logging.DEBUG)
Expand Down

0 comments on commit 143ed5c

Please sign in to comment.