// Copyright (c) 2015-2026 Vector 35 Inc // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. #pragma once #ifdef BINARYNINJACORE_LIBRARY #include "ilsourcelocation.h" #include "type.h" #else #include "binaryninjaapi.h" #endif #include "base/function_ref.h" #include #include #ifdef BINARYNINJACORE_LIBRARY namespace BinaryNinjaCore #else namespace BinaryNinja #endif { #ifdef BINARYNINJACORE_LIBRARY typedef size_t ExprId; #endif class LowLevelILFunction; template struct LowLevelILInstructionAccessor {}; struct LowLevelILInstruction; struct LowLevelILConstantInstruction; struct LowLevelILOneOperandInstruction; struct LowLevelILTwoOperandInstruction; struct LowLevelILTwoOperandWithCarryInstruction; struct LowLevelILLabel; struct MediumLevelILInstruction; class LowLevelILOperand; class LowLevelILOperandList; /*! \ingroup lowlevelil */ struct RegisterOrFlag { bool isFlag; uint32_t index; RegisterOrFlag(); RegisterOrFlag(bool flag, uint32_t i); RegisterOrFlag(const RegisterOrFlag& v); bool IsRegister() const { return !isFlag; } bool IsFlag() const { return isFlag; } uint32_t GetRegister() const; uint32_t GetFlag() const; RegisterOrFlag& operator=(const RegisterOrFlag& v); bool operator==(const RegisterOrFlag& v) const; bool operator!=(const RegisterOrFlag& v) const; bool operator<(const RegisterOrFlag& v) const; uint64_t ToIdentifier() const; static RegisterOrFlag FromIdentifier(uint64_t id); static RegisterOrFlag Register(uint32_t reg) { return RegisterOrFlag(false, reg); } static RegisterOrFlag Flag(uint32_t flag) { return RegisterOrFlag(true, flag); } }; /*! \ingroup lowlevelil */ struct SSARegister { uint32_t reg; size_t version; SSARegister(); SSARegister(uint32_t r, size_t i); SSARegister(const SSARegister& v); SSARegister& operator=(const SSARegister& v); bool operator==(const SSARegister& v) const; bool operator!=(const SSARegister& v) const; bool operator<(const SSARegister& v) const; }; /*! \ingroup lowlevelil */ struct SSARegisterStack { uint32_t regStack; size_t version; SSARegisterStack(); SSARegisterStack(uint32_t r, size_t i); SSARegisterStack(const SSARegisterStack& v); SSARegisterStack& operator=(const SSARegisterStack& v); bool operator==(const SSARegisterStack& v) const; bool operator!=(const SSARegisterStack& v) const; bool operator<(const SSARegisterStack& v) const; }; /*! \ingroup lowlevelil */ struct SSAFlag { uint32_t flag; size_t version; SSAFlag(); SSAFlag(uint32_t f, size_t i); SSAFlag(const SSAFlag& v); SSAFlag& operator=(const SSAFlag& v); bool operator==(const SSAFlag& v) const; bool operator!=(const SSAFlag& v) const; bool operator<(const SSAFlag& v) const; }; /*! \ingroup lowlevelil */ struct SSARegisterOrFlag { RegisterOrFlag regOrFlag; size_t version; SSARegisterOrFlag(); SSARegisterOrFlag(const RegisterOrFlag& rf, size_t i); SSARegisterOrFlag(const SSARegister& v); SSARegisterOrFlag(const SSAFlag& v); SSARegisterOrFlag(const SSARegisterOrFlag& v); SSARegisterOrFlag& operator=(const SSARegisterOrFlag& v); bool operator==(const SSARegisterOrFlag& v) const; bool operator!=(const SSARegisterOrFlag& v) const; bool operator<(const SSARegisterOrFlag& v) const; }; /*! \ingroup lowlevelil */ enum LowLevelILOperandType : uint8_t { IntegerLowLevelOperand, IndexLowLevelOperand, ExprLowLevelOperand, RegisterLowLevelOperand, RegisterStackLowLevelOperand, FlagLowLevelOperand, FlagConditionLowLevelOperand, IntrinsicLowLevelOperand, SemanticFlagClassLowLevelOperand, SemanticFlagGroupLowLevelOperand, SSARegisterLowLevelOperand, SSARegisterStackLowLevelOperand, SSAFlagLowLevelOperand, IndexListLowLevelOperand, IndexMapLowLevelOperand, ExprListLowLevelOperand, RegisterOrFlagListLowLevelOperand, SSARegisterListLowLevelOperand, SSARegisterStackListLowLevelOperand, SSAFlagListLowLevelOperand, SSARegisterOrFlagListLowLevelOperand, RegisterStackAdjustmentsLowLevelOperand, ConstraintLowLevelOperand, }; /*! \ingroup lowlevelil */ enum LowLevelILOperandUsage : uint8_t { SourceExprLowLevelOperandUsage, SourceRegisterLowLevelOperandUsage, SourceRegisterStackLowLevelOperandUsage, SourceFlagLowLevelOperandUsage, SourceSSARegisterLowLevelOperandUsage, SourceSSARegisterStackLowLevelOperandUsage, SourceSSAFlagLowLevelOperandUsage, DestExprLowLevelOperandUsage, DestRegisterLowLevelOperandUsage, DestRegisterStackLowLevelOperandUsage, DestFlagLowLevelOperandUsage, DestSSARegisterLowLevelOperandUsage, DestSSARegisterStackLowLevelOperandUsage, DestSSAFlagLowLevelOperandUsage, SemanticFlagClassLowLevelOperandUsage, SemanticFlagGroupLowLevelOperandUsage, PartialRegisterLowLevelOperandUsage, PartialSSARegisterStackSourceLowLevelOperandUsage, StackSSARegisterLowLevelOperandUsage, StackMemoryVersionLowLevelOperandUsage, TopSSARegisterLowLevelOperandUsage, LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage, CarryExprLowLevelOperandUsage, ConditionExprLowLevelOperandUsage, HighRegisterLowLevelOperandUsage, HighSSARegisterLowLevelOperandUsage, LowRegisterLowLevelOperandUsage, LowSSARegisterLowLevelOperandUsage, IntrinsicLowLevelOperandUsage, ConstantLowLevelOperandUsage, VectorLowLevelOperandUsage, StackAdjustmentLowLevelOperandUsage, TargetLowLevelOperandUsage, TrueTargetLowLevelOperandUsage, FalseTargetLowLevelOperandUsage, BitIndexLowLevelOperandUsage, SourceMemoryVersionLowLevelOperandUsage, DestMemoryVersionLowLevelOperandUsage, FlagConditionLowLevelOperandUsage, OutputSSARegistersLowLevelOperandUsage, OutputMemoryVersionLowLevelOperandUsage, ParameterExprsLowLevelOperandUsage, SourceSSARegistersLowLevelOperandUsage, SourceSSARegisterStacksLowLevelOperandUsage, SourceSSAFlagsLowLevelOperandUsage, OutputRegisterOrFlagListLowLevelOperandUsage, OutputSSARegisterOrFlagListLowLevelOperandUsage, OutputMemoryIntrinsicLowLevelOperandUsage, SourceMemoryVersionsLowLevelOperandUsage, TargetsLowLevelOperandUsage, RegisterStackAdjustmentsLowLevelOperandUsage, OffsetLowLevelOperandUsage, ConstraintLowLevelOperandUsage, }; } // namespace BinaryNinjaCore namespace std { #ifdef BINARYNINJACORE_LIBRARY template <> struct hash #else template <> struct hash #endif { #ifdef BINARYNINJACORE_LIBRARY typedef BinaryNinjaCore::SSARegister argument_type; #else typedef BinaryNinja::SSARegister argument_type; #endif typedef uint32_t result_type; result_type operator()(argument_type const& value) const { return ((result_type)value.reg) ^ ((result_type)value.version << 16); } }; #ifdef BINARYNINJACORE_LIBRARY template <> struct hash #else template <> struct hash #endif { #ifdef BINARYNINJACORE_LIBRARY typedef BinaryNinjaCore::SSARegisterStack argument_type; #else typedef BinaryNinja::SSARegisterStack argument_type; #endif typedef uint64_t result_type; result_type operator()(argument_type const& value) const { return ((result_type)value.regStack) ^ ((result_type)value.version << 32); } }; #ifdef BINARYNINJACORE_LIBRARY template <> struct hash #else template <> struct hash #endif { #ifdef BINARYNINJACORE_LIBRARY typedef BinaryNinjaCore::SSAFlag argument_type; #else typedef BinaryNinja::SSAFlag argument_type; #endif typedef uint32_t result_type; result_type operator()(argument_type const& value) const { return ((result_type)value.flag) ^ ((result_type)value.version << 16); } }; template <> struct hash { typedef BNLowLevelILOperation argument_type; typedef int result_type; result_type operator()(argument_type const& value) const { return (result_type)value; } }; #ifdef BINARYNINJACORE_LIBRARY template <> struct hash #else template <> struct hash #endif { #ifdef BINARYNINJACORE_LIBRARY typedef BinaryNinjaCore::LowLevelILOperandUsage argument_type; #else typedef BinaryNinja::LowLevelILOperandUsage argument_type; #endif typedef int result_type; result_type operator()(argument_type const& value) const { return (result_type)value; } }; } // namespace std #ifdef BINARYNINJACORE_LIBRARY namespace BinaryNinjaCore #else namespace BinaryNinja #endif { #ifdef BINARYNINJACORE_LIBRARY #define _STD_VECTOR vector #define _STD_SET set #define _STD_UNORDERED_MAP unordered_map #define _STD_MAP map #else #define _STD_VECTOR std::vector #define _STD_SET std::set #define _STD_UNORDERED_MAP std::unordered_map #define _STD_MAP std::map #endif /*! \ingroup lowlevelil */ class LowLevelILInstructionAccessException : public ExceptionWithStackTrace { public: LowLevelILInstructionAccessException() : ExceptionWithStackTrace("invalid access to LLIL instruction") {} }; /*! \ingroup lowlevelil */ class LowLevelILIntegerList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef uint64_t value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; #ifdef BINARYNINJACORE_LIBRARY LowLevelILFunction* function; #else Ref function; #endif size_t offset; size_t count; bool operator==(const ListIterator& a) const; bool operator!=(const ListIterator& a) const; bool operator<(const ListIterator& a) const; ListIterator& operator++(); uint64_t operator*(); LowLevelILFunction* GetFunction() const { return function; } }; ListIterator m_start; public: typedef ListIterator const_iterator; LowLevelILIntegerList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; uint64_t operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILIndexList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef size_t value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; return *this; } size_t operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILIndexList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; size_t operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILIndexMap { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef std::pair value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; ++pos; return *this; } const std::pair operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILIndexMap(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; size_t operator[](uint64_t value) const; operator _STD_MAP() const; }; /*! \ingroup lowlevelil */ class LowLevelILInstructionList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef LowLevelILInstruction value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; size_t instructionIndex; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; return *this; } const LowLevelILInstruction operator*(); }; LowLevelILIntegerList m_list; size_t m_instructionIndex; public: typedef ListIterator const_iterator; LowLevelILInstructionList( LowLevelILFunction* func, size_t offset, size_t count, size_t instrIndex); const_iterator begin() const; const_iterator end() const; size_t size() const; const LowLevelILInstruction operator[](size_t i) const; operator _STD_VECTOR() const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILRegisterOrFlagList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef RegisterOrFlag value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; return *this; } const RegisterOrFlag operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILRegisterOrFlagList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const RegisterOrFlag operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILSSARegisterList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef SSARegister value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; ++pos; return *this; } const SSARegister operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILSSARegisterList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const SSARegister operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILSSARegisterStackList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef SSARegisterStack value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; ++pos; return *this; } const SSARegisterStack operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILSSARegisterStackList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const SSARegisterStack operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILSSAFlagList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef SSAFlag value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; ++pos; return *this; } const SSAFlag operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILSSAFlagList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const SSAFlag operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ class LowLevelILSSARegisterOrFlagList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef SSARegisterOrFlag value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; LowLevelILIntegerList::const_iterator pos; bool operator==(const ListIterator& a) const { return pos == a.pos; } bool operator!=(const ListIterator& a) const { return pos != a.pos; } bool operator<(const ListIterator& a) const { return pos < a.pos; } ListIterator& operator++() { ++pos; ++pos; return *this; } const SSARegisterOrFlag operator*(); }; LowLevelILIntegerList m_list; public: typedef ListIterator const_iterator; LowLevelILSSARegisterOrFlagList(LowLevelILFunction* func, size_t offset, size_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const SSARegisterOrFlag operator[](size_t i) const; operator _STD_VECTOR() const; }; /*! \ingroup lowlevelil */ struct LowLevelILInstructionBase : public BNLowLevelILInstruction { #ifdef BINARYNINJACORE_LIBRARY LowLevelILFunction* function; #else Ref function; #endif size_t exprIndex, instructionIndex; LowLevelILOperandList GetOperands() const; uint64_t GetRawOperandAsInteger(size_t operand) const; uint32_t GetRawOperandAsRegister(size_t operand) const; size_t GetRawOperandAsIndex(size_t operand) const; BNLowLevelILFlagCondition GetRawOperandAsFlagCondition(size_t operand) const; LowLevelILInstruction GetRawOperandAsExpr(size_t operand) const; SSARegister GetRawOperandAsSSARegister(size_t operand) const; SSARegisterStack GetRawOperandAsSSARegisterStack(size_t operand) const; SSARegisterStack GetRawOperandAsPartialSSARegisterStackSource(size_t operand) const; SSAFlag GetRawOperandAsSSAFlag(size_t operand) const; LowLevelILIndexList GetRawOperandAsIndexList(size_t operand) const; LowLevelILIndexMap GetRawOperandAsIndexMap(size_t operand) const; LowLevelILInstructionList GetRawOperandAsExprList(size_t operand) const; LowLevelILRegisterOrFlagList GetRawOperandAsRegisterOrFlagList(size_t operand) const; LowLevelILSSARegisterList GetRawOperandAsSSARegisterList(size_t operand) const; LowLevelILSSARegisterStackList GetRawOperandAsSSARegisterStackList(size_t operand) const; LowLevelILSSAFlagList GetRawOperandAsSSAFlagList(size_t operand) const; LowLevelILSSARegisterOrFlagList GetRawOperandAsSSARegisterOrFlagList(size_t operand) const; _STD_MAP GetRawOperandAsRegisterStackAdjustments(size_t operand) const; PossibleValueSet GetRawOperandAsPossibleValueSet(size_t operand) const; void UpdateRawOperand(size_t operandIndex, ExprId value); void UpdateRawOperandAsSSARegisterList(size_t operandIndex, const _STD_VECTOR& regs); void UpdateRawOperandAsSSARegisterOrFlagList( size_t operandIndex, const _STD_VECTOR& outputs); RegisterValue GetValue() const; PossibleValueSet GetPossibleValues( const _STD_SET& options = _STD_SET()) const; RegisterValue GetRegisterValue(uint32_t reg); RegisterValue GetRegisterValueAfter(uint32_t reg); PossibleValueSet GetPossibleRegisterValues(uint32_t reg); PossibleValueSet GetPossibleRegisterValuesAfter(uint32_t reg); RegisterValue GetFlagValue(uint32_t flag); RegisterValue GetFlagValueAfter(uint32_t flag); PossibleValueSet GetPossibleFlagValues(uint32_t flag); PossibleValueSet GetPossibleFlagValuesAfter(uint32_t flag); RegisterValue GetStackContents(int32_t offset, size_t len); RegisterValue GetStackContentsAfter(int32_t offset, size_t len); PossibleValueSet GetPossibleStackContents(int32_t offset, size_t len); PossibleValueSet GetPossibleStackContentsAfter(int32_t offset, size_t len); size_t GetSSAInstructionIndex() const; size_t GetNonSSAInstructionIndex() const; size_t GetSSAExprIndex() const; size_t GetNonSSAExprIndex() const; LowLevelILInstruction GetSSAForm() const; LowLevelILInstruction GetNonSSAForm() const; size_t GetMediumLevelILInstructionIndex() const; size_t GetMediumLevelILExprIndex() const; size_t GetMappedMediumLevelILInstructionIndex() const; size_t GetMappedMediumLevelILExprIndex() const; bool HasMediumLevelIL() const; bool HasMappedMediumLevelIL() const; MediumLevelILInstruction GetMediumLevelIL() const; MediumLevelILInstruction GetMappedMediumLevelIL() const; // Return (and leak) a string describing the instruction for debugger use char* Dump() const; void Replace(ExprId expr); void SetAttributes(uint32_t attributes); void SetAttribute(BNILInstructionAttribute attribute, bool state = true); void ClearAttribute(BNILInstructionAttribute attribute); template LowLevelILInstructionAccessor& As() { if (operation != N) throw LowLevelILInstructionAccessException(); return *(LowLevelILInstructionAccessor*)this; } LowLevelILOneOperandInstruction& AsOneOperand() { return *(LowLevelILOneOperandInstruction*)this; } LowLevelILTwoOperandInstruction& AsTwoOperand() { return *(LowLevelILTwoOperandInstruction*)this; } LowLevelILTwoOperandWithCarryInstruction& AsTwoOperandWithCarry() { return *(LowLevelILTwoOperandWithCarryInstruction*)this; } template const LowLevelILInstructionAccessor& As() const { if (operation != N) throw LowLevelILInstructionAccessException(); return *(const LowLevelILInstructionAccessor*)this; } const LowLevelILConstantInstruction& AsConstant() const { return *(const LowLevelILConstantInstruction*)this; } const LowLevelILOneOperandInstruction& AsOneOperand() const { return *(const LowLevelILOneOperandInstruction*)this; } const LowLevelILTwoOperandInstruction& AsTwoOperand() const { return *(const LowLevelILTwoOperandInstruction*)this; } const LowLevelILTwoOperandWithCarryInstruction& AsTwoOperandWithCarry() const { return *(const LowLevelILTwoOperandWithCarryInstruction*)this; } }; /*! \ingroup lowlevelil */ struct LowLevelILInstruction : public LowLevelILInstructionBase { LowLevelILInstruction(); LowLevelILInstruction( LowLevelILFunction* func, const BNLowLevelILInstruction& instr, size_t expr, size_t instrIdx); LowLevelILInstruction(const LowLevelILInstructionBase& instr); void VisitExprs(bn::base::function_ref func) const; ExprId CopyTo(LowLevelILFunction* dest, const ILSourceLocation& sourceLocation = {}) const; ExprId CopyTo(LowLevelILFunction* dest, bn::base::function_ref subExprHandler, const ILSourceLocation& sourceLocation = {}) const; // Templated accessors for instruction operands, use these for efficient access to a known instruction template LowLevelILInstruction GetSourceExpr() const { return As().GetSourceExpr(); } template uint32_t GetSourceRegister() const { return As().GetSourceRegister(); } template uint32_t GetSourceRegisterStack() const { return As().GetSourceRegisterStack(); } template uint32_t GetSourceFlag() const { return As().GetSourceFlag(); } template SSARegister GetSourceSSARegister() const { return As().GetSourceSSARegister(); } template SSARegisterStack GetSourceSSARegisterStack() const { return As().GetSourceSSARegisterStack(); } template SSAFlag GetSourceSSAFlag() const { return As().GetSourceSSAFlag(); } template LowLevelILInstruction GetDestExpr() const { return As().GetDestExpr(); } template uint32_t GetDestRegister() const { return As().GetDestRegister(); } template uint32_t GetDestRegisterStack() const { return As().GetDestRegisterStack(); } template uint32_t GetDestFlag() const { return As().GetDestFlag(); } template SSARegister GetDestSSARegister() const { return As().GetDestSSARegister(); } template SSARegisterStack GetDestSSARegisterStack() const { return As().GetDestSSARegisterStack(); } template SSAFlag GetDestSSAFlag() const { return As().GetDestSSAFlag(); } template uint32_t GetSemanticFlagClass() const { return As().GetSemanticFlagClass(); } template uint32_t GetSemanticFlagGroup() const { return As().GetSemanticFlagGroup(); } template uint32_t GetPartialRegister() const { return As().GetPartialRegister(); } template SSARegister GetStackSSARegister() const { return As().GetStackSSARegister(); } template SSARegister GetTopSSARegister() const { return As().GetTopSSARegister(); } template LowLevelILInstruction GetLeftExpr() const { return As().GetLeftExpr(); } template LowLevelILInstruction GetRightExpr() const { return As().GetRightExpr(); } template LowLevelILInstruction GetCarryExpr() const { return As().GetCarryExpr(); } template LowLevelILInstruction GetConditionExpr() const { return As().GetConditionExpr(); } template uint32_t GetHighRegister() const { return As().GetHighRegister(); } template SSARegister GetHighSSARegister() const { return As().GetHighSSARegister(); } template uint32_t GetLowRegister() const { return As().GetLowRegister(); } template SSARegister GetLowSSARegister() const { return As().GetLowSSARegister(); } template uint32_t GetIntrinsic() const { return As().GetIntrinsic(); } template int64_t GetConstant() const { return As().GetConstant(); } template uint64_t GetOffset() const { return As().GetOffset(); } template int64_t GetVector() const { return As().GetVector(); } template int64_t GetStackAdjustment() const { return As().GetStackAdjustment(); } template size_t GetTarget() const { return As().GetTarget(); } template size_t GetTrueTarget() const { return As().GetTrueTarget(); } template size_t GetFalseTarget() const { return As().GetFalseTarget(); } template size_t GetBitIndex() const { return As().GetBitIndex(); } template size_t GetSourceMemoryVersion() const { return As().GetSourceMemoryVersion(); } template size_t GetDestMemoryVersion() const { return As().GetDestMemoryVersion(); } template BNLowLevelILFlagCondition GetFlagCondition() const { return As().GetFlagCondition(); } template LowLevelILSSARegisterList GetOutputSSARegisters() const { return As().GetOutputSSARegisters(); } template LowLevelILInstructionList GetParameterExprs() const { return As().GetParameterExprs(); } template LowLevelILSSARegisterList GetSourceSSARegisters() const { return As().GetSourceSSARegisters(); } template LowLevelILSSARegisterStackList GetSourceSSARegisterStacks() const { return As().GetSourceSSARegisterStacks(); } template LowLevelILSSAFlagList GetSourceSSAFlags() const { return As().GetSourceSSAFlags(); } template LowLevelILRegisterOrFlagList GetOutputRegisterOrFlagList() const { return As().GetOutputRegisterOrFlagList(); } template LowLevelILSSARegisterOrFlagList GetOutputSSARegisterOrFlagList() const { return As().GetOutputSSARegisterOrFlagList(); } template LowLevelILIndexList GetSourceMemoryVersions() const { return As().GetSourceMemoryVersions(); } template LowLevelILIndexMap GetTargets() const { return As().GetTargets(); } template _STD_MAP GetRegisterStackAdjustments() const { return As().GetRegisterStackAdjustments(); } template void SetDestSSAVersion(size_t version) { As().SetDestSSAVersion(version); } template void SetSourceSSAVersion(size_t version) { As().SetSourceSSAVersion(version); } template void SetHighSSAVersion(size_t version) { As().SetHighSSAVersion(version); } template void SetLowSSAVersion(size_t version) { As().SetLowSSAVersion(version); } template void SetStackSSAVersion(size_t version) { As().SetStackSSAVersion(version); } template void SetTopSSAVersion(size_t version) { As().SetTopSSAVersion(version); } template void SetDestMemoryVersion(size_t version) { As().SetDestMemoryVersion(version); } template void SetSourceMemoryVersion(size_t version) { As().SetSourceMemoryVersion(version); } template void SetOutputSSARegisters(const _STD_VECTOR& regs) { As().SetOutputSSARegisters(regs); } template void SetOutputSSARegisterOrFlagList(const _STD_VECTOR& outputs) { As().SetOutputSSARegisterOrFlagList(outputs); } template PossibleValueSet GetConstraint() const { return As().GetConstraint(); } bool GetOperandIndexForUsage(LowLevelILOperandUsage usage, size_t& operandIndex) const; // Generic accessors for instruction operands, these will throw a LowLevelILInstructionAccessException // on type mismatch. These are slower than the templated versions above. LowLevelILInstruction GetSourceExpr() const; uint32_t GetSourceRegister() const; uint32_t GetSourceRegisterStack() const; uint32_t GetSourceFlag() const; SSARegister GetSourceSSARegister() const; SSARegisterStack GetSourceSSARegisterStack() const; SSAFlag GetSourceSSAFlag() const; LowLevelILInstruction GetDestExpr() const; uint32_t GetDestRegister() const; uint32_t GetDestRegisterStack() const; uint32_t GetDestFlag() const; SSARegister GetDestSSARegister() const; SSARegisterStack GetDestSSARegisterStack() const; SSAFlag GetDestSSAFlag() const; uint32_t GetSemanticFlagClass() const; uint32_t GetSemanticFlagGroup() const; uint32_t GetPartialRegister() const; SSARegister GetStackSSARegister() const; SSARegister GetTopSSARegister() const; LowLevelILInstruction GetLeftExpr() const; LowLevelILInstruction GetRightExpr() const; LowLevelILInstruction GetCarryExpr() const; LowLevelILInstruction GetConditionExpr() const; uint32_t GetHighRegister() const; SSARegister GetHighSSARegister() const; uint32_t GetLowRegister() const; SSARegister GetLowSSARegister() const; uint32_t GetIntrinsic() const; int64_t GetConstant() const; uint64_t GetOffset() const; int64_t GetVector() const; int64_t GetStackAdjustment() const; size_t GetTarget() const; size_t GetTrueTarget() const; size_t GetFalseTarget() const; size_t GetBitIndex() const; size_t GetSourceMemoryVersion() const; size_t GetDestMemoryVersion() const; BNLowLevelILFlagCondition GetFlagCondition() const; LowLevelILSSARegisterList GetOutputSSARegisters() const; LowLevelILInstructionList GetParameterExprs() const; LowLevelILSSARegisterList GetSourceSSARegisters() const; LowLevelILSSARegisterStackList GetSourceSSARegisterStacks() const; LowLevelILSSAFlagList GetSourceSSAFlags() const; LowLevelILRegisterOrFlagList GetOutputRegisterOrFlagList() const; LowLevelILSSARegisterOrFlagList GetOutputSSARegisterOrFlagList() const; LowLevelILIndexList GetSourceMemoryVersions() const; LowLevelILIndexMap GetTargets() const; _STD_MAP GetRegisterStackAdjustments() const; }; /*! \ingroup lowlevelil */ class LowLevelILOperand { LowLevelILInstruction m_instr; LowLevelILOperandUsage m_usage; LowLevelILOperandType m_type; size_t m_operandIndex; public: LowLevelILOperand(const LowLevelILInstruction& instr, LowLevelILOperandUsage usage, size_t operandIndex); LowLevelILOperandType GetType() const { return m_type; } LowLevelILOperandUsage GetUsage() const { return m_usage; } uint64_t GetInteger() const; size_t GetIndex() const; LowLevelILInstruction GetExpr() const; uint32_t GetRegister() const; uint32_t GetRegisterStack() const; uint32_t GetFlag() const; uint32_t GetSemanticFlagClass() const; uint32_t GetSemanticFlagGroup() const; uint32_t GetIntrinsic() const; BNLowLevelILFlagCondition GetFlagCondition() const; SSARegister GetSSARegister() const; SSARegisterStack GetSSARegisterStack() const; SSAFlag GetSSAFlag() const; LowLevelILIndexList GetIndexList() const; LowLevelILIndexMap GetIndexMap() const; LowLevelILInstructionList GetExprList() const; LowLevelILSSARegisterList GetSSARegisterList() const; LowLevelILSSARegisterStackList GetSSARegisterStackList() const; LowLevelILSSAFlagList GetSSAFlagList() const; LowLevelILRegisterOrFlagList GetRegisterOrFlagList() const; LowLevelILSSARegisterOrFlagList GetSSARegisterOrFlagList() const; _STD_MAP GetRegisterStackAdjustments() const; }; /*! \ingroup lowlevelil */ class LowLevelILOperandList { struct ListIterator { typedef std::forward_iterator_tag iterator_category; typedef LowLevelILOperand value_type; typedef std::ptrdiff_t difference_type; typedef void pointer; typedef value_type reference; const LowLevelILOperandList* owner; size_t index; constexpr bool operator==(const ListIterator& a) const { return index == a.index; } constexpr auto operator<=>(const ListIterator& a) const { return index <=> a.index; } ListIterator& operator++() { ++index; return *this; } const LowLevelILOperand operator*(); }; LowLevelILInstruction m_instr; const LowLevelILOperandUsage* m_usages; const uint8_t* m_indices; uint8_t m_count; public: typedef ListIterator const_iterator; LowLevelILOperandList(const LowLevelILInstruction& instr, const LowLevelILOperandUsage* usages, const uint8_t* indices, uint8_t count); const_iterator begin() const; const_iterator end() const; size_t size() const; const LowLevelILOperand operator[](size_t i) const; operator _STD_VECTOR() const; }; struct LowLevelILConstantInstruction : public LowLevelILInstructionBase { int64_t GetConstant() const { return GetRawOperandAsInteger(0); } }; struct LowLevelILOffsetInstruction : public LowLevelILInstructionBase { int64_t GetOffset() const { return GetRawOperandAsInteger(1); } }; struct LowLevelILOneOperandInstruction : public LowLevelILInstructionBase { LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(0); } }; struct LowLevelILTwoOperandInstruction : public LowLevelILInstructionBase { LowLevelILInstruction GetLeftExpr() const { return GetRawOperandAsExpr(0); } LowLevelILInstruction GetRightExpr() const { return GetRawOperandAsExpr(1); } }; struct LowLevelILTwoOperandWithCarryInstruction : public LowLevelILInstructionBase { LowLevelILInstruction GetLeftExpr() const { return GetRawOperandAsExpr(0); } LowLevelILInstruction GetRightExpr() const { return GetRawOperandAsExpr(1); } LowLevelILInstruction GetCarryExpr() const { return GetRawOperandAsExpr(2); } }; // Implementations of each instruction to fetch the correct operand value for the valid operands, these // are derived from LowLevelILInstructionBase so that invalid operand accessor functions will generate // a compiler error. template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegister() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetHighRegister() const { return GetRawOperandAsRegister(0); } uint32_t GetLowRegister() const { return GetRawOperandAsRegister(1); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetDestSSARegister() const { return GetRawOperandAsSSARegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetDestSSARegister() const { return GetRawOperandAsSSARegister(0); } uint32_t GetPartialRegister() const { return GetRawOperandAsRegister(2); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(3); } void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetHighSSARegister() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegister(0); } SSARegister GetLowSSARegister() const { return GetRawOperandAsExpr(1).GetRawOperandAsSSARegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } void SetHighSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } void SetLowSSAVersion(size_t version) { GetRawOperandAsExpr(1).UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegisterStack() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegisterStack() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } SSARegister GetTopSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(3); } void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } void SetTopSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } uint32_t GetDestRegister() const { return GetRawOperandAsRegister(1); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegister() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetDestSSARegister() const { return GetRawOperandAsSSARegister(0); } void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } SSARegister GetSourceSSARegister() const { return GetRawOperandAsSSARegister(2); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(3, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceRegister() const { return GetRawOperandAsRegister(0); } PossibleValueSet GetConstraint() const { return GetRawOperandAsPossibleValueSet(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetSourceSSARegister() const { return GetRawOperandAsSSARegister(0); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } PossibleValueSet GetConstraint() const { return GetRawOperandAsPossibleValueSet(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestFlag() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSAFlag GetDestSSAFlag() const { return GetRawOperandAsSSAFlag(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } void SetDestSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(0); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(1); } void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } size_t GetDestMemoryVersion() const { return GetRawOperandAsIndex(1); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(2); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(3); } void SetDestMemoryVersion(size_t version) { UpdateRawOperand(1, version); } void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(2, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceRegister() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetSourceSSARegister() const { return GetRawOperandAsSSARegister(0); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetSourceSSARegister() const { return GetRawOperandAsSSARegister(0); } uint32_t GetPartialRegister() const { return GetRawOperandAsRegister(2); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceRegisterStack() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceRegisterStack() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegister() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetDestRegisterStack() const { return GetRawOperandAsRegister(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsSSARegisterStack(0); } LowLevelILInstruction GetSourceExpr() const { return GetRawOperandAsExpr(2); } SSARegister GetTopSSARegister() const { return GetRawOperandAsExpr(3).GetRawOperandAsSSARegister(0); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } void SetTopSSAVersion(size_t version) { GetRawOperandAsExpr(3).UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsSSARegisterStack(0); } uint32_t GetSourceRegister() const { return GetRawOperandAsRegister(2); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } SSARegister GetTopSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } void SetTopSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterStack(0); } SSARegisterStack GetSourceSSARegisterStack() const { return GetRawOperandAsExpr(0).GetRawOperandAsPartialSSARegisterStackSource(0); } uint32_t GetDestRegister() const { return GetRawOperandAsRegister(1); } void SetDestSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(1, version); } void SetSourceSSAVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(2, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceFlag() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSourceFlag() const { return GetRawOperandAsRegister(0); } size_t GetBitIndex() const { return GetRawOperandAsIndex(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSAFlag GetSourceSSAFlag() const { return GetRawOperandAsSSAFlag(0); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSAFlag GetSourceSSAFlag() const { return GetRawOperandAsSSAFlag(0); } size_t GetBitIndex() const { return GetRawOperandAsIndex(2); } void SetSourceSSAVersion(size_t version) { UpdateRawOperand(1, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetHighRegister() const { return GetRawOperandAsRegister(0); } uint32_t GetLowRegister() const { return GetRawOperandAsRegister(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetHighSSARegister() const { return GetRawOperandAsSSARegister(0); } SSARegister GetLowSSARegister() const { return GetRawOperandAsSSARegister(2); } void SetHighSSAVersion(size_t version) { UpdateRawOperand(1, version); } void SetLowSSAVersion(size_t version) { UpdateRawOperand(3, version); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } LowLevelILIndexMap GetTargets() const { return GetRawOperandAsIndexMap(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } int64_t GetStackAdjustment() const { return GetRawOperandAsInteger(1); } _STD_MAP GetRegisterStackAdjustments() const { return GetRawOperandAsRegisterStackAdjustments(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstruction GetConditionExpr() const { return GetRawOperandAsExpr(0); } size_t GetTrueTarget() const { return GetRawOperandAsIndex(1); } size_t GetFalseTarget() const { return GetRawOperandAsIndex(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { size_t GetTarget() const { return GetRawOperandAsIndex(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { BNLowLevelILFlagCondition GetFlagCondition() const { return GetRawOperandAsFlagCondition(0); } uint32_t GetSemanticFlagClass() const { return GetRawOperandAsRegister(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { uint32_t GetSemanticFlagGroup() const { return GetRawOperandAsRegister(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { int64_t GetVector() const { return GetRawOperandAsInteger(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILSSARegisterList GetOutputSSARegisters() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterList(1); } size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } SSARegister GetStackSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsExpr(2).GetRawOperandAsIndex(2); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0); } void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(2, version); } void SetStackSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } void SetOutputSSARegisters(const _STD_VECTOR& regs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterList(1, regs); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILSSARegisterList GetOutputSSARegisters() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterList(1); } size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } SSARegister GetStackSSARegister() const { return GetRawOperandAsExpr(1).GetRawOperandAsSSARegister(0); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsExpr(1).GetRawOperandAsIndex(2); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(2).GetRawOperandAsExprList(0); } void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(1).UpdateRawOperand(2, version); } void SetStackSSAVersion(size_t version) { GetRawOperandAsExpr(1).UpdateRawOperand(1, version); } void SetOutputSSARegisters(const _STD_VECTOR& regs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterList(1, regs); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILSSARegisterList GetOutputSSARegisters() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterList(1); } size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } LowLevelILInstruction GetDestExpr() const { return GetRawOperandAsExpr(1); } SSARegister GetStackSSARegister() const { return GetRawOperandAsExpr(2).GetRawOperandAsSSARegister(0); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsExpr(2).GetRawOperandAsIndex(2); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0); } void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } void SetSourceMemoryVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(2, version); } void SetStackSSAVersion(size_t version) { GetRawOperandAsExpr(2).UpdateRawOperand(1, version); } void SetOutputSSARegisters(const _STD_VECTOR& regs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterList(1, regs); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILRegisterOrFlagList GetOutputRegisterOrFlagList() const { return GetRawOperandAsRegisterOrFlagList(0); } uint32_t GetIntrinsic() const { return GetRawOperandAsRegister(2); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILSSARegisterOrFlagList GetOutputSSARegisterOrFlagList() const { return GetRawOperandAsSSARegisterOrFlagList(0); } uint32_t GetIntrinsic() const { return GetRawOperandAsRegister(2); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(3).GetRawOperandAsExprList(0); } void SetOutputSSARegisterOrFlagList(const _STD_VECTOR& outputs) { UpdateRawOperandAsSSARegisterOrFlagList(0, outputs); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILSSARegisterOrFlagList GetOutputSSARegisterOrFlagList() const { return GetRawOperandAsExpr(0).GetRawOperandAsSSARegisterOrFlagList(1); } size_t GetDestMemoryVersion() const { return GetRawOperandAsExpr(0).GetRawOperandAsIndex(0); } size_t GetSourceMemoryVersion() const { return GetRawOperandAsIndex(3); } uint32_t GetIntrinsic() const { return GetRawOperandAsRegister(1); } LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExpr(2).GetRawOperandAsExprList(0); } void SetDestMemoryVersion(size_t version) { GetRawOperandAsExpr(0).UpdateRawOperand(0, version); } void SetSourceMemoryVersion(size_t version) { UpdateRawOperand(3, version); } void SetOutputSSARegisterOrFlagList(const _STD_VECTOR& outputs) { GetRawOperandAsExpr(0).UpdateRawOperandAsSSARegisterOrFlagList(1, outputs); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { LowLevelILInstructionList GetParameterExprs() const { return GetRawOperandAsExprList(0); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegister GetDestSSARegister() const { return GetRawOperandAsSSARegister(0); } LowLevelILSSARegisterList GetSourceSSARegisters() const { return GetRawOperandAsSSARegisterList(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSARegisterStack GetDestSSARegisterStack() const { return GetRawOperandAsSSARegisterStack(0); } LowLevelILSSARegisterStackList GetSourceSSARegisterStacks() const { return GetRawOperandAsSSARegisterStackList(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { SSAFlag GetDestSSAFlag() const { return GetRawOperandAsSSAFlag(0); } LowLevelILSSAFlagList GetSourceSSAFlags() const { return GetRawOperandAsSSAFlagList(2); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase { size_t GetDestMemoryVersion() const { return GetRawOperandAsIndex(0); } LowLevelILIndexList GetSourceMemoryVersions() const { return GetRawOperandAsIndexList(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILConstantInstruction { size_t GetConstant() const { return GetRawOperandAsIndex(0); } size_t GetOffset() const { return GetRawOperandAsIndex(1); } }; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILInstructionBase {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILConstantInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILConstantInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILConstantInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandWithCarryInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandWithCarryInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandWithCarryInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILTwoOperandWithCarryInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; template <> struct LowLevelILInstructionAccessor : public LowLevelILOneOperandInstruction {}; #undef _STD_VECTOR #undef _STD_SET #undef _STD_UNORDERED_MAP #undef _STD_MAP } // namespace BinaryNinjaCore #ifdef BINARYNINJACORE_LIBRARY #define IL_INS_NS BinaryNinjaCore #else #define IL_INS_NS BinaryNinja #endif template<> struct fmt::formatter { // -> normal, ? -> debug char presentation = ' '; format_context::iterator format(const IL_INS_NS::LowLevelILInstruction& obj, format_context& ctx) const; constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator { auto it = ctx.begin(), end = ctx.end(); if (it != end && *it == '?') presentation = *it++; if (it != end && *it != '}') report_error("invalid format"); return it; } }; #undef IL_INS_NS