summaryrefslogtreecommitdiff
path: root/binaryninjaapi.h
diff options
context:
space:
mode:
authorRusty Wagner <rusty.wagner@gmail.com>2023-01-24 18:38:13 -0700
committerRusty Wagner <rusty.wagner@gmail.com>2023-01-30 11:57:43 -0500
commita3939bdec15f9299ae9a681255fa93c47113870a (patch)
tree2b4bb5643ac3cd25a618a99a542968fe81c66bcc /binaryninjaapi.h
parentcf4220570c2d1b7105fb29719383f64026d46837 (diff)
Fix UAF on C++ BinaryView plugin init, improve demangler and BinaryView APIs
Diffstat (limited to 'binaryninjaapi.h')
-rw-r--r--binaryninjaapi.h150
1 files changed, 126 insertions, 24 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 80b9cacd..05a5e1df 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -57,6 +57,40 @@
#endif
namespace BinaryNinja {
+#ifdef __GNUC__
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ static inline uint16_t ToLE16(uint16_t val) { return val; }
+ static inline uint32_t ToLE32(uint32_t val) { return val; }
+ static inline uint64_t ToLE64(uint64_t val) { return val; }
+ static inline uint16_t ToBE16(uint16_t val) { return __builtin_bswap16(val); }
+ static inline uint32_t ToBE32(uint32_t val) { return __builtin_bswap32(val); }
+ static inline uint64_t ToBE64(uint64_t val) { return __builtin_bswap64(val); }
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ static inline uint16_t ToBE16(uint16_t val) { return val; }
+ static inline uint32_t ToBE32(uint32_t val) { return val; }
+ static inline uint64_t ToBE64(uint64_t val) { return val; }
+ static inline uint16_t ToLE16(uint16_t val) { return __builtin_bswap16(val); }
+ static inline uint32_t ToLE32(uint32_t val) { return __builtin_bswap32(val); }
+ static inline uint64_t ToLE64(uint64_t val) { return __builtin_bswap64(val); }
+#endif
+#elif defined(_MSC_VER)
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ static inline uint16_t ToLE16(uint16_t val) { return val; }
+ static inline uint32_t ToLE32(uint32_t val) { return val; }
+ static inline uint64_t ToLE64(uint64_t val) { return val; }
+ static inline uint16_t ToBE16(uint16_t val) { return _byteswap_ushort(val); }
+ static inline uint32_t ToBE32(uint32_t val) { return _byteswap_ulong(val); }
+ static inline uint64_t ToBE64(uint64_t val) { return _byteswap_uint64(val); }
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ static inline uint16_t ToBE16(uint16_t val) { return val; }
+ static inline uint32_t ToBE32(uint32_t val) { return val; }
+ static inline uint64_t ToBE64(uint64_t val) { return val; }
+ static inline uint16_t ToLE16(uint16_t val) { return _byteswap_ushort(val); }
+ static inline uint32_t ToLE32(uint32_t val) { return _byteswap_ulong(val); }
+ static inline uint64_t ToLE64(uint64_t val) { return _byteswap_uint64(val); }
+#endif
+#endif
+
/*!
\ingroup refcount
*/
@@ -145,6 +179,9 @@ namespace BinaryNinja {
if (m_refs == 0)
delete this;
}
+
+ void AddRefForCallback() { AddRefInternal(); }
+ void ReleaseForCallback() { ReleaseInternal(); }
};
/*!
@@ -312,6 +349,28 @@ namespace BinaryNinja {
T* GetPtr() const { return m_obj; }
};
+ /*!
+ \ingroup refcount
+ */
+ template <class T>
+ class CallbackRef
+ {
+ T* m_obj;
+
+ public:
+ CallbackRef<T>(void* obj) : m_obj((T*)obj) { m_obj->AddRefForCallback(); }
+ ~CallbackRef<T>() { m_obj->ReleaseForCallback(); }
+ operator T*() const { return m_obj; }
+ T* operator->() const { return m_obj; }
+ T& operator*() const { return *m_obj; }
+ bool operator==(const T* obj) const { return T::GetObject(m_obj) == T::GetObject(obj); }
+ bool operator==(const Ref<T>& obj) const { return T::GetObject(m_obj) == T::GetObject(obj.m_obj); }
+ bool operator!=(const T* obj) const { return T::GetObject(m_obj) != T::GetObject(obj); }
+ bool operator!=(const Ref<T>& obj) const { return T::GetObject(m_obj) != T::GetObject(obj.m_obj); }
+ bool operator<(const T* obj) const { return T::GetObject(m_obj) < T::GetObject(obj); }
+ bool operator<(const Ref<T>& obj) const { return T::GetObject(m_obj) < T::GetObject(obj.m_obj); }
+ T* GetPtr() const { return m_obj; }
+ };
/*!
\ingroup confidence
@@ -911,59 +970,67 @@ namespace BinaryNinja {
\param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
\param[in] mangledName a mangled Microsoft Visual Studio C++ name
- \param[out] outType Pointer to Type to output
+ \param[out] outType Reference to Type to output
\param[out] outVarName QualifiedName reference to write the output name to.
\param[in] simplify Whether to simplify demangled names.
\ingroup demangle
*/
- bool DemangleMS(Architecture* arch, const std::string& mangledName, Type** outType, QualifiedName& outVarName,
- const bool simplify = false);
+ bool DemangleMS(Architecture* arch, const std::string& mangledName, Ref<Type>& outType, QualifiedName& outVarName,
+ const bool simplify = false);
/*! Demangles a Microsoft Visual Studio C++ name
This overload will use the view's "analysis.types.templateSimplifier" setting
- to determine whether to simplify the mangled name.
+ to determine whether to simplify the mangled name.
- \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
+ \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
\param[in] mangledName a mangled Microsoft Visual Studio C++ name
- \param[out] outType Pointer to Type to output
+ \param[out] outType Reference to Type to output
\param[out] outVarName QualifiedName reference to write the output name to.
\param[in] view View to check the analysis.types.templateSimplifier for
- \ingroup demangle
+ \ingroup demangle
*/
- bool DemangleMS(Architecture* arch, const std::string& mangledName, Type** outType, QualifiedName& outVarName,
- const Ref<BinaryView>& view);
+ bool DemangleMS(Architecture* arch, const std::string& mangledName, Ref<Type>& outType, QualifiedName& outVarName,
+ BinaryView* view);
/*! Demangles a GNU3 name
- \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
+ \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
\param[in] mangledName a mangled GNU3 name
- \param[out] outType Pointer to Type to output
+ \param[out] outType Reference to Type to output
\param[out] outVarName QualifiedName reference to write the output name to.
\param[in] simplify Whether to simplify demangled names.
\ingroup demangle
*/
- bool DemangleGNU3(Ref<Architecture> arch, const std::string& mangledName, Type** outType, QualifiedName& outVarName,
- const bool simplify = false);
+ bool DemangleGNU3(Ref<Architecture> arch, const std::string& mangledName, Ref<Type>& outType,
+ QualifiedName& outVarName, const bool simplify = false);
/*! Demangles a GNU3 name
This overload will use the view's "analysis.types.templateSimplifier" setting
to determine whether to simplify the mangled name.
- \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
+ \param[in] arch Architecture for the symbol. Required for pointer and integer sizes.
\param[in] mangledName a mangled GNU3 name
- \param[out] outType Pointer to Type to output
+ \param[out] outType Reference to Type to output
\param[out] outVarName QualifiedName reference to write the output name to.
\param[in] view View to check the analysis.types.templateSimplifier for
\ingroup demangle
*/
- bool DemangleGNU3(Ref<Architecture> arch, const std::string& mangledName, Type** outType, QualifiedName& outVarName,
- const Ref<BinaryView>& view);
+ bool DemangleGNU3(Ref<Architecture> arch, const std::string& mangledName, Ref<Type>& outType,
+ QualifiedName& outVarName, BinaryView* view);
+
+ /*! Determines if a symbol name is a mangled GNU3 name
+
+ \param[in] mangledName a potentially mangled name
+
+ \ingroup demangle
+ */
+ bool IsGNU3MangledString(const std::string& mangledName);
/*!
\ingroup mainthread
@@ -3458,8 +3525,11 @@ namespace BinaryNinja {
\param platform Platform for the function to be loaded
\param addr Virtual adddress of the function to be loaded
+ \param autoDiscovered true if function was automatically discovered, false if created by user
+ \param type optional function type
*/
- void AddFunctionForAnalysis(Platform* platform, uint64_t addr);
+ Ref<Function> AddFunctionForAnalysis(
+ Platform* platform, uint64_t addr, bool autoDiscovered = false, Type* type = nullptr);
/*! adds an virtual address to start analysis from for a given platform
@@ -3471,8 +3541,9 @@ namespace BinaryNinja {
/*! removes a function from the list of functions
\param func Function to be removed
+ \param updateRefs automatically update other functions that were referenced
*/
- void RemoveAnalysisFunction(Function* func);
+ void RemoveAnalysisFunction(Function* func, bool updateRefs = false);
/*! Add a new user function of the given platform at the virtual address
@@ -5151,14 +5222,14 @@ namespace BinaryNinja {
\param data An existing BinaryView, typically with the \c Raw type
\return The BinaryView created by this BinaryViewType
*/
- virtual BinaryView* Create(BinaryView* data) = 0;
+ virtual Ref<BinaryView> Create(BinaryView* data) = 0;
/*! Create ephemeral BinaryView to generate information for preview
\param data An existing BinaryView, typically with the \c Raw type
\return The BinaryView created by this BinaryViewType
*/
- virtual BinaryView* Parse(BinaryView* data) = 0;
+ virtual Ref<BinaryView> Parse(BinaryView* data);
/*! Check whether this BinaryViewType is valid for given data
@@ -5166,7 +5237,8 @@ namespace BinaryNinja {
\return Whether this BinaryViewType is valid for given data
*/
virtual bool IsTypeValidForData(BinaryView* data) = 0;
- virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) = 0;
+ virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data);
+ Ref<Settings> GetDefaultLoadSettingsForData(BinaryView* data);
static void RegisterBinaryViewFinalizationEvent(const std::function<void(BinaryView* view)>& callback);
static void RegisterBinaryViewInitialAnalysisCompletionEvent(
@@ -5183,9 +5255,10 @@ namespace BinaryNinja {
{
public:
CoreBinaryViewType(BNBinaryViewType* type);
- virtual BinaryView* Create(BinaryView* data) override;
- virtual BinaryView* Parse(BinaryView* data) override;
+ virtual Ref<BinaryView> Create(BinaryView* data) override;
+ virtual Ref<BinaryView> Parse(BinaryView* data) override;
virtual bool IsTypeValidForData(BinaryView* data) override;
+ virtual bool IsDeprecated() override;
virtual Ref<Settings> GetLoadSettingsForData(BinaryView* data) override;
};
@@ -5452,6 +5525,18 @@ namespace BinaryNinja {
*/
void SeekRelative(int64_t offset);
+ /*! Gets the virtual base offset for the stream
+
+ \return The current virtual base
+ */
+ uint64_t GetVirtualBase();
+
+ /*! Sets a virtual base offset for the stream
+
+ \param base The new virtual base
+ */
+ void SetVirtualBase(uint64_t base);
+
/*! Whether the current cursor position is at the end of the file.
*/
@@ -14868,4 +14953,21 @@ namespace BinaryNinja {
void Finalize();
};
+ /*!
+ \ingroup binaryview
+ */
+ class SymbolQueue
+ {
+ BNSymbolQueue* m_object;
+
+ static void ResolveCallback(void* ctxt, BNSymbol** symbol, BNType** type);
+ static void AddCallback(void* ctxt, BNSymbol* symbol, BNType* type);
+
+ public:
+ SymbolQueue();
+ ~SymbolQueue();
+ void Append(const std::function<std::pair<Ref<Symbol>, Ref<Type>>()>& resolve,
+ const std::function<void(Symbol*, Type*)>& add);
+ void Process();
+ };
} // namespace BinaryNinja