summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Potchik <brian@vector35.com>2022-11-20 21:35:06 -0500
committerBrian Potchik <brian@vector35.com>2022-11-20 21:35:06 -0500
commit0763a5064d53a6ec58b7bd40e8c47679d55a81d0 (patch)
treebedd36cb2c0c857ab438389c2ac3e0bdb97b7012
parentae69370eb054e2d1679aff0247ad3e217df62a62 (diff)
Initial constant expression builtin outliner.
-rw-r--r--binaryninjaapi.h11
-rw-r--r--binaryninjacore.h10
-rw-r--r--binaryview.cpp6
-rw-r--r--databuffer.cpp4
-rw-r--r--docs/dev/bnil-mlil.md3
-rw-r--r--examples/mlil_parser/src/mlil_parser.cpp1
-rw-r--r--highlevelilinstruction.cpp13
-rw-r--r--highlevelilinstruction.h3
-rw-r--r--mediumlevelilinstruction.cpp12
-rw-r--r--mediumlevelilinstruction.h3
-rw-r--r--python/binaryview.py3
-rw-r--r--python/databuffer.py4
-rw-r--r--python/highlevelil.py15
-rw-r--r--python/mediumlevelil.py15
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")],