Skip to content

Commit f3e2a87

Browse files
committed
reimplement llil validation for caller_sites and implement plural IL forms on references
1 parent b8daf0b commit f3e2a87

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

python/binaryview.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,42 @@ def llil(self) -> Optional[lowlevelil.LowLevelILInstruction]:
125125
return None
126126
return self.function.get_low_level_il_at(self.address, self.arch)
127127

128+
@property
129+
def llils(self) -> Iterator[lowlevelil.LowLevelILInstruction]:
130+
"""Returns the low level il instructions at the current location if any exists"""
131+
if self.function is None or self.arch is None:
132+
return
133+
return self.function.get_low_level_ils_at(self.address, self.arch)
134+
128135
@property
129136
def mlil(self) -> Optional[mediumlevelil.MediumLevelILInstruction]:
130137
"""Returns the medium level il instruction at the current location if one exists"""
131138
llil = self.llil
132139
return llil.mlil if llil is not None else None
133140

141+
@property
142+
def mlils(self) -> Iterator[mediumlevelil.MediumLevelILInstruction]:
143+
"""Returns the medium level il instructions at the current location if any exists"""
144+
if self.function is None or self.arch is None:
145+
return
146+
for llil in self.llils:
147+
for mlil in llil.mlils:
148+
yield mlil
149+
134150
@property
135151
def hlil(self) -> Optional[highlevelil.HighLevelILInstruction]:
136152
"""Returns the high level il instruction at the current location if one exists"""
137153
mlil = self.mlil
138154
return mlil.hlil if mlil is not None else None
139155

156+
@property
157+
def hlils(self) -> Iterator[highlevelil.HighLevelILInstruction]:
158+
"""Returns the high level il instructions at the current location if any exists"""
159+
if self.function is None or self.arch is None:
160+
return
161+
for llil in self.llils:
162+
for hlil in llil.hlils:
163+
yield hlil
140164

141165
class NotificationType(IntFlag):
142166
NotificationBarrier = 1 << 0

python/function.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,6 +1863,38 @@ def get_low_level_il_at(
18631863

18641864
return llil[idx]
18651865

1866+
def get_low_level_ils_at(self, addr: int,
1867+
arch: Optional['architecture.Architecture'] = None) -> List['lowlevelil.LowLevelILInstruction']:
1868+
"""
1869+
``get_low_level_ils_at`` gets the LowLevelILInstruction(s) corresponding to the given virtual address
1870+
See the `developer docs <https://dev-docs.binary.ninja/dev/concepts.html#mapping-between-ils>`_ for more information.
1871+
1872+
:param int addr: virtual address of the instruction to be queried
1873+
:param Architecture arch: (optional) Architecture for the given function
1874+
:rtype: list(LowLevelILInstruction)
1875+
:Example:
1876+
1877+
>>> func = next(bv.functions)
1878+
>>> func.get_low_level_ils_at(func.start)
1879+
[<il: push(rbp)>]
1880+
"""
1881+
llil = self.llil
1882+
if llil is None:
1883+
return []
1884+
1885+
if arch is None:
1886+
arch = self.arch
1887+
count = ctypes.c_ulonglong()
1888+
instrs = core.BNGetLowLevelILInstructionsForAddress(self.handle, arch.handle, addr, count)
1889+
assert instrs is not None, "core.BNGetLowLevelILInstructionsForAddress returned None"
1890+
try:
1891+
result = []
1892+
for i in range(0, count.value):
1893+
result.append(llil[instrs[i]])
1894+
return result
1895+
finally:
1896+
core.BNFreeILInstructionList(instrs)
1897+
18661898
def get_llil_at(self, addr: int,
18671899
arch: Optional['architecture.Architecture'] = None) -> Optional['lowlevelil.LowLevelILInstruction']:
18681900
"""
@@ -3265,8 +3297,9 @@ def caller_sites(self) -> Generator['binaryview.ReferenceSource', None, None]:
32653297
:rtype: list(ReferenceSource)
32663298
"""
32673299
for site in self.view.get_code_refs(self.start):
3268-
if isinstance(site.llil, Localcall):
3269-
yield site
3300+
for llil in site.llils:
3301+
if isinstance(llil, Localcall) and llil.dest.value == self.start:
3302+
yield site
32703303

32713304
@property
32723305
def workflow(self):

0 commit comments

Comments
 (0)