summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2023-02-04 15:23:52 -0500
committerBrian Potchik <brian@vector35.com>2023-02-04 15:23:52 -0500
commit1a7d06b3b8044ccdee4e3ff0883a33bf8cce487f (patch)
tree6779d6b368acfcad57474e0fd12c1ae4158f5c38
parent4005984260466439560545040850557922003325 (diff)
Initial support for constant data expressions.
-rw-r--r--binaryninjaapi.h28
-rw-r--r--binaryninjacore.h19
-rw-r--r--binaryview.cpp6
-rw-r--r--function.cpp56
-rw-r--r--highlevelilinstruction.cpp78
-rw-r--r--highlevelilinstruction.h29
-rw-r--r--mediumlevelilinstruction.cpp42
-rw-r--r--mediumlevelilinstruction.h30
-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
13 files changed, 331 insertions, 86 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 59b41e63..5be1d760 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -4379,13 +4379,6 @@ namespace BinaryNinja {
*/
size_t GetInstructionLength(Architecture* arch, uint64_t addr);
- /*! Get the constant data at an address. Temporary API for debug only.
-
- \param[in] addr Address of the constant data
- \return DataBuffer containing the constant data
- */
- DataBuffer GetConstantData(uint64_t addr);
-
/*! Get the string at an address
\param[in] addr Address of the string
@@ -8367,6 +8360,7 @@ namespace BinaryNinja {
BNRegisterValueType state;
int64_t value;
int64_t offset;
+ size_t size;
RegisterValue();
@@ -8376,6 +8370,18 @@ namespace BinaryNinja {
BNRegisterValue ToAPIObject();
};
+ struct ConstantData : public BNRegisterValue
+ {
+ Ref<Function> func = nullptr;
+
+ ConstantData();
+ ConstantData(BNRegisterValueType state, uint64_t value);
+ ConstantData(BNRegisterValueType state, uint64_t value, size_t size, Ref<Function> func = nullptr);
+
+ DataBuffer ToDataBuffer() const;
+ RegisterValue ToRegisterValue() const;
+ };
+
/*!
\ingroup function
*/
@@ -8384,6 +8390,7 @@ namespace BinaryNinja {
BNRegisterValueType state;
int64_t value;
int64_t offset;
+ size_t size;
std::vector<BNValueRange> ranges;
std::set<int64_t> valueSet;
std::vector<LookupTableEntry> table;
@@ -8620,6 +8627,9 @@ namespace BinaryNinja {
size_t GetLowLevelILForInstruction(Architecture* arch, uint64_t addr);
std::set<size_t> GetLowLevelILInstructionsForAddress(Architecture* arch, uint64_t addr);
std::vector<size_t> GetLowLevelILExitsForInstruction(Architecture* arch, uint64_t addr);
+
+ DataBuffer GetConstantData(BNRegisterValueType state, uint64_t value, size_t size = 0);
+
RegisterValue GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg);
RegisterValue GetRegisterValueAfterInstruction(Architecture* arch, uint64_t addr, uint32_t reg);
RegisterValue GetStackContentsAtInstruction(Architecture* arch, uint64_t addr, int64_t offset, size_t size);
@@ -10848,7 +10858,6 @@ namespace BinaryNinja {
ExprId AddressOf(const Variable& var, const ILSourceLocation& loc = ILSourceLocation());
ExprId AddressOfField(const Variable& var, uint64_t offset, const ILSourceLocation& loc = ILSourceLocation());
ExprId Const(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
- ExprId ConstData(size_t size, uint64_t addr, const ILSourceLocation& loc = ILSourceLocation());
ExprId ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
ExprId ExternPointer(
size_t size, uint64_t val, uint64_t offset, const ILSourceLocation& loc = ILSourceLocation());
@@ -10856,6 +10865,7 @@ namespace BinaryNinja {
ExprId FloatConstSingle(float val, const ILSourceLocation& loc = ILSourceLocation());
ExprId FloatConstDouble(double val, const ILSourceLocation& loc = ILSourceLocation());
ExprId ImportedAddress(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId ConstData(size_t size, const ConstantData& data, const ILSourceLocation& loc = ILSourceLocation());
ExprId Add(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
ExprId AddWithCarry(
size_t size, ExprId left, ExprId right, ExprId carry, const ILSourceLocation& loc = ILSourceLocation());
@@ -11218,7 +11228,6 @@ namespace BinaryNinja {
const ILSourceLocation& loc = ILSourceLocation());
ExprId AddressOf(ExprId src, const ILSourceLocation& loc = ILSourceLocation());
ExprId Const(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
- ExprId ConstData(size_t size, uint64_t addr, const ILSourceLocation& loc = ILSourceLocation());
ExprId ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
ExprId ExternPointer(
size_t size, uint64_t val, uint64_t offset, const ILSourceLocation& loc = ILSourceLocation());
@@ -11226,6 +11235,7 @@ namespace BinaryNinja {
ExprId FloatConstSingle(float val, const ILSourceLocation& loc = ILSourceLocation());
ExprId FloatConstDouble(double val, const ILSourceLocation& loc = ILSourceLocation());
ExprId ImportedAddress(size_t size, uint64_t val, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId ConstData(size_t size, const ConstantData& data, const ILSourceLocation& loc = ILSourceLocation());
ExprId Add(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
ExprId AddWithCarry(
size_t size, ExprId left, ExprId right, ExprId carry, const ILSourceLocation& loc = ILSourceLocation());
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 3219e63b..52614f41 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -36,14 +36,14 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
-#define BN_CURRENT_CORE_ABI_VERSION 31
+#define BN_CURRENT_CORE_ABI_VERSION 32
// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
// will require rebuilding. The minimum version is increased when there are
// incompatible changes that break binary compatibility, such as changes to
// existing types or functions.
-#define BN_MINIMUM_CORE_ABI_VERSION 31
+#define BN_MINIMUM_CORE_ABI_VERSION 32
#ifdef __GNUC__
#ifdef BINARYNINJACORE_LIBRARY
@@ -944,7 +944,13 @@ extern "C"
UnsignedRangeValue,
LookupTableValue,
InSetOfValues,
- NotInSetOfValues
+ NotInSetOfValues,
+
+ // The following support constant data and values larger than 8 bytes
+ ConstantDataValue = 0x8000,
+ ConstantDataZeroExtendValue = ConstantDataValue | 0x1,
+ ConstantDataSignExtendValue = ConstantDataValue | 0x2,
+ ConstantDataAggregateValue = ConstantDataValue | 0x3
};
enum BNDataFlowQueryOption
@@ -996,6 +1002,7 @@ extern "C"
BNRegisterValueType state;
int64_t value;
int64_t offset;
+ size_t size;
};
struct BNRegisterValueWithConfidence
@@ -1014,6 +1021,7 @@ extern "C"
BNRegisterValueType state;
int64_t value;
int64_t offset;
+ size_t size;
BNValueRange* ranges;
int64_t* valueSet;
BNLookupTableEntry* table;
@@ -3809,6 +3817,9 @@ extern "C"
BINARYNINJACOREAPI BNHighLevelILFunction* BNGetFunctionHighLevelILIfAvailable(BNFunction* func);
BINARYNINJACOREAPI BNLanguageRepresentationFunction* BNGetFunctionLanguageRepresentation(BNFunction* func);
BINARYNINJACOREAPI BNLanguageRepresentationFunction* BNGetFunctionLanguageRepresentationIfAvailable(BNFunction* func);
+
+ BINARYNINJACOREAPI BNDataBuffer* BNGetConstantData(BNFunction* func, BNRegisterValueType state, uint64_t value, size_t size = 0);
+
BINARYNINJACOREAPI BNRegisterValue BNGetRegisterValueAtInstruction(
BNFunction* func, BNArchitecture* arch, uint64_t addr, uint32_t reg);
BINARYNINJACOREAPI BNRegisterValue BNGetRegisterValueAfterInstruction(
@@ -4062,8 +4073,6 @@ extern "C"
BINARYNINJACOREAPI void BNRegisterGlobalFunctionRecognizer(BNFunctionRecognizer* rec);
- BINARYNINJACOREAPI BNDataBuffer* BNGetConstantData(BNBinaryView* view, uint64_t addr);
-
BINARYNINJACOREAPI bool BNGetStringAtAddress(BNBinaryView* view, uint64_t addr, BNStringReference* strRef);
BINARYNINJACOREAPI BNStringReference* BNGetStrings(BNBinaryView* view, size_t* count);
BINARYNINJACOREAPI BNStringReference* BNGetStringsInRange(
diff --git a/binaryview.cpp b/binaryview.cpp
index ef8889ca..84267ba3 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -3160,12 +3160,6 @@ size_t BinaryView::GetInstructionLength(Architecture* arch, uint64_t addr)
}
-DataBuffer BinaryView::GetConstantData(uint64_t addr)
-{
- return DataBuffer(BNGetConstantData(m_object, addr));
-}
-
-
bool BinaryView::GetStringAtAddress(uint64_t addr, BNStringReference& strRef)
{
return BNGetStringAtAddress(m_object, addr, &strRef);
diff --git a/function.cpp b/function.cpp
index 4be60124..581121c2 100644
--- a/function.cpp
+++ b/function.cpp
@@ -101,7 +101,7 @@ Variable Variable::FromIdentifier(uint64_t id)
}
-RegisterValue::RegisterValue() : state(UndeterminedValue), value(0), offset(0) {}
+RegisterValue::RegisterValue() : state(UndeterminedValue), value(0), offset(0), size(0) {}
bool RegisterValue::IsConstant() const
@@ -116,6 +116,50 @@ BNRegisterValue RegisterValue::ToAPIObject()
result.state = state;
result.value = value;
result.offset = offset;
+ result.size = size;
+ return result;
+}
+
+
+ConstantData::ConstantData()
+{
+ state = UndeterminedValue;
+ value = 0;
+ size = 0;
+}
+
+ConstantData::ConstantData(BNRegisterValueType _state, uint64_t _value)
+{
+ state = _state;
+ value = _value;
+ size = 0;
+}
+
+
+ConstantData::ConstantData(BNRegisterValueType _state, uint64_t _value, size_t _size, Ref<Function> _func)
+{
+ state = _state;
+ value = _value;
+ size = _size;
+ func = _func;
+}
+
+
+DataBuffer ConstantData::ToDataBuffer() const
+{
+ if (func)
+ return func->GetConstantData(state, value, size);
+
+ return DataBuffer();
+}
+
+
+RegisterValue ConstantData::ToRegisterValue() const
+{
+ RegisterValue result;
+ result.state = state;
+ result.value = value;
+ result.size = size;
return result;
}
@@ -385,6 +429,8 @@ RegisterValue RegisterValue::FromAPIObject(const BNRegisterValue& value)
RegisterValue result;
result.state = value.state;
result.value = value.value;
+ result.offset = value.offset;
+ result.size = value.size;
return result;
}
@@ -395,6 +441,7 @@ PossibleValueSet PossibleValueSet::FromAPIObject(BNPossibleValueSet& value)
result.state = value.state;
result.value = value.value;
result.offset = value.offset;
+ result.size = value.size;
if (value.state == LookupTableValue)
{
for (size_t i = 0; i < value.count; i++)
@@ -429,6 +476,7 @@ BNPossibleValueSet PossibleValueSet::ToAPIObject()
result.state = state;
result.value = value;
result.offset = offset;
+ result.size = size;
result.count = 0;
if ((state == SignedRangeValue) || (state == UnsignedRangeValue))
@@ -477,6 +525,12 @@ BNPossibleValueSet PossibleValueSet::ToAPIObject()
}
+DataBuffer Function::GetConstantData(BNRegisterValueType state, uint64_t value, size_t size)
+{
+ return DataBuffer(BNGetConstantData(m_object, state, value, size));
+}
+
+
RegisterValue Function::GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg)
{
BNRegisterValue value = BNGetRegisterValueAtInstruction(m_object, arch->GetObject(), addr, reg);
diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp
index e9c2676d..608b2fac 100644
--- a/highlevelilinstruction.cpp
+++ b/highlevelilinstruction.cpp
@@ -38,25 +38,38 @@ using namespace std;
unordered_map<HighLevelILOperandUsage, HighLevelILOperandType> HighLevelILInstructionBase::operandTypeForUsage = {
- {SourceExprHighLevelOperandUsage, ExprHighLevelOperand}, {VariableHighLevelOperandUsage, VariableHighLevelOperand},
+ {SourceExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {VariableHighLevelOperandUsage, VariableHighLevelOperand},
{DestVariableHighLevelOperandUsage, VariableHighLevelOperand},
{SSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand},
{DestSSAVariableHighLevelOperandUsage, SSAVariableHighLevelOperand},
- {DestExprHighLevelOperandUsage, ExprHighLevelOperand}, {LeftExprHighLevelOperandUsage, ExprHighLevelOperand},
- {RightExprHighLevelOperandUsage, ExprHighLevelOperand}, {CarryExprHighLevelOperandUsage, ExprHighLevelOperand},
- {IndexExprHighLevelOperandUsage, ExprHighLevelOperand}, {ConditionExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {DestExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {LeftExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {RightExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {CarryExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {IndexExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {ConditionExprHighLevelOperandUsage, ExprHighLevelOperand},
{ConditionPhiExprHighLevelOperandUsage, ExprHighLevelOperand},
- {TrueExprHighLevelOperandUsage, ExprHighLevelOperand}, {FalseExprHighLevelOperandUsage, ExprHighLevelOperand},
- {LoopExprHighLevelOperandUsage, ExprHighLevelOperand}, {InitExprHighLevelOperandUsage, ExprHighLevelOperand},
- {UpdateExprHighLevelOperandUsage, ExprHighLevelOperand}, {DefaultExprHighLevelOperandUsage, ExprHighLevelOperand},
- {HighExprHighLevelOperandUsage, ExprHighLevelOperand}, {LowExprHighLevelOperandUsage, ExprHighLevelOperand},
- {OffsetHighLevelOperandUsage, IntegerHighLevelOperand}, {MemberIndexHighLevelOperandUsage, IndexHighLevelOperand},
- {ConstantHighLevelOperandUsage, IntegerHighLevelOperand}, {VectorHighLevelOperandUsage, IntegerHighLevelOperand},
- {IntrinsicHighLevelOperandUsage, IntrinsicHighLevelOperand}, {TargetHighLevelOperandUsage, IndexHighLevelOperand},
+ {TrueExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {FalseExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {LoopExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {InitExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {UpdateExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {DefaultExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {HighExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {LowExprHighLevelOperandUsage, ExprHighLevelOperand},
+ {OffsetHighLevelOperandUsage, IntegerHighLevelOperand},
+ {MemberIndexHighLevelOperandUsage, IndexHighLevelOperand},
+ {ConstantHighLevelOperandUsage, IntegerHighLevelOperand},
+ {ConstantDataHighLevelOperandUsage, ConstantDataHighLevelOperand},
+ {VectorHighLevelOperandUsage, IntegerHighLevelOperand},
+ {IntrinsicHighLevelOperandUsage, IntrinsicHighLevelOperand},
+ {TargetHighLevelOperandUsage, IndexHighLevelOperand},
{ParameterExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{SourceExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{DestExprsHighLevelOperandUsage, ExprListHighLevelOperand},
- {BlockExprsHighLevelOperandUsage, ExprListHighLevelOperand}, {CasesHighLevelOperandUsage, ExprListHighLevelOperand},
+ {BlockExprsHighLevelOperandUsage, ExprListHighLevelOperand},
+ {CasesHighLevelOperandUsage, ExprListHighLevelOperand},
{ValueExprsHighLevelOperandUsage, ExprListHighLevelOperand},
{SourceSSAVariablesHighLevelOperandUsage, SSAVariableListHighLevelOperand},
{SourceMemoryVersionHighLevelOperandUsage, IndexHighLevelOperand},
@@ -122,10 +135,10 @@ unordered_map<BNHighLevelILOperation, vector<HighLevelILOperandUsage>>
DestMemoryVersionHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage}},
{HLIL_TRAP, {VectorHighLevelOperandUsage}},
{HLIL_CONST, {ConstantHighLevelOperandUsage}},
- {HLIL_CONST_DATA, {ConstantHighLevelOperandUsage}},
{HLIL_CONST_PTR, {ConstantHighLevelOperandUsage}},
{HLIL_EXTERN_PTR, {ConstantHighLevelOperandUsage, OffsetHighLevelOperandUsage}},
{HLIL_FLOAT_CONST, {ConstantHighLevelOperandUsage}}, {HLIL_IMPORT, {ConstantHighLevelOperandUsage}},
+ {HLIL_CONST_DATA, {ConstantDataHighLevelOperandUsage}},
{HLIL_ADD, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
{HLIL_SUB, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
{HLIL_AND, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}},
@@ -511,6 +524,14 @@ uint64_t HighLevelILOperand::GetInteger() const
}
+ConstantData HighLevelILOperand::GetConstantData() const
+{
+ if (m_type != ConstantDataHighLevelOperand)
+ throw HighLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsConstantData(m_operandIndex);
+}
+
+
size_t HighLevelILOperand::GetIndex() const
{
if (m_type != IndexHighLevelOperand)
@@ -708,6 +729,12 @@ uint64_t HighLevelILInstructionBase::GetRawOperandAsInteger(size_t operand) cons
}
+ConstantData HighLevelILInstructionBase::GetRawOperandAsConstantData(size_t operand) const
+{
+ return ConstantData((BNRegisterValueType)operands[operand], (uint64_t)operands[operand + 1], size, function->GetFunction());
+}
+
+
size_t HighLevelILInstructionBase::GetRawOperandAsIndex(size_t operand) const
{
return (size_t)operands[operand];
@@ -1491,8 +1518,6 @@ ExprId HighLevelILInstruction::CopyTo(
subExprHandler(AsTwoOperandWithCarry().GetCarryExpr()));
case HLIL_CONST:
return dest->Const(size, GetConstant<HLIL_CONST>(), *this);
- case HLIL_CONST_DATA:
- return dest->ConstData(size, GetConstant<HLIL_CONST_DATA>(), *this);
case HLIL_CONST_PTR:
return dest->ConstPointer(size, GetConstant<HLIL_CONST_PTR>(), *this);
case HLIL_EXTERN_PTR:
@@ -1501,6 +1526,8 @@ ExprId HighLevelILInstruction::CopyTo(
return dest->FloatConstRaw(size, GetConstant<HLIL_FLOAT_CONST>(), *this);
case HLIL_IMPORT:
return dest->ImportedAddress(size, GetConstant<HLIL_IMPORT>(), *this);
+ case HLIL_CONST_DATA:
+ return dest->ConstData(size, GetConstantData<HLIL_CONST_DATA>(), *this);
case HLIL_BP:
return dest->Breakpoint(*this);
case HLIL_TRAP:
@@ -2281,6 +2308,15 @@ int64_t HighLevelILInstruction::GetConstant() const
}
+ConstantData HighLevelILInstruction::GetConstantData() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ConstantDataHighLevelOperandUsage, operandIndex))
+ return GetRawOperandAsConstantData(operandIndex);
+ throw HighLevelILInstructionAccessException();
+}
+
+
int64_t HighLevelILInstruction::GetVector() const
{
size_t operandIndex;
@@ -2652,12 +2688,6 @@ ExprId HighLevelILFunction::Const(size_t size, uint64_t val, const ILSourceLocat
}
-ExprId HighLevelILFunction::ConstData(size_t size, uint64_t addr, const ILSourceLocation& loc)
-{
- return AddExprWithLocation(HLIL_CONST_DATA, loc, size, addr);
-}
-
-
ExprId HighLevelILFunction::ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc)
{
return AddExprWithLocation(HLIL_CONST_PTR, loc, size, val);
@@ -2706,6 +2736,12 @@ ExprId HighLevelILFunction::ImportedAddress(size_t size, uint64_t val, const ILS
}
+ExprId HighLevelILFunction::ConstData(size_t size, const ConstantData& data, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_CONST_DATA, loc, size, data.state, data.value);
+}
+
+
ExprId HighLevelILFunction::Add(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
{
return AddExprWithLocation(HLIL_ADD, loc, size, left, right);
diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h
index 7ac97d2d..19303bdc 100644
--- a/highlevelilinstruction.h
+++ b/highlevelilinstruction.h
@@ -48,6 +48,7 @@ namespace BinaryNinja
struct HighLevelILInstruction;
struct HighLevelILConstantInstruction;
+ struct HighLevelILConstantDataInstruction;
struct HighLevelILOneOperandInstruction;
struct HighLevelILTwoOperandInstruction;
struct HighLevelILTwoOperandWithCarryInstruction;
@@ -62,6 +63,7 @@ namespace BinaryNinja
enum HighLevelILOperandType
{
IntegerHighLevelOperand,
+ ConstantDataHighLevelOperand,
IndexHighLevelOperand,
IntrinsicHighLevelOperand,
ExprHighLevelOperand,
@@ -100,6 +102,7 @@ namespace BinaryNinja
OffsetHighLevelOperandUsage,
MemberIndexHighLevelOperandUsage,
ConstantHighLevelOperandUsage,
+ ConstantDataHighLevelOperandUsage,
VectorHighLevelOperandUsage,
IntrinsicHighLevelOperandUsage,
TargetHighLevelOperandUsage,
@@ -336,6 +339,7 @@ namespace BinaryNinja
HighLevelILOperandList GetOperands() const;
uint64_t GetRawOperandAsInteger(size_t operand) const;
+ ConstantData GetRawOperandAsConstantData(size_t operand) const;
size_t GetRawOperandAsIndex(size_t operand) const;
HighLevelILInstruction GetRawOperandAsExpr(size_t operand) const;
Variable GetRawOperandAsVariable(size_t operand) const;
@@ -408,6 +412,10 @@ namespace BinaryNinja
{
return *(const HighLevelILConstantInstruction*)this;
}
+ const HighLevelILConstantDataInstruction& AsConstantData() const
+ {
+ return *(const HighLevelILConstantDataInstruction*)this;
+ }
const HighLevelILOneOperandInstruction& AsOneOperand() const
{
return *(const HighLevelILOneOperandInstruction*)this;
@@ -559,6 +567,11 @@ namespace BinaryNinja
return As<N>().GetConstant();
}
template <BNHighLevelILOperation N>
+ ConstantData GetConstantData() const
+ {
+ return As<N>().GetConstantData();
+ }
+ template <BNHighLevelILOperation N>
int64_t GetVector() const
{
return As<N>().GetVector();
@@ -732,6 +745,7 @@ namespace BinaryNinja
uint64_t GetOffset() const;
size_t GetMemberIndex() const;
int64_t GetConstant() const;
+ ConstantData GetConstantData() const;
int64_t GetVector() const;
uint32_t GetIntrinsic() const;
uint64_t GetTarget() const;
@@ -764,6 +778,7 @@ namespace BinaryNinja
HighLevelILOperandUsage GetUsage() const { return m_usage; }
uint64_t GetInteger() const;
+ ConstantData GetConstantData() const;
size_t GetIndex() const;
uint32_t GetIntrinsic() const;
HighLevelILInstruction GetExpr() const;
@@ -824,6 +839,14 @@ namespace BinaryNinja
/*!
\ingroup highlevelil
*/
+ struct HighLevelILConstantDataInstruction : public HighLevelILInstructionBase
+ {
+ ConstantData GetConstantData() const { return GetRawOperandAsConstantData(0); }
+ };
+
+ /*!
+ \ingroup highlevelil
+ */
struct HighLevelILOneOperandInstruction : public HighLevelILInstructionBase
{
HighLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(0); }
@@ -1169,9 +1192,6 @@ namespace BinaryNinja
struct HighLevelILInstructionAccessor<HLIL_CONST> : public HighLevelILConstantInstruction
{};
template <>
- struct HighLevelILInstructionAccessor<HLIL_CONST_DATA> : public HighLevelILConstantInstruction
- {};
- template <>
struct HighLevelILInstructionAccessor<HLIL_CONST_PTR> : public HighLevelILConstantInstruction
{};
template <>
@@ -1180,6 +1200,9 @@ namespace BinaryNinja
template <>
struct HighLevelILInstructionAccessor<HLIL_IMPORT> : public HighLevelILConstantInstruction
{};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_CONST_DATA> : public HighLevelILConstantDataInstruction
+ {};
template <>
struct HighLevelILInstructionAccessor<HLIL_ADD> : public HighLevelILTwoOperandInstruction
diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp
index acf04de9..f16d160e 100644
--- a/mediumlevelilinstruction.cpp
+++ b/mediumlevelilinstruction.cpp
@@ -55,6 +55,7 @@ unordered_map<MediumLevelILOperandUsage, MediumLevelILOperandType> MediumLevelIL
{LowSSAVariableMediumLevelOperandUsage, VariableMediumLevelOperand},
{OffsetMediumLevelOperandUsage, IntegerMediumLevelOperand},
{ConstantMediumLevelOperandUsage, IntegerMediumLevelOperand},
+ {ConstantDataMediumLevelOperandUsage, ConstantDataMediumLevelOperand},
{VectorMediumLevelOperandUsage, IntegerMediumLevelOperand},
{IntrinsicMediumLevelOperandUsage, IntrinsicMediumLevelOperand},
{TargetMediumLevelOperandUsage, IndexMediumLevelOperand},
@@ -169,10 +170,10 @@ unordered_map<BNMediumLevelILOperation, vector<MediumLevelILOperandUsage>>
{MLIL_VAR_PHI, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariablesMediumLevelOperandUsages}},
{MLIL_MEM_PHI, {DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionsMediumLevelOperandUsage}},
{MLIL_CONST, {ConstantMediumLevelOperandUsage}},
- {MLIL_CONST_DATA, {ConstantMediumLevelOperandUsage}},
{MLIL_CONST_PTR, {ConstantMediumLevelOperandUsage}},
{MLIL_EXTERN_PTR, {ConstantMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}},
{MLIL_FLOAT_CONST, {ConstantMediumLevelOperandUsage}}, {MLIL_IMPORT, {ConstantMediumLevelOperandUsage}},
+ {MLIL_CONST_DATA, {ConstantDataMediumLevelOperandUsage}},
{MLIL_ADD, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
{MLIL_SUB, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
{MLIL_AND, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}},
@@ -732,6 +733,14 @@ uint64_t MediumLevelILOperand::GetInteger() const
}
+ConstantData MediumLevelILOperand::GetConstantData() const
+{
+ if (m_type != ConstantDataMediumLevelOperand)
+ throw MediumLevelILInstructionAccessException();
+ return m_instr.GetRawOperandAsConstantData(m_operandIndex);
+}
+
+
size_t MediumLevelILOperand::GetIndex() const
{
if (m_type != IndexMediumLevelOperand)
@@ -952,6 +961,12 @@ uint64_t MediumLevelILInstructionBase::GetRawOperandAsInteger(size_t operand) co
}
+ConstantData MediumLevelILInstructionBase::GetRawOperandAsConstantData(size_t operand) const
+{
+ return ConstantData((BNRegisterValueType)operands[operand], (uint64_t)operands[operand + 1], size, function->GetFunction());
+}
+
+
size_t MediumLevelILInstructionBase::GetRawOperandAsIndex(size_t operand) const
{
return (size_t)operands[operand];
@@ -1818,8 +1833,6 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
return dest->If(subExprHandler(GetConditionExpr<MLIL_IF>()), *labelA, *labelB, *this);
case MLIL_CONST:
return dest->Const(size, GetConstant<MLIL_CONST>(), *this);
- case MLIL_CONST_DATA:
- return dest->ConstData(size, GetConstant<MLIL_CONST_DATA>(), *this);
case MLIL_CONST_PTR:
return dest->ConstPointer(size, GetConstant<MLIL_CONST_PTR>(), *this);
case MLIL_EXTERN_PTR:
@@ -1828,6 +1841,8 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
return dest->FloatConstRaw(size, GetConstant<MLIL_FLOAT_CONST>(), *this);
case MLIL_IMPORT:
return dest->ImportedAddress(size, GetConstant<MLIL_IMPORT>(), *this);
+ case MLIL_CONST_DATA:
+ return dest->ConstData(size, GetConstantData<MLIL_CONST_DATA>(), *this);
case MLIL_BP:
return dest->Breakpoint(*this);
case MLIL_TRAP:
@@ -2025,6 +2040,15 @@ int64_t MediumLevelILInstruction::GetConstant() const
}
+ConstantData MediumLevelILInstruction::GetConstantData() const
+{
+ size_t operandIndex;
+ if (GetOperandIndexForUsage(ConstantDataMediumLevelOperandUsage, operandIndex))
+ return GetRawOperandAsConstantData(operandIndex);
+ throw MediumLevelILInstructionAccessException();
+}
+
+
int64_t MediumLevelILInstruction::GetVector() const
{
size_t operandIndex;
@@ -2365,12 +2389,6 @@ ExprId MediumLevelILFunction::Const(size_t size, uint64_t val, const ILSourceLoc
}
-ExprId MediumLevelILFunction::ConstData(size_t size, uint64_t addr, const ILSourceLocation& loc)
-{
- return AddExprWithLocation(MLIL_CONST_DATA, loc, size, addr);
-}
-
-
ExprId MediumLevelILFunction::ConstPointer(size_t size, uint64_t val, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_CONST_PTR, loc, size, val);
@@ -2419,6 +2437,12 @@ ExprId MediumLevelILFunction::ImportedAddress(size_t size, uint64_t val, const I
}
+ExprId MediumLevelILFunction::ConstData(size_t size, const ConstantData& data, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CONST_DATA, loc, size, data.state, data.value);
+}
+
+
ExprId MediumLevelILFunction::Add(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc)
{
return AddExprWithLocation(MLIL_ADD, loc, size, left, right);
diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h
index 43047fa3..90d2700c 100644
--- a/mediumlevelilinstruction.h
+++ b/mediumlevelilinstruction.h
@@ -24,6 +24,7 @@
#include <unordered_map>
#include <vector>
#ifdef BINARYNINJACORE_LIBRARY
+ #include "constantdata.h"
#include "variable.h"
#else
#include "binaryninjaapi.h"
@@ -43,6 +44,7 @@ namespace BinaryNinja
struct MediumLevelILInstruction;
struct MediumLevelILConstantInstruction;
+ struct MediumLevelILConstantDataInstruction;
struct MediumLevelILOneOperandInstruction;
struct MediumLevelILTwoOperandInstruction;
struct MediumLevelILTwoOperandWithCarryInstruction;
@@ -76,6 +78,7 @@ namespace BinaryNinja
enum MediumLevelILOperandType
{
IntegerMediumLevelOperand,
+ ConstantDataMediumLevelOperand,
IndexMediumLevelOperand,
IntrinsicMediumLevelOperand,
ExprMediumLevelOperand,
@@ -111,6 +114,7 @@ namespace BinaryNinja
LowSSAVariableMediumLevelOperandUsage,
OffsetMediumLevelOperandUsage,
ConstantMediumLevelOperandUsage,
+ ConstantDataMediumLevelOperandUsage,
VectorMediumLevelOperandUsage,
IntrinsicMediumLevelOperandUsage,
TargetMediumLevelOperandUsage,
@@ -443,6 +447,7 @@ namespace BinaryNinja
MediumLevelILOperandList GetOperands() const;
uint64_t GetRawOperandAsInteger(size_t operand) const;
+ ConstantData GetRawOperandAsConstantData(size_t operand) const;
size_t GetRawOperandAsIndex(size_t operand) const;
MediumLevelILInstruction GetRawOperandAsExpr(size_t operand) const;
Variable GetRawOperandAsVariable(size_t operand) const;
@@ -538,6 +543,10 @@ namespace BinaryNinja
{
return *(const MediumLevelILConstantInstruction*)this;
}
+ const MediumLevelILConstantDataInstruction& AsConstantData() const
+ {
+ return *(const MediumLevelILConstantDataInstruction*)this;
+ }
const MediumLevelILOneOperandInstruction& AsOneOperand() const
{
return *(const MediumLevelILOneOperandInstruction*)this;
@@ -655,6 +664,11 @@ namespace BinaryNinja
return As<N>().GetConstant();
}
template <BNMediumLevelILOperation N>
+ ConstantData GetConstantData() const
+ {
+ return As<N>().GetConstantData();
+ }
+ template <BNMediumLevelILOperation N>
int64_t GetVector() const
{
return As<N>().GetVector();
@@ -817,6 +831,7 @@ namespace BinaryNinja
SSAVariable GetLowSSAVariable() const;
uint64_t GetOffset() const;
int64_t GetConstant() const;
+ ConstantData GetConstantData() const;
int64_t GetVector() const;
uint32_t GetIntrinsic() const;
size_t GetTarget() const;
@@ -853,6 +868,7 @@ namespace BinaryNinja
MediumLevelILOperandUsage GetUsage() const { return m_usage; }
uint64_t GetInteger() const;
+ ConstantData GetConstantData() const;
size_t GetIndex() const;
uint32_t GetIntrinsic() const;
MediumLevelILInstruction GetExpr() const;
@@ -915,6 +931,14 @@ namespace BinaryNinja
/*!
\ingroup mediumlevelil
*/
+ struct MediumLevelILConstantDataInstruction : public MediumLevelILInstructionBase
+ {
+ ConstantData GetConstantData() const { return GetRawOperandAsConstantData(0); }
+ };
+
+ /*!
+ \ingroup mediumlevelil
+ */
struct MediumLevelILOneOperandInstruction : public MediumLevelILInstructionBase
{
MediumLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(0); }
@@ -1455,9 +1479,6 @@ namespace BinaryNinja
struct MediumLevelILInstructionAccessor<MLIL_CONST> : public MediumLevelILConstantInstruction
{};
template <>
- struct MediumLevelILInstructionAccessor<MLIL_CONST_DATA> : public MediumLevelILConstantInstruction
- {};
- template <>
struct MediumLevelILInstructionAccessor<MLIL_CONST_PTR> : public MediumLevelILConstantInstruction
{};
template <>
@@ -1466,6 +1487,9 @@ namespace BinaryNinja
template <>
struct MediumLevelILInstructionAccessor<MLIL_IMPORT> : public MediumLevelILConstantInstruction
{};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_CONST_DATA> : public MediumLevelILConstantDataInstruction
+ {};
template <>
struct MediumLevelILInstructionAccessor<MLIL_ADD> : public MediumLevelILTwoOperandInstruction
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