diff --git a/decompiler/frontend/binaryninja/handlers/globals.py b/decompiler/frontend/binaryninja/handlers/globals.py index e1ca10a4..a57cd434 100644 --- a/decompiler/frontend/binaryninja/handlers/globals.py +++ b/decompiler/frontend/binaryninja/handlers/globals.py @@ -156,6 +156,10 @@ def lift_global_variable( if not self._view: self._view = view + # BNinja error cases: nullptr/small numbers (0, -12...) + if not addr_in_section(view, variable.address): + return Constant(variable.address, vartype=Integer(view.address_size * BYTE_SIZE, False)) + # If addr was already lifted: Return lifted GlobalVariable with updated SSA variable_identifier = (variable.address, self._lifter.lift(variable.type)) if variable_identifier in self._lifted_globals.keys(): @@ -165,10 +169,6 @@ def lift_global_variable( else self._lifted_globals[variable_identifier] ) - # BNinja error cases: nullptr/small numbers (0, -12...) - if not addr_in_section(view, variable.address): - return Constant(variable.address, vartype=Integer(view.address_size * BYTE_SIZE, False)) - # Check if there is a cycle between GlobalVariables initial_value if callers and variable.address in callers: return ( @@ -231,6 +231,8 @@ def _lift_pointer_type( 1. Function pointer: If Bninja already knows it's a function pointer. 2. Type pointer: As normal type pointer (there _should_ be a datavariable at the pointers dest.) 3. Void pointer: Try to extract a datavariable (recover type of void* directly), string (char*) or raw bytes (void*) at the given address + Caution: A pointer can point at a constant instead of a variable (e.g. stdout/stderr) + => 2/3 catch this error with a value in section check """ match variable.type.target: case FunctionType(): # BNinja knows it's a imported function pointer @@ -239,19 +241,23 @@ def _lift_pointer_type( ) case VoidType(): # BNinja knows it's a pointer pointing at something # Extract the initial_value and type from the location where the pointer is pointing to - init_value, type = self._get_unknown_pointer_value(variable, callers) + init_value, vtype = self._get_unknown_pointer_value(variable, callers) case _: if callers: callers.append(variable.address) else: callers = [variable.address] - init_value, type = ( - self._lifter.lift(self._view.get_data_var_at(variable.value), view=self._view, callers=callers), - self._lifter.lift(variable.type), - ) + + vtype = self._lifter.lift(variable.type) + # BNinja error case: Pointer does not point at variable in view + if not addr_in_section(self._view, variable.value): + init_value = Constant(variable.value, vartype=Integer(self._view.address_size * BYTE_SIZE, False)) + else: + init_value = self._lifter.lift(self._view.get_data_var_at(variable.value), view=self._view, callers=callers) + return self._build_global_variable( name=self._lifter.lift(variable.symbol).name if variable.symbol else None, - type=type, + type=vtype, addr=variable.address, init_value=init_value, ssa_label=parent.ssa_memory_version if parent else 0,