diff options
| author | Brian Potchik <brian@vector35.com> | 2023-02-04 15:23:52 -0500 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2023-02-04 15:23:52 -0500 |
| commit | 1a7d06b3b8044ccdee4e3ff0883a33bf8cce487f (patch) | |
| tree | 6779d6b368acfcad57474e0fd12c1ae4158f5c38 | |
| parent | 4005984260466439560545040850557922003325 (diff) | |
Initial support for constant data expressions.
| -rw-r--r-- | binaryninjaapi.h | 28 | ||||
| -rw-r--r-- | binaryninjacore.h | 19 | ||||
| -rw-r--r-- | binaryview.cpp | 6 | ||||
| -rw-r--r-- | function.cpp | 56 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 78 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 29 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 42 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 30 | ||||
| -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 |
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 |
