From e18c9d35c0f5f70b6cdaaa54283a838f33479df9 Mon Sep 17 00:00:00 2001 From: NeoQuix <83972469+NeoQuix@users.noreply.github.com> Date: Tue, 1 Oct 2024 14:37:37 +0200 Subject: [PATCH] Fix: EnumerationType support in lifter (and format) (#440) --- .../frontend/binaryninja/handlers/globals.py | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/decompiler/frontend/binaryninja/handlers/globals.py b/decompiler/frontend/binaryninja/handlers/globals.py index ae25747c..94fb77d0 100644 --- a/decompiler/frontend/binaryninja/handlers/globals.py +++ b/decompiler/frontend/binaryninja/handlers/globals.py @@ -8,6 +8,7 @@ ArrayType, BoolType, CharType, + EnumerationType, FloatType, FunctionType, IntegerType, @@ -21,7 +22,6 @@ from decompiler.frontend.lifter import Handler from decompiler.structures.pseudo import ArrayType as PseudoArrayType from decompiler.structures.pseudo import ( - ComplexTypeMember, Constant, ConstantComposition, CustomType, @@ -31,7 +31,6 @@ Integer, OperationType, Pointer, - Struct, StructConstant, Symbol, UnaryOperation, @@ -64,9 +63,12 @@ ==> trust bninja lift normally => If a void*, then we try determine the value via get_unknown_pointer_value - NamedTypeReferenceType - - (enum/structs + - (enum/structs references) => lifts struct members recursively => includes special handling of a BNinja bug when accessing certain PDB enum types + - EnumerationType + - lift enums with their corresponding type + - !Upstream Error with with PE files with PDB information present - StructType - enum/structs => implementation *very* similar to NamedTypeReferenceType @@ -95,6 +97,7 @@ def __init__(self, lifter): VoidType: self._lift_void_type, ArrayType: self._lift_array_type, PointerType: self._lift_pointer_type, + EnumerationType: self._lift_enum_type, NamedTypeReferenceType: self._lift_named_type_ref, StructureType: self._lift_structure_type, } @@ -264,17 +267,7 @@ def _lift_named_type_ref(self, variable: DataVariable, parent: Optional[MediumLe return self._lift_struct_helper(variable, parent, struct_type) case NamedTypeReferenceClass.EnumNamedTypeClass: - try: - value = Constant(variable.value, self._lifter.lift(variable.type)) - return self._build_global_variable( - variable.name, - value.type, - variable.address, - value, - parent.ssa_memory_version if parent else 0, - ) - except Exception: - return Constant("Unknown value", self._lifter.lift(variable.type)) # BNinja error + return self._lift_enum_type(variable, parent) case _: raise NotImplementedError(f"No handler for '{variable.type.named_type_class}' in lifter") @@ -299,6 +292,20 @@ def _lift_struct_helper(self, variable, parent, struct_type): variable.name, s_type, variable.address, StructConstant(values, s_type), parent.ssa_memory_version if parent else 0 ) + def _lift_enum_type(self, variable: DataVariable, parent: Optional[MediumLevelILInstruction] = None, **_): + """Lift a Enum type from Binary Ninja. Try/Catch Block because of an upstream problem with PDB on PE files""" + try: + value = Constant(variable.value, self._lifter.lift(variable.type)) + return self._build_global_variable( + variable.name, + value.type, + variable.address, + value, + parent.ssa_memory_version if parent else 0, + ) + except Exception: + return Constant("Unknown value", self._lifter.lift(variable.type)) # BNinja error + def _get_unknown_value(self, variable: DataVariable): """Return string or bytes at dv.address(!) (dv.type must be void)""" if (data := get_different_string_types_at(variable.address, self._view)) and data[0] is not None: