From ce335c283f87297855bd9360e7063f3b8ef34afc Mon Sep 17 00:00:00 2001 From: Peter LaFosse Date: Thu, 23 Jun 2022 13:57:56 -0400 Subject: Add some helper routines for getting the IL of callsites --- python/binaryview.py | 19 +++++++++++++++++++ python/function.py | 13 ++++++++++++- suite/api_test.py | 12 ++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/python/binaryview.py b/python/binaryview.py index c28e225a..fbbba6f9 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -105,6 +105,25 @@ class ReferenceSource: return ReferenceSource(func, arch, ref.addr) + @property + def llil(self) -> Optional[lowlevelil.LowLevelILInstruction]: + """Returns the low level il instruction at the current location if one exists""" + if self.function is None or self.arch is None: + return None + return self.function.get_low_level_il_at(self.address, self.arch) + + @property + def mlil(self) -> Optional[mediumlevelil.MediumLevelILInstruction]: + """Returns the medium level il instruction at the current location if one exists""" + llil = self.llil + return llil.mlil if llil is not None else None + + @property + def hlil(self) -> Optional[highlevelil.HighLevelILInstruction]: + """Returns the high level il instruction at the current location if one exists""" + mlil = self.mlil + return mlil.hlil if mlil is not None else None + class BinaryDataNotification: def __init__(self): diff --git a/python/function.py b/python/function.py index 4d859683..c43a5868 100644 --- a/python/function.py +++ b/python/function.py @@ -3120,7 +3120,7 @@ class Function: ``callers`` returns a list of functions that call this function Does not point to the actual address where the call occurs, just the start of the function that contains the call. - :return: List of start addresess for Functions that call this function + :return: List of start addresses for Functions that call this function :rtype: list(int) """ functions = [] @@ -3129,6 +3129,17 @@ class Function: functions.append(ref.function) return functions + @property + def caller_sites(self) -> Generator['ReferenceSource', None, None]: + """ + ``caller_sites`` returns a list of ReferenceSource objects corresponding to the addresses + in functions which reference this function + + :return: List of start ReferenceSource objects of the call sites to this function + :rtype: list(int) + """ + return self.view.get_code_refs(self.start) + @property def workflow(self): handle = core.BNGetWorkflowForFunction(self.handle) diff --git a/suite/api_test.py b/suite/api_test.py index 793b2b1a..8ef6aa04 100644 --- a/suite/api_test.py +++ b/suite/api_test.py @@ -2094,6 +2094,18 @@ class TestWithFunction(TestWithBinaryView): self.func.add_user_code_ref(from_addr, to_addr) refs = list(self.func.view.get_code_refs(from_addr)) + f = self.bv.get_functions_by_name("puts")[0] + refs = list(f.caller_sites) + assert len(refs) == 2 + assert str(refs[0].llil) == 'call(0x82dc)' + assert str(refs[1].llil) == 'call(0x82dc)' + + assert str(refs[0].mlil) == '0x82dc("helloworld")' + assert str(refs[1].mlil) == '0x82dc("goodbyeworld")' + + assert str(refs[0].hlil) == 'puts("helloworld")' + assert str(refs[1].hlil) == 'puts("goodbyeworld")' + def test_reg_values(self): r0 = self.bv.arch.get_reg_index('r0') r3 = self.bv.arch.get_reg_index('r3') -- cgit v1.3.1