summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/binaryview.py3
-rw-r--r--python/function.py4
-rw-r--r--python/highlevelil.py31
-rw-r--r--python/mediumlevelil.py33
-rw-r--r--python/variable.py58
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