diff options
| author | Xusheng <xusheng@vector35.com> | 2022-12-20 17:15:03 +0800 |
|---|---|---|
| committer | Xusheng <xusheng@vector35.com> | 2022-12-21 11:42:54 +0800 |
| commit | 0e5e2fad380cdda9e53294d90f7e0fd90c959280 (patch) | |
| tree | 54e7d187d8409d8f4fccf9a3e8a0e5e90e962fad | |
| parent | 74dfc90a4291ff12228288e45bdbfe714869bac3 (diff) | |
Add support for adding magic values into expression parser
| -rw-r--r-- | binaryninjaapi.h | 55 | ||||
| -rw-r--r-- | binaryninjacore.h | 7 | ||||
| -rw-r--r-- | binaryview.cpp | 54 | ||||
| -rw-r--r-- | python/binaryview.py | 37 |
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. |
