diff options
| author | Brian Potchik <brian@vector35.com> | 2022-11-20 21:35:06 -0500 |
|---|---|---|
| committer | Brian Potchik <brian@vector35.com> | 2022-11-20 21:35:06 -0500 |
| commit | 0763a5064d53a6ec58b7bd40e8c47679d55a81d0 (patch) | |
| tree | bedd36cb2c0c857ab438389c2ac3e0bdb97b7012 | |
| parent | ae69370eb054e2d1679aff0247ad3e217df62a62 (diff) | |
Initial constant expression builtin outliner.
| -rw-r--r-- | binaryninjaapi.h | 11 | ||||
| -rw-r--r-- | binaryninjacore.h | 10 | ||||
| -rw-r--r-- | binaryview.cpp | 6 | ||||
| -rw-r--r-- | databuffer.cpp | 4 | ||||
| -rw-r--r-- | docs/dev/bnil-mlil.md | 3 | ||||
| -rw-r--r-- | examples/mlil_parser/src/mlil_parser.cpp | 1 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 13 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 3 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 12 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 3 | ||||
| -rw-r--r-- | python/binaryview.py | 3 | ||||
| -rw-r--r-- | python/databuffer.py | 4 | ||||
| -rw-r--r-- | python/highlevelil.py | 15 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 15 |
14 files changed, 91 insertions, 12 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index c59b554a..ccf72b0a 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1316,7 +1316,7 @@ namespace BinaryNinja { bool operator==(const DataBuffer& other) const; bool operator!=(const DataBuffer& other) const; - std::string ToEscapedString() const; + std::string ToEscapedString(bool nullTerminates = false) const; static DataBuffer FromEscapedString(const std::string& src); std::string ToBase64() const; static DataBuffer FromBase64(const std::string& src); @@ -4289,6 +4289,13 @@ 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 @@ -9564,6 +9571,7 @@ 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()); @@ -9932,6 +9940,7 @@ 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()); diff --git a/binaryninjacore.h b/binaryninjacore.h index 876ec84e..d5655a09 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 28 +#define BN_CURRENT_CORE_ABI_VERSION 29 // 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 28 +#define BN_MINIMUM_CORE_ABI_VERSION 29 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -1055,6 +1055,7 @@ extern "C" MLIL_ADDRESS_OF, MLIL_ADDRESS_OF_FIELD, MLIL_CONST, + MLIL_CONST_DATA, MLIL_CONST_PTR, MLIL_EXTERN_PTR, MLIL_FLOAT_CONST, @@ -1241,6 +1242,7 @@ extern "C" HLIL_DEREF_FIELD, HLIL_ADDRESS_OF, HLIL_CONST, + HLIL_CONST_DATA, HLIL_CONST_PTR, HLIL_EXTERN_PTR, HLIL_FLOAT_CONST, @@ -3080,7 +3082,7 @@ extern "C" BINARYNINJACOREAPI uint8_t BNGetDataBufferByte(BNDataBuffer* buf, size_t offset); BINARYNINJACOREAPI void BNSetDataBufferByte(BNDataBuffer* buf, size_t offset, uint8_t val); - BINARYNINJACOREAPI char* BNDataBufferToEscapedString(BNDataBuffer* buf); + BINARYNINJACOREAPI char* BNDataBufferToEscapedString(BNDataBuffer* buf, bool nullTerminates); BINARYNINJACOREAPI BNDataBuffer* BNDecodeEscapedString(const char* str); BINARYNINJACOREAPI char* BNDataBufferToBase64(BNDataBuffer* buf); BINARYNINJACOREAPI BNDataBuffer* BNDecodeBase64(const char* str); @@ -4030,6 +4032,8 @@ 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 9459fdd0..f1b5b3b5 100644 --- a/binaryview.cpp +++ b/binaryview.cpp @@ -3128,6 +3128,12 @@ 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/databuffer.cpp b/databuffer.cpp index 1699ebb6..24b20856 100644 --- a/databuffer.cpp +++ b/databuffer.cpp @@ -190,9 +190,9 @@ const uint8_t& DataBuffer::operator[](size_t offset) const } -string DataBuffer::ToEscapedString() const +string DataBuffer::ToEscapedString(bool nullTerminates) const { - char* str = BNDataBufferToEscapedString(m_buffer); + char* str = BNDataBufferToEscapedString(m_buffer, nullTerminates); string result = str; BNFreeString(str); return result; diff --git a/docs/dev/bnil-mlil.md b/docs/dev/bnil-mlil.md index dadd0d01..ee7c1d91 100644 --- a/docs/dev/bnil-mlil.md +++ b/docs/dev/bnil-mlil.md @@ -305,7 +305,7 @@ The parameter list can be accessed through the `params` property: * `MLIL_STORE_STRUCT` - Stores `size` bytes into struct offset `dest` + `offset` from `src` * `MLIL_VAR` - A variable expression `src` * `MLIL_VAR_ALIASED` - A variable expression `src` that is known to have other variables pointing to the same destination -* `MLIL_VAR_ALIASED_FIELD` - +* `MLIL_VAR_ALIASED_FIELD` - * `MLIL_VAR_FIELD` - A variable and offset expression `src`, `offset` * `MLIL_VAR_SPLIT` - A split pair of variables `high`:`low` which can be used a single expression * `MLIL_VAR_PHI` - A `PHI` represents the combination of several prior versions of a variable when differnet basic blocks coalesce into a single destination and it's unknown which path was taken. @@ -313,6 +313,7 @@ The parameter list can be accessed through the `params` property: * `MLIL_ADDRESS_OF` - The address of variable `src` * `MLIL_ADDRESS_OF_FIELD` - The address and `offset` of the variable `src` * `MLIL_CONST` - A constant integral value `constant` +* `MLIL_CONST_DATA` - A constant data reference `constant data reference` * `MLIL_CONST_PTR` - A constant integral value which is used as a pointer `constant` * `MLIL_EXTERN_PTR` - A symbolic pointer `constant` + `offset` to a symbol that exists outside the binary * `MLIL_FLOAT_CONST` - A floating point constant `constant` diff --git a/examples/mlil_parser/src/mlil_parser.cpp b/examples/mlil_parser/src/mlil_parser.cpp index 941b0021..d858b59c 100644 --- a/examples/mlil_parser/src/mlil_parser.cpp +++ b/examples/mlil_parser/src/mlil_parser.cpp @@ -37,6 +37,7 @@ static void PrintOperation(BNMediumLevelILOperation operation) ENUM_PRINTER(MLIL_ADDRESS_OF) ENUM_PRINTER(MLIL_ADDRESS_OF_FIELD) ENUM_PRINTER(MLIL_CONST) + ENUM_PRINTER(MLIL_CONST_DATA) ENUM_PRINTER(MLIL_CONST_PTR) ENUM_PRINTER(MLIL_EXTERN_PTR) ENUM_PRINTER(MLIL_ADD) diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 98c85ea2..0b106d8b 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -120,7 +120,9 @@ unordered_map<BNHighLevelILOperation, vector<HighLevelILOperandUsage>> SourceMemoryVersionHighLevelOperandUsage}}, {HLIL_INTRINSIC_SSA, {IntrinsicHighLevelOperandUsage, ParameterExprsHighLevelOperandUsage, DestMemoryVersionHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage}}, - {HLIL_TRAP, {VectorHighLevelOperandUsage}}, {HLIL_CONST, {ConstantHighLevelOperandUsage}}, + {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}}, @@ -1448,6 +1450,8 @@ 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: @@ -1924,6 +1928,7 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons return false; return AsTwoOperandWithCarry().GetCarryExpr() < other.AsTwoOperandWithCarry().GetCarryExpr(); case HLIL_CONST: + case HLIL_CONST_DATA: case HLIL_CONST_PTR: case HLIL_FLOAT_CONST: case HLIL_IMPORT: @@ -2606,6 +2611,12 @@ 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); diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index fe205b41..13d146ac 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -1166,6 +1166,9 @@ 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 <> diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index 33b2c327..0cdda81e 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -168,7 +168,9 @@ unordered_map<BNMediumLevelILOperation, vector<MediumLevelILOperandUsage>> {MLIL_TRAP, {VectorMediumLevelOperandUsage}}, {MLIL_VAR_PHI, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariablesMediumLevelOperandUsages}}, {MLIL_MEM_PHI, {DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionsMediumLevelOperandUsage}}, - {MLIL_CONST, {ConstantMediumLevelOperandUsage}}, {MLIL_CONST_PTR, {ConstantMediumLevelOperandUsage}}, + {MLIL_CONST, {ConstantMediumLevelOperandUsage}}, + {MLIL_CONST_DATA, {ConstantMediumLevelOperandUsage}}, + {MLIL_CONST_PTR, {ConstantMediumLevelOperandUsage}}, {MLIL_EXTERN_PTR, {ConstantMediumLevelOperandUsage, OffsetMediumLevelOperandUsage}}, {MLIL_FLOAT_CONST, {ConstantMediumLevelOperandUsage}}, {MLIL_IMPORT, {ConstantMediumLevelOperandUsage}}, {MLIL_ADD, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}}, @@ -1775,6 +1777,8 @@ 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: @@ -2320,6 +2324,12 @@ 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); diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index ed57934c..6d86386c 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -1452,6 +1452,9 @@ 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 <> diff --git a/python/binaryview.py b/python/binaryview.py index 9c318f0a..35be7068 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -6047,6 +6047,9 @@ class BinaryView: raise TypeError("Removal is only supported with a Component or string representing its Guid") + def get_constant_data(self, addr: int) -> '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/databuffer.py b/python/databuffer.py index bbcdd37b..44b64ab5 100644 --- a/python/databuffer.py +++ b/python/databuffer.py @@ -143,8 +143,8 @@ class DataBuffer: return False return bytes(self) == bytes(other) - def escape(self) -> str: - return core.BNDataBufferToEscapedString(self.handle) + def escape(self, null_terminates=False) -> str: + return core.BNDataBufferToEscapedString(self.handle, null_terminates) def unescape(self) -> 'DataBuffer': return DataBuffer(handle=core.BNDecodeEscapedString(str(self))) diff --git a/python/highlevelil.py b/python/highlevelil.py index b9bb3e88..1f8c3f84 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -38,6 +38,7 @@ from . import types from . import highlight from . import flowgraph from . import variable +from . import databuffer from .interaction import show_graph_report from .commonil import ( BaseILInstruction, Tailcall, Syscall, Localcall, Comparison, Signed, UnaryOperation, BinaryOperation, SSA, Phi, @@ -54,7 +55,7 @@ OperandsType = Tuple[ExpressionIndex, ExpressionIndex, ExpressionIndex, Expressi HighLevelILOperandType = Union['HighLevelILInstruction', 'lowlevelil.ILIntrinsic', 'variable.Variable', 'mediumlevelil.SSAVariable', List[int], List['variable.Variable'], List['mediumlevelil.SSAVariable'], List['HighLevelILInstruction'], Optional[int], float, - 'GotoLabel'] + 'GotoLabel', databuffer.DataBuffer] VariablesList = List[Union['mediumlevelil.SSAVariable', 'variable.Variable']] StringOrType = Union[str, '_types.Type', '_types.TypeBuilder'] @@ -1402,6 +1403,17 @@ class HighLevelILConst(HighLevelILInstruction, Constant): @dataclass(frozen=True, repr=False, eq=False) +class HighLevelILConstData(HighLevelILInstruction, Constant): + @property + def constant(self) -> '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: @@ -1978,6 +1990,7 @@ 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"), diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 535723f7..6d6077c7 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -36,6 +36,7 @@ from . import flowgraph from . import variable from . import architecture from . import binaryview +from . import databuffer from .interaction import show_graph_report from .commonil import ( BaseILInstruction, Constant, BinaryOperation, UnaryOperation, Comparison, SSA, Phi, FloatingPoint, ControlFlow, @@ -146,6 +147,8 @@ 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: [ @@ -1029,6 +1032,17 @@ class MediumLevelILConst(MediumLevelILConstBase): @dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILConstData(MediumLevelILConstBase): + @property + def constant(self) -> '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: @@ -2488,6 +2502,7 @@ 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")], |
