@@ -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 )
416436class 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