Skip to content

Commit 19d290e

Browse files
committed
Add lift_function method to Python architecture class
1 parent 70fd453 commit 19d290e

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

python/architecture.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,26 @@ def finalize(self) -> None:
412412
core.BNAnalyzeBasicBlocksContextFinalize(self._handle)
413413

414414

415+
@dataclass
416+
class FunctionLifterContext:
417+
"""Used by ``lift_function`` and contains contextual information for function-level lifting
418+
419+
.. note:: This class is meant to be used by Architecture plugins only
420+
"""
421+
422+
_handle: core.BNFunctionLifterContext
423+
424+
@staticmethod
425+
def from_core_struct(bn_fl_context: core.BNFunctionLifterContext) -> "FunctionLifterContext":
426+
"""Create a FunctionLifterContext from a core.BNFunctionLifterContext structure."""
427+
428+
return FunctionLifterContext(
429+
_handle=bn_fl_context,
430+
# TODO: Populate additional fields
431+
)
432+
433+
434+
415435
@dataclass(frozen=True)
416436
class RegisterInfo:
417437
full_width_reg: RegisterName
@@ -611,6 +631,7 @@ def __init__(self):
611631
self._get_instruction_low_level_il
612632
)
613633
self._cb.analyzeBasicBlocks = self._cb.analyzeBasicBlocks.__class__(self._analyze_basic_blocks)
634+
self._cb.liftFunction = self._cb.liftFunction.__class__(self._lift_function)
614635
self._cb.getRegisterName = self._cb.getRegisterName.__class__(self._get_register_name)
615636
self._cb.getFlagName = self._cb.getFlagName.__class__(self._get_flag_name)
616637
self._cb.getFlagWriteTypeName = self._cb.getFlagWriteTypeName.__class__(self._get_flag_write_type_name)
@@ -1084,6 +1105,15 @@ def _analyze_basic_blocks(self, ctx, func, ptr_bn_bb_context):
10841105
except:
10851106
log_error_for_exception("Unhandled Python exception in Architecture._analyze_basic_blocks")
10861107

1108+
def _lift_function(self, ctx, func, ptr_bn_fl_context):
1109+
try:
1110+
bn_fl_context = ptr_bn_fl_context.contents
1111+
context = FunctionLifterContext.from_core_struct(bn_fl_context)
1112+
return self.lift_function(lowlevelil.LowLevelILFunction(arch=self, handle=core.BNNewLowLevelILFunctionReference(func)), context)
1113+
except:
1114+
log_error_for_exception("Unhandled Python exception in Architecture._lift_function")
1115+
return False
1116+
10871117
def _get_register_name(self, ctxt, reg):
10881118
try:
10891119
if reg in self._regs_by_index:
@@ -1814,6 +1844,22 @@ def analyze_basic_blocks(self, func: 'function.Function', context: BasicBlockAna
18141844
except:
18151845
log_error_for_exception("Unhandled Python exception in Architecture.analyze_basic_blocks")
18161846

1847+
def lift_function(self, func: "lowlevelil.LowLevelILFunction", context: FunctionLifterContext):
1848+
"""
1849+
``lift_function`` performs lifting of the function and commits the results to the function analysis
1850+
1851+
.. note:: Architecture subclasses should only implement this method if function-level analysis is required
1852+
1853+
:param LowLevelILFunction func: the function to analyze
1854+
:param FunctionLifterContext context: the lifting context
1855+
"""
1856+
1857+
try:
1858+
return core.BNArchitectureDefaultLiftFunction(func.handle, context._handle)
1859+
except:
1860+
log_error_for_exception("Unhandled Python exception in Architecture.lift_function")
1861+
return False
1862+
18171863
def get_low_level_il_from_bytes(self, data: bytes, addr: int) -> 'lowlevelil.LowLevelILInstruction':
18181864
"""
18191865
``get_low_level_il_from_bytes`` converts the instruction in bytes to ``il`` at the given virtual address

0 commit comments

Comments
 (0)