summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2022-12-20 17:15:03 +0800
committerXusheng <xusheng@vector35.com>2022-12-21 11:42:54 +0800
commit0e5e2fad380cdda9e53294d90f7e0fd90c959280 (patch)
tree54e7d187d8409d8f4fccf9a3e8a0e5e90e962fad
parent74dfc90a4291ff12228288e45bdbfe714869bac3 (diff)
Add support for adding magic values into expression parser
-rw-r--r--binaryninjaapi.h55
-rw-r--r--binaryninjacore.h7
-rw-r--r--binaryview.cpp54
-rw-r--r--python/binaryview.py37
4 files changed, 153 insertions, 0 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 70f7b97e..f3009fd5 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -4909,6 +4909,61 @@ namespace BinaryNinja {
\return The created Logger
*/
Ref<Logger> CreateLogger(const std::string& name);
+
+ /*! Add a magic value to the expression parser
+
+ If the magic value already exists, its value gets updated.
+ The magic value can be used in the expression by a `$` followed by its name, e.g., `$foobar`.
+ It is optionally to include the `$` when calling this function, i.e., calling with `foobar` and `$foobar`
+ has the same effect.
+
+ \param name Name for the magic value to add or update
+ \param value Value for the magic value
+ */
+ void AddExpressionParserMagicValue(const std::string& name, uint64_t value);
+
+ /*! Remove a magic value from the expression parser
+
+ If the magic value gets referenced after removal, an error will occur during the parsing.
+
+ \param name Name for the magic value to remove
+ \param value Value for the magic value
+ */
+ void RemoveExpressionParserMagicValue(const std::string& name);
+
+ /*! Add a list of magic value to the expression parser
+
+ The vector `names` and `values` must have the same size. The ith name in the `names` will correspond to
+ the ith value in the `values`.
+
+ If a magic value already exists, its value gets updated.
+ The magic value can be used in the expression by a `$` followed by its name, e.g., `$foobar`.
+ It is optionally to include the `$` when calling this function, i.e., calling with `foobar` and `$foobar`
+ has the same effect.
+
+ \param name Name for the magic values to add or update
+ \param value Values for the magic value
+ */
+ void AddExpressionParserMagicValues(const std::vector<std::string>& names, const std::vector<uint64_t>& values);
+
+ /*! Remove a list of magic value from the expression parser
+
+ If any of the magic values gets referenced after removal, an error will occur during the parsing.
+
+ \param name Names for the magic value to remove
+ */
+ void RemoveExpressionParserMagicValues(const std::vector<std::string>& names);
+
+ /*! Get the value of an expression parser magic value
+
+ If the quried magic value exists, the function returns true and the magic value is returned in `value`.
+ If the quried magic value does not exist, the function returns false.
+
+ \param[in] name Name for the magic value to query
+ \param[out] value Value for the magic value
+ \return Whether the magic value exists
+ */
+ bool GetExpressionParserMagicValue(const std::string& name, uint64_t* value);
};
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 58d1e44b..ad71ced9 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -5486,6 +5486,13 @@ extern "C"
BINARYNINJACOREAPI BNTypeWithConfidence BNCreateStructureMemberFromAccess(
BNBinaryView* view, BNQualifiedName* name, uint64_t offset);
+ BINARYNINJACOREAPI void BNAddExpressionParserMagicValue(BNBinaryView* view, const char* name, uint64_t value);
+ BINARYNINJACOREAPI void BNRemoveExpressionParserMagicValue(BNBinaryView* view, const char* name);
+ BINARYNINJACOREAPI void BNAddExpressionParserMagicValues(BNBinaryView* view, const char** names, uint64_t* values,
+ size_t count);
+ BINARYNINJACOREAPI void BNRemoveExpressionParserMagicValues(BNBinaryView* view, const char** names, size_t count);
+ BINARYNINJACOREAPI bool BNGetExpressionParserMagicValue(BNBinaryView* view, const char* name, uint64_t* value);
+
// Source code processing
BINARYNINJACOREAPI bool BNPreprocessSource(const char* source, const char* fileName, char** output, char** errors,
const char** includeDirs, size_t includeDirCount);
diff --git a/binaryview.cpp b/binaryview.cpp
index 1eb96e51..bcdeb724 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -4293,6 +4293,60 @@ Ref<Logger> BinaryView::CreateLogger(const string& name)
}
+void BinaryView::AddExpressionParserMagicValue(const std::string& name, uint64_t value)
+{
+ BNAddExpressionParserMagicValue(m_object, name.c_str(), value);
+}
+
+
+void BinaryView::RemoveExpressionParserMagicValue(const string& name)
+{
+ BNRemoveExpressionParserMagicValue(m_object, name.c_str());
+}
+
+
+void BinaryView::AddExpressionParserMagicValues(const std::vector<std::string>& names, const std::vector<uint64_t>& values)
+{
+ if (names.empty() || values.empty() || (names.size() != values.size()))
+ return;
+
+ const char** namesArray = new const char*[names.size()];
+ auto* valuesArray = new uint64_t[names.size()];
+
+ for (size_t i = 0; i < names.size(); i++)
+ {
+ namesArray[i] = names[i].c_str();
+ valuesArray[i] = values[i];
+ }
+
+ BNAddExpressionParserMagicValues(m_object, namesArray, valuesArray, names.size());
+
+ delete[] namesArray;
+ delete[] valuesArray;
+}
+
+
+bool BinaryView::GetExpressionParserMagicValue(const std::string& name, uint64_t* value)
+{
+ return BNGetExpressionParserMagicValue(m_object, name.c_str(), value);
+}
+
+
+void BinaryView::RemoveExpressionParserMagicValues(const vector<string>& names)
+{
+ if (names.empty())
+ return;
+
+ const char** toRemove = new const char*[names.size()];
+ for (size_t i = 0; i < names.size(); i++)
+ toRemove[i] = names[i].c_str();
+
+ BNRemoveExpressionParserMagicValues(m_object, toRemove, names.size());
+
+ delete[] toRemove;
+}
+
+
Relocation::Relocation(BNRelocation* reloc)
{
m_object = reloc;
diff --git a/python/binaryview.py b/python/binaryview.py
index c744b670..287b4395 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -4740,6 +4740,43 @@ class BinaryView:
return _types.Type.create(core.BNNewTypeReference(result.type), confidence=result.confidence)
+ def add_expression_parser_magic_value(self, name: str, value: int) -> None:
+ core.BNAddExpressionParserMagicValue(self.handle, name, value)
+
+ def remove_expression_parser_magic_value(self, name: str) -> None:
+ core.BNRemoveExpressionParserMagicValue(self.handle, name)
+
+ def add_expression_parser_magic_values(self, names: List[str], values: List[int]) -> None:
+ if len(names) == 0 or len(values) == 0 or (not len(names) == len(values)):
+ return
+
+ names_buf = (ctypes.c_char_p * len(names))()
+ for i in range(0, len(names)):
+ names_buf[i] = names[i].encode('charmap')
+
+ values_buf = (ctypes.c_ulonglong * len(values))()
+ for i in range(0, len(values)):
+ values_buf[i] = values[i]
+
+ core.BNAddExpressionParserMagicValues(self.handle, names_buf, values_buf, len(names))
+
+ def remove_expression_parser_magic_values(self, names: List[str]) -> None:
+ if len(names) == 0:
+ return
+
+ names_buf = (ctypes.c_char_p * len(names))()
+ for i in range(0, len(names)):
+ names_buf[i] = names[i].encode('charmap')
+
+ core.BNRemoveExpressionParserMagicValues(self.handle, names_buf, len(names))
+
+ def get_expression_parser_magic_value(self, name: str) -> Optional[int]:
+ result = ctypes.c_ulonglong()
+ if not core.BNGetExpressionParserMagicValue(self.handle, name, result):
+ return None
+
+ return result.value
+
def get_callers(self, addr: int) -> Generator[ReferenceSource, None, None]:
"""
``get_callers`` returns a list of ReferenceSource objects (xrefs or cross-references) that call the provided virtual address.