diff options
| author | Peter LaFosse <peter@vector35.com> | 2021-06-23 09:31:22 -0400 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2021-09-05 10:08:09 -0400 |
| commit | 6de4900db74a341fddfda46f7cb4342fdc31f8e0 (patch) | |
| tree | 790a990b2b9ccd8229a31754d28a74a2db839851 /python/function.py | |
| parent | ea052d32732f62000164f243a1aad0bb7425199e (diff) | |
Refactor Variable class
The Variable class is now broken into 3 separate classes with helper
methods to convert between them.
CoreVariable is implemented as a frozen dataclass and is analogous
to BNVariable
VariableNameAndType is analogous to BNVariableNameAndType
Bothe the above are passive objects and can not be changed directly
The new and improved Variable object is now an active object which
can be operated on directly and changes will take effect immediately
Diffstat (limited to 'python/function.py')
| -rw-r--r-- | python/function.py | 102 |
1 files changed, 43 insertions, 59 deletions
diff --git a/python/function.py b/python/function.py index 64aabdbb..64d54327 100644 --- a/python/function.py +++ b/python/function.py @@ -858,8 +858,19 @@ class Function(object): assert v is not None, "core.BNGetStackLayout returned None" try: for i in range(0, count.value): - yield variable.Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, - types.Type(handle = core.BNNewTypeReference(v[i].type), platform = self.platform, confidence = v[i].typeConfidence)) + yield variable.Variable.from_BNVariable(self, v[i].var) + finally: + core.BNFreeVariableNameAndTypeList(v, count.value) + + @property + def core_var_stack_layout(self) -> Generator['variable.CoreVariable', None, None]: + """List of function stack variables (read-only)""" + count = ctypes.c_ulonglong() + v = core.BNGetStackLayout(self.handle, count) + assert v is not None, "core.BNGetStackLayout returned None" + try: + for i in range(0, count.value): + yield variable.CoreVariable.from_BNVariable(v[i].var) finally: core.BNFreeVariableNameAndTypeList(v, count.value) @@ -871,8 +882,19 @@ class Function(object): assert v is not None, "core.BNGetFunctionVariables returned None" try: for i in range(0, count.value): - yield variable.Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, - types.Type(handle = core.BNNewTypeReference(v[i].type), platform = self.platform, confidence = v[i].typeConfidence)) + yield variable.Variable.from_BNVariable(self, v[i].var) + finally: + core.BNFreeVariableNameAndTypeList(v, count.value) + + @property + def core_vars(self) -> Generator['variable.CoreVariable', None, None]: + """Generator of CoreVariable objects""" + count = ctypes.c_ulonglong() + v = core.BNGetFunctionVariables(self.handle, count) + assert v is not None, "core.BNGetFunctionVariables returned None" + try: + for i in range(0, count.value): + yield variable.CoreVariable.from_BNVariable(v[i].var) finally: core.BNFreeVariableNameAndTypeList(v, count.value) @@ -1005,7 +1027,7 @@ class Function(object): result = core.BNGetFunctionParameterVariables(self.handle) var_list = [] for i in range(0, result.count): - var_list.append(variable.Variable(self, result.vars[i].type, result.vars[i].index, result.vars[i].storage)) + var_list.append(variable.Variable.from_BNVariable(self, result.vars[i])) confidence = result.confidence core.BNFreeParameterVariables(result) return variable.ParameterVariables(var_list, confidence, self) @@ -1919,8 +1941,8 @@ class Function(object): result = [] for i in range(0, count.value): var_type = types.Type(core.BNNewTypeReference(refs[i].type), platform = self.platform, confidence = refs[i].typeConfidence) - result.append(variable.StackVariableReference(refs[i].sourceOperand, var_type, - refs[i].name, variable.Variable.from_identifier(self, refs[i].varIdentifier, refs[i].name, var_type), + var = variable.Variable.from_identifier(self, refs[i].varIdentifier) + result.append(variable.StackVariableReference(refs[i].sourceOperand, var_type, refs[i].name, var, refs[i].referencedOffset, refs[i].size)) core.BNFreeStackVariableReferenceList(refs, count.value) return result @@ -2499,46 +2521,26 @@ class Function(object): def create_auto_var(self, var:'variable.Variable', var_type:'types.Type', name:str, ignore_disjoint_uses:bool=False) -> None: - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage tc = core.BNTypeWithConfidence() tc.type = var_type.handle tc.confidence = var_type.confidence - core.BNCreateAutoVariable(self.handle, var_data, tc, name, ignore_disjoint_uses) + core.BNCreateAutoVariable(self.handle, var.to_BNVariable(), tc, name, ignore_disjoint_uses) def create_user_var(self, var:'variable.Variable', var_type:'types.Type', name:str, ignore_disjoint_uses:bool=False) -> None: - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage tc = core.BNTypeWithConfidence() tc.type = var_type.handle tc.confidence = var_type.confidence - core.BNCreateUserVariable(self.handle, var_data, tc, name, ignore_disjoint_uses) + core.BNCreateUserVariable(self.handle, var.to_BNVariable(), tc, name, ignore_disjoint_uses) def delete_auto_var(self, var:'variable.Variable') -> None: - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - core.BNDeleteAutoVariable(self.handle, var_data) + core.BNDeleteAutoVariable(self.handle, var.to_BNVariable()) def delete_user_var(self, var:'variable.Variable') -> None: - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - core.BNDeleteUserVariable(self.handle, var_data) + core.BNDeleteUserVariable(self.handle, var.to_BNVariable()) def is_var_user_defined(self, var:'variable.Variable') -> bool: - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - return core.BNIsVariableUserDefined(self.handle, var_data) + return core.BNIsVariableUserDefined(self.handle, var.to_BNVariable()) def get_stack_var_at_frame_offset(self, offset:int, addr:int, arch:Optional['architecture.Architecture']=None) -> \ Optional['variable.Variable']: @@ -2549,9 +2551,7 @@ class Function(object): found_var = core.BNVariableNameAndType() if not core.BNGetStackVariableAtFrameOffset(self.handle, arch.handle, addr, offset, found_var): return None - result = variable.Variable(self, found_var.var.type, found_var.var.index, found_var.var.storage, - found_var.name, types.Type(handle = core.BNNewTypeReference(found_var.type), platform = self.platform, - confidence = found_var.typeConfidence)) + result = variable.Variable.from_BNVariable(self, found_var.var) core.BNFreeVariableNameAndType(found_var) return result @@ -2576,7 +2576,7 @@ class Function(object): raise Exception("can not get_reg_value_at_exit if Function.arch is") result = core.BNGetFunctionRegisterValueAtExit(self.handle, self.arch.get_reg_index(reg)) - return variable.RegisterValue(self.arch, result.value, confidence = result.confidence) + return variable.RegisterValue.from_BNRegisterValue(result, self.arch) def set_auto_call_stack_adjustment(self, addr:int, adjust:Union[int, 'types.SizeWithConfidence'],\ arch:Optional['architecture.Architecture']=None) -> None: @@ -2764,11 +2764,7 @@ class Function(object): def_site.arch = self.arch.handle def_site.address = def_addr - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - core.BNSetUserVariableValue(self.handle, var_data, def_site, value._to_api_object()) + core.BNSetUserVariableValue(self.handle, var.to_BNVariable(), def_site, value._to_api_object()) def clear_user_var_value(self, var:'variable.Variable', def_addr:int) -> None: """ @@ -2795,11 +2791,7 @@ class Function(object): def_site.arch = self.arch.handle def_site.address = def_addr - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - core.BNClearUserVariableValue(self.handle, var_data, def_site) + core.BNClearUserVariableValue(self.handle, var.to_BNVariable(), def_site) def get_all_user_var_values(self) -> \ Mapping['variable.Variable', Mapping['ArchAndAddr', 'variable.PossibleValueSet']]: @@ -2816,7 +2808,7 @@ class Function(object): i = 0 for i in range(count.value): var_val = var_values[i] - var = variable.Variable(self, var_val.var.type, var_val.var.index, var_val.var.storage) + var = variable.Variable.from_BNVariable(self, var_val.var) if var not in result: result[var] = {} def_site = ArchAndAddr(var_val.defSite.arch, var_val.defSite.address) @@ -2948,11 +2940,7 @@ class Function(object): >>> current_function.get_mlil_var_refs(var) """ count = ctypes.c_ulonglong(0) - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - refs = core.BNGetMediumLevelILVariableReferences(self.handle, var_data, count) + refs = core.BNGetMediumLevelILVariableReferences(self.handle, var.to_BNVariable(), count) assert refs is not None, "core.BNGetMediumLevelILVariableReferences returned None" result = [] for i in range(0, count.value): @@ -3002,7 +2990,7 @@ class Function(object): refs = core.BNGetMediumLevelILVariableReferencesInRange(self.handle, arch.handle, addr, length, count) assert refs is not None, "core.BNGetMediumLevelILVariableReferencesInRange returned None" for i in range(0, count.value): - var = variable.Variable(self, refs[i].var.type, refs[i].var.index, refs[i].var.storage) + var = variable.Variable.from_BNVariable(self, refs[i].var) if refs[i].source.func: func = Function(self.view, core.BNNewFunctionReference(refs[i].source.func)) else: @@ -3032,11 +3020,7 @@ class Function(object): >>> current_function.get_hlil_var_refs(var) """ count = ctypes.c_ulonglong(0) - var_data = core.BNVariable() - var_data.type = var.source_type - var_data.index = var.index - var_data.storage = var.storage - refs = core.BNGetHighLevelILVariableReferences(self.handle, var_data, count) + refs = core.BNGetHighLevelILVariableReferences(self.handle, var.to_BNVariable(), count) assert refs is not None, "core.BNGetHighLevelILVariableReferences returned None" result = [] for i in range(0, count.value): @@ -3080,7 +3064,7 @@ class Function(object): refs = core.BNGetHighLevelILVariableReferencesInRange(self.handle, arch.handle, addr, length, count) assert refs is not None, "core.BNGetHighLevelILVariableReferencesInRange returned None" for i in range(0, count.value): - var = variable.Variable(self, refs[i].var.type, refs[i].var.index, refs[i].var.storage) + var = variable.Variable.from_BNVariable(self, refs[i].var) if refs[i].source.func: func = Function(self.view, core.BNNewFunctionReference(refs[i].source.func)) else: |
