diff options
| author | Jordan Wiens <jordan@psifertex.com> | 2025-07-09 20:54:37 -0400 |
|---|---|---|
| committer | Jordan Wiens <jordan@psifertex.com> | 2025-07-09 21:07:16 -0400 |
| commit | f3e2a872d8cbf45428e750cffb3b1d220b331d5f (patch) | |
| tree | 8fbde00170593170b49d8c2a74d89baad3a20801 /python | |
| parent | b8daf0b7953c56f202abfcd7fad99882c21ec11d (diff) | |
reimplement llil validation for caller_sites and implement plural IL forms on references
Diffstat (limited to 'python')
| -rw-r--r-- | python/binaryview.py | 24 | ||||
| -rw-r--r-- | python/function.py | 37 |
2 files changed, 59 insertions, 2 deletions
diff --git a/python/binaryview.py b/python/binaryview.py index da2423ac..e2af96a1 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -126,17 +126,41 @@ class ReferenceSource: return self.function.get_low_level_il_at(self.address, self.arch) @property + def llils(self) -> Iterator[lowlevelil.LowLevelILInstruction]: + """Returns the low level il instructions at the current location if any exists""" + if self.function is None or self.arch is None: + return + return self.function.get_low_level_ils_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 mlils(self) -> Iterator[mediumlevelil.MediumLevelILInstruction]: + """Returns the medium level il instructions at the current location if any exists""" + if self.function is None or self.arch is None: + return + for llil in self.llils: + for mlil in llil.mlils: + yield mlil + + @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 + @property + def hlils(self) -> Iterator[highlevelil.HighLevelILInstruction]: + """Returns the high level il instructions at the current location if any exists""" + if self.function is None or self.arch is None: + return + for llil in self.llils: + for hlil in llil.hlils: + yield hlil class NotificationType(IntFlag): NotificationBarrier = 1 << 0 diff --git a/python/function.py b/python/function.py index 9ea8093b..01b482c4 100644 --- a/python/function.py +++ b/python/function.py @@ -1863,6 +1863,38 @@ class Function: return llil[idx] + def get_low_level_ils_at(self, addr: int, + arch: Optional['architecture.Architecture'] = None) -> List['lowlevelil.LowLevelILInstruction']: + """ + ``get_low_level_ils_at`` gets the LowLevelILInstruction(s) corresponding to the given virtual address + See the `developer docs <https://dev-docs.binary.ninja/dev/concepts.html#mapping-between-ils>`_ for more information. + + :param int addr: virtual address of the instruction to be queried + :param Architecture arch: (optional) Architecture for the given function + :rtype: list(LowLevelILInstruction) + :Example: + + >>> func = next(bv.functions) + >>> func.get_low_level_ils_at(func.start) + [<il: push(rbp)>] + """ + llil = self.llil + if llil is None: + return [] + + if arch is None: + arch = self.arch + count = ctypes.c_ulonglong() + instrs = core.BNGetLowLevelILInstructionsForAddress(self.handle, arch.handle, addr, count) + assert instrs is not None, "core.BNGetLowLevelILInstructionsForAddress returned None" + try: + result = [] + for i in range(0, count.value): + result.append(llil[instrs[i]]) + return result + finally: + core.BNFreeILInstructionList(instrs) + def get_llil_at(self, addr: int, arch: Optional['architecture.Architecture'] = None) -> Optional['lowlevelil.LowLevelILInstruction']: """ @@ -3265,8 +3297,9 @@ class Function: :rtype: list(ReferenceSource) """ for site in self.view.get_code_refs(self.start): - if isinstance(site.llil, Localcall): - yield site + for llil in site.llils: + if isinstance(llil, Localcall) and llil.dest.value == self.start: + yield site @property def workflow(self): |
