diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/binaryview.py | 3 | ||||
| -rw-r--r-- | python/function.py | 4 | ||||
| -rw-r--r-- | python/highlevelil.py | 31 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 33 | ||||
| -rw-r--r-- | python/variable.py | 58 |
5 files changed, 100 insertions, 29 deletions
diff --git a/python/binaryview.py b/python/binaryview.py index 10431078..be4f28be 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -6178,9 +6178,6 @@ class BinaryView: raise TypeError("Removal is only supported with a Component or string representing its Guid") - def get_constant_data(self, addr: int) -> databuffer.DataBuffer: - return databuffer.DataBuffer(handle=core.BNGetConstantData(self.handle, addr)) - def get_strings(self, start: Optional[int] = None, length: Optional[int] = None) -> List['StringReference']: """ ``get_strings`` returns a list of strings defined in the binary in the optional virtual address range: diff --git a/python/function.py b/python/function.py index 7511b809..73b08b48 100644 --- a/python/function.py +++ b/python/function.py @@ -39,6 +39,7 @@ from . import mediumlevelil from . import highlevelil from . import binaryview from . import basicblock +from . import databuffer from . import variable from . import flowgraph from . import callingconvention @@ -1692,6 +1693,9 @@ class Function: finally: core.BNFreeILInstructionList(exits) + def get_constant_data(self, state: RegisterValueType, value: int, size: int = 0) -> databuffer.DataBuffer: + return databuffer.DataBuffer(handle=core.BNGetConstantData(self.handle, state, value, size)) + def get_reg_value_at( self, addr: int, reg: 'architecture.RegisterType', arch: Optional['architecture.Architecture'] = None ) -> 'variable.RegisterValue': diff --git a/python/highlevelil.py b/python/highlevelil.py index 8c84a646..1784c806 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -210,6 +210,8 @@ class HighLevelILInstruction(BaseILInstruction): ("constant", "int"), ("offset", "int") ], HighLevelILOperation.HLIL_FLOAT_CONST: [("constant", "float")], HighLevelILOperation.HLIL_IMPORT: [ ("constant", "int") + ], HighLevelILOperation.HLIL_CONST_DATA: [("constant_data", "constant_data")], HighLevelILOperation.HLIL_CONST_DATA: [ + ("constant_data", "constant_data") ], HighLevelILOperation.HLIL_ADD: [("left", "expr"), ("right", "expr")], HighLevelILOperation.HLIL_ADC: [ ("left", "expr"), ("right", "expr"), ("carry", "expr") ], HighLevelILOperation.HLIL_SUB: [("left", "expr"), ("right", "expr")], HighLevelILOperation.HLIL_SBB: [ @@ -686,6 +688,11 @@ class HighLevelILInstruction(BaseILInstruction): else: return float(value) + def get_constant_data(self, operand_index1: int, operand_index2: int) -> variable.ConstantData: + state = variable.RegisterValueType(self.core_instr.operands[operand_index1]) + value = self.core_instr.operands[operand_index2] + return variable.ConstantData(value, 0, state, core.max_confidence, self.core_instr.size, self.function.source_function) + def get_expr(self, operand_index: int) -> 'HighLevelILInstruction': return HighLevelILInstruction.create(self.function, ExpressionIndex(self.core_instr.operands[operand_index])) @@ -1418,17 +1425,6 @@ class HighLevelILConst(HighLevelILInstruction, Constant): @dataclass(frozen=True, repr=False, eq=False) -class HighLevelILConstData(HighLevelILInstruction, Constant): - @property - def constant(self) -> 'databuffer.DataBuffer': - return self.function.source_function.view.get_constant_data(self.get_int(0)) - - @property - def operands(self) -> List[HighLevelILOperandType]: - return [self.constant] - - -@dataclass(frozen=True, repr=False, eq=False) class HighLevelILConstPtr(HighLevelILInstruction, Constant): @property def constant(self) -> int: @@ -1477,6 +1473,17 @@ class HighLevelILImport(HighLevelILInstruction, Constant): @dataclass(frozen=True, repr=False, eq=False) +class HighLevelILConstData(HighLevelILInstruction, Constant): + @property + def constant_data(self) -> variable.ConstantData: + return self.get_constant_data(0, 1) + + @property + def operands(self) -> List[HighLevelILOperandType]: + return [self.constant_data] + + +@dataclass(frozen=True, repr=False, eq=False) class HighLevelILAdd(HighLevelILBinaryBase, Arithmetic): pass @@ -2005,11 +2012,11 @@ ILInstruction = { HighLevelILDerefFieldSsa, # ("src", "expr"), ("src_memory", "int"), ("offset", "int"), ("member_index", "member_index"), HighLevelILOperation.HLIL_ADDRESS_OF: HighLevelILAddressOf, # ("src", "expr"), HighLevelILOperation.HLIL_CONST: HighLevelILConst, # ("constant", "int"), - HighLevelILOperation.HLIL_CONST_DATA: HighLevelILConstData, # ("constant", "int"), HighLevelILOperation.HLIL_CONST_PTR: HighLevelILConstPtr, # ("constant", "int"), HighLevelILOperation.HLIL_EXTERN_PTR: HighLevelILExternPtr, # ("constant", "int"), ("offset", "int"), HighLevelILOperation.HLIL_FLOAT_CONST: HighLevelILFloatConst, # ("constant", "float"), HighLevelILOperation.HLIL_IMPORT: HighLevelILImport, # ("constant", "int"), + HighLevelILOperation.HLIL_CONST_DATA: HighLevelILConstData, # [("constant_data", "constant_data")], HighLevelILOperation.HLIL_ADD: HighLevelILAdd, # ("left", "expr"), ("right", "expr"), HighLevelILOperation.HLIL_ADC: HighLevelILAdc, # ("left", "expr"), ("right", "expr"), ("carry", "expr"), HighLevelILOperation.HLIL_SUB: HighLevelILSub, # ("left", "expr"), ("right", "expr"), diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 68cddcb8..e5b1e704 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -152,12 +152,12 @@ class MediumLevelILInstruction(BaseILInstruction): ("src", "var"), ("offset", "int") ], MediumLevelILOperation.MLIL_CONST: [("constant", "int")], MediumLevelILOperation.MLIL_CONST_PTR: [ ("constant", "int") - ], MediumLevelILOperation.MLIL_CONST_DATA: [("constant", "int")], MediumLevelILOperation.MLIL_CONST_DATA: [ - ("constant", "int") ], MediumLevelILOperation.MLIL_EXTERN_PTR: [ ("constant", "int"), ("offset", "int") ], MediumLevelILOperation.MLIL_FLOAT_CONST: [("constant", "float")], MediumLevelILOperation.MLIL_IMPORT: [ ("constant", "int") + ], MediumLevelILOperation.MLIL_CONST_DATA: [("constant_data", "constant_data")], MediumLevelILOperation.MLIL_CONST_DATA: [ + ("constant_data", "constant_data") ], MediumLevelILOperation.MLIL_ADD: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ADC: [ ("left", "expr"), ("right", "expr"), ("carry", "expr") ], MediumLevelILOperation.MLIL_SUB: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_SBB: [ @@ -797,6 +797,11 @@ class MediumLevelILInstruction(BaseILInstruction): else: return float(value) + def _get_constant_data(self, operand_index1: int, operand_index2: int) -> variable.ConstantData: + state = variable.RegisterValueType(self.instr.operands[operand_index1]) + value = self.instr.operands[operand_index2] + return variable.ConstantData(value, 0, state, core.max_confidence, self.instr.size, self.function.source_function) + def _get_expr(self, operand_index: int) -> 'MediumLevelILInstruction': return MediumLevelILInstruction.create(self.function, ExpressionIndex(self.instr.operands[operand_index])) @@ -1046,17 +1051,6 @@ class MediumLevelILConst(MediumLevelILConstBase): @dataclass(frozen=True, repr=False, eq=False) -class MediumLevelILConstData(MediumLevelILConstBase): - @property - def constant(self) -> 'databuffer.DataBuffer': - return self.function.source_function.view.get_constant_data(self._get_int(0)) - - @property - def operands(self) -> List[databuffer.DataBuffer]: - return [self.constant] - - -@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILConstPtr(MediumLevelILConstBase): @property def constant(self) -> int: @@ -1090,6 +1084,17 @@ class MediumLevelILImport(MediumLevelILConstBase): @dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILConstData(MediumLevelILConstBase): + @property + def constant_data(self) -> variable.ConstantData: + return self._get_constant_data(0, 1) + + @property + def operands(self) -> List[variable.ConstantData]: + return [self.constant_data] + + +@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILNeg(MediumLevelILUnaryBase, Arithmetic): pass @@ -2516,10 +2521,10 @@ ILInstruction = { MediumLevelILOperation.MLIL_VAR: MediumLevelILVar, # [("src", "var")], MediumLevelILOperation.MLIL_ADDRESS_OF: MediumLevelILAddressOf, # [("src", "var")], MediumLevelILOperation.MLIL_CONST: MediumLevelILConst, # [("constant", "int")], - MediumLevelILOperation.MLIL_CONST_DATA: MediumLevelILConstData, # [("constant", "int")], MediumLevelILOperation.MLIL_CONST_PTR: MediumLevelILConstPtr, # [("constant", "int")], MediumLevelILOperation.MLIL_FLOAT_CONST: MediumLevelILFloatConst, # [("constant", "float")], MediumLevelILOperation.MLIL_IMPORT: MediumLevelILImport, # [("constant", "int")], + MediumLevelILOperation.MLIL_CONST_DATA: MediumLevelILConstData, # [("constant_data", "constant_data")], MediumLevelILOperation.MLIL_SET_VAR: MediumLevelILSetVar, # [("dest", "var"), ("src", "expr")], MediumLevelILOperation.MLIL_LOAD_STRUCT: MediumLevelILLoadStruct, # [("src", "expr"), ("offset", "int")], MediumLevelILOperation.MLIL_STORE: MediumLevelILStore, # [("dest", "expr"), ("src", "expr")], diff --git a/python/variable.py b/python/variable.py index ee0d93a4..1cd703c9 100644 --- a/python/variable.py +++ b/python/variable.py @@ -25,6 +25,7 @@ from dataclasses import dataclass import binaryninja from . import _binaryninjacore as core +from . import databuffer from . import decorators from .enums import RegisterValueType, VariableSourceType, DeadStoreElimination, FunctionGraphType @@ -49,12 +50,14 @@ class RegisterValue: offset: int type: RegisterValueType = RegisterValueType.UndeterminedValue confidence: int = core.max_confidence + size: int = 0 def _to_core_struct(self) -> core.BNRegisterValue: result = core.BNRegisterValue() result.state = self.type result.value = self.value result.offset = self.offset + result.size = self.size return result def _to_core_struct_with_confidence(self): @@ -107,6 +110,8 @@ class RegisterValue: return ReturnAddressRegisterValue(reg_value.value, confidence=confidence) elif reg_value.state == RegisterValueType.ExternalPointerValue: return ExternalPointerRegisterValue(reg_value.value, reg_value.offset, confidence=confidence) + elif reg_value.state & RegisterValueType.ConstantDataValue == RegisterValueType.ConstantDataValue: + return ConstantDataRegisterValue(reg_value.value, 0, reg_value.state, confidence=confidence, size=reg_value.size) assert False, f"RegisterValueType {reg_value.state} not handled" @@ -186,6 +191,41 @@ class ExternalPointerRegisterValue(RegisterValue): return f"<external {self.value:#x} + offset {self.offset:#x}>" +@dataclass(frozen=True, eq=False) +class ConstantDataRegisterValue(RegisterValue): + + def __repr__(self): + if self.type == RegisterValueType.ConstantDataZeroExtendValue: + return f"<const data {{zx.{self.size}({self.value:#x})}}>" + if self.type == RegisterValueType.ConstantDataSignExtendValue: + return f"<const data {{sx.{self.size}({self.value:#x})}}>" + if self.type == RegisterValueType.ConstantDataAggregateValue: + return f"<const data {{aggregate.{self.size}}} @ {self.value:#x}>" + return f"<const data {{invalid}} {self.type} {self.value:#x}>" + + +@dataclass(frozen=True, eq=False) +class ConstantData(RegisterValue): + function: '_function.Function' = None + + def __repr__(self): + if self.type == RegisterValueType.ConstantDataZeroExtendValue: + return f"<const data {{zx.{self.size}({self.value:#x})}}>" + if self.type == RegisterValueType.ConstantDataSignExtendValue: + return f"<const data {{sx.{self.size}({self.value:#x})}}>" + if self.type == RegisterValueType.ConstantDataAggregateValue: + return f"<const data {{aggregate.{self.size}}} @ {self.value:#x}>" + return f"<const data {{invalid}} {self.type} {self.value:#x}>" + + @property + def data(self) -> databuffer.DataBuffer: + if self.size <= 8: + raise ValueError(f"Invalid ConstantData with size: {self.size}") + if self.function is None: + raise ValueError(f"ConstantData requires a Function instance: {self.size}") + return self.function.get_constant_data(self.type, self.value, self.size) + + @dataclass(frozen=True) class ValueRange: start: int @@ -226,6 +266,9 @@ class PossibleValueSet: self._value = value.value elif value.state == RegisterValueType.StackFrameOffset: self._offset = value.value + elif value.state & RegisterValueType.ConstantDataValue == RegisterValueType.ConstantDataValue: + self._value = value.value + self._size = value.size elif value.state == RegisterValueType.SignedRangeValue: self._offset = value.value self._ranges = [] @@ -270,6 +313,12 @@ class PossibleValueSet: return f"<const ptr {self.value:#x}>" if self._type == RegisterValueType.StackFrameOffset: return f"<stack frame offset {self._offset:#x}>" + if self._type == RegisterValueType.ConstantDataZeroExtendValue: + return f"<const data {{zx.{self._size}({self.value:#x})}}>" + if self._type == RegisterValueType.ConstantDataSignExtendValue: + return f"<const data {{sx.{self._size}({self.value:#x})}}>" + if self._type == RegisterValueType.ConstantDataAggregateValue: + return f"<const data {{aggregate.{self._size}}} @ {self.value:#x}>" if self._type == RegisterValueType.SignedRangeValue: return f"<signed ranges: {repr(self.ranges)}>" if self._type == RegisterValueType.UnsignedRangeValue: @@ -317,6 +366,8 @@ class PossibleValueSet: return self.value == other.value elif self.type == RegisterValueType.StackFrameOffset: return self.offset == other.offset + elif self.type & RegisterValueType.ConstantDataValue == RegisterValueType.ConstantDataValue: + return self.value == other.value and self._size == other._size elif self.type in [RegisterValueType.SignedRangeValue, RegisterValueType.UnsignedRangeValue]: return self.ranges == other.ranges elif self.type in [RegisterValueType.InSetOfValues, RegisterValueType.NotInSetOfValues]: @@ -342,6 +393,9 @@ class PossibleValueSet: result.value = self.value elif self.type == RegisterValueType.StackFrameOffset: result.offset = self.value + elif self.type & RegisterValueType.ConstantDataValue == RegisterValueType.ConstantDataValue: + result.value = self.value + result.size = self.size elif self.type == RegisterValueType.SignedRangeValue: result.offset = self.value result.ranges = (core.BNValueRange * self.count)() @@ -406,6 +460,10 @@ class PossibleValueSet: return self._offset @property + def size(self) -> int: + return self._size + + @property def ranges(self) -> List[ValueRange]: return self._ranges |
