diff options
Diffstat (limited to 'plugins/warp/api/warp.h')
| -rw-r--r-- | plugins/warp/api/warp.h | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/plugins/warp/api/warp.h b/plugins/warp/api/warp.h new file mode 100644 index 00000000..b57a0c7b --- /dev/null +++ b/plugins/warp/api/warp.h @@ -0,0 +1,378 @@ +#pragma once + +#include <binaryninjaapi.h> +#include "warpcore.h" + +template<class T, T *(*AddObjectReference)(T *), void (*FreeObjectReference)(T *)> +class WarpRefCountObject +{ + void AddRefInternal() { m_refs.fetch_add(1); } + + void ReleaseInternal() + { + if (m_refs.fetch_sub(1) == 1) + { + if (!m_registeredRef) + delete this; + } + } + +public: + std::atomic<int> m_refs; + bool m_registeredRef = false; + T *m_object; + + WarpRefCountObject() : m_refs(0), m_object(nullptr) + { + } + + virtual ~WarpRefCountObject() = default; + + T *GetObject() const { return m_object; } + + static T *GetObject(WarpRefCountObject *obj) + { + if (!obj) + return nullptr; + return obj->GetObject(); + } + + void AddRef() + { + if (m_object && (m_refs != 0)) + AddObjectReference(m_object); + AddRefInternal(); + } + + void Release() + { + if (m_object) + FreeObjectReference(m_object); + ReleaseInternal(); + } + + void AddRefForRegistration() { m_registeredRef = true; } + + void ReleaseForRegistration() + { + m_object = nullptr; + m_registeredRef = false; + if (m_refs == 0) + delete this; + } +}; + +namespace Warp { + template<class T> + class Ref + { + T *m_obj; +#ifdef BN_REF_COUNT_DEBUG + void* m_assignmentTrace = nullptr; +#endif + + public: + Ref() : m_obj(NULL) + { + } + + Ref(T *obj) : m_obj(obj) + { + if (m_obj) + { + m_obj->AddRef(); +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + } + } + + Ref(const Ref &obj) : m_obj(obj.m_obj) + { + if (m_obj) + { + m_obj->AddRef(); +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + } + } + + Ref(Ref &&other) : m_obj(other.m_obj) + { + other.m_obj = 0; +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = other.m_assignmentTrace; +#endif + } + + ~Ref() + { + if (m_obj) + { + m_obj->Release(); +#ifdef BN_REF_COUNT_DEBUG + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); +#endif + } + } + + Ref<T> &operator=(const Ref<T> &obj) + { +#ifdef BN_REF_COUNT_DEBUG + if (m_obj) + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); + if (obj.m_obj) + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + T *oldObj = m_obj; + m_obj = obj.m_obj; + if (m_obj) + m_obj->AddRef(); + if (oldObj) + oldObj->Release(); + return *this; + } + + Ref<T> &operator=(Ref<T> &&other) + { + if (m_obj) + { +#ifdef BN_REF_COUNT_DEBUG + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); +#endif + m_obj->Release(); + } + m_obj = other.m_obj; + other.m_obj = 0; +#ifdef BN_REF_COUNT_DEBUG + m_assignmentTrace = other.m_assignmentTrace; +#endif + return *this; + } + + Ref<T> &operator=(T *obj) + { +#ifdef BN_REF_COUNT_DEBUG + if (m_obj) + BNUnregisterObjectRefDebugTrace(typeid(T).name(), m_assignmentTrace); + if (obj) + m_assignmentTrace = BNRegisterObjectRefDebugTrace(typeid(T).name()); +#endif + T *oldObj = m_obj; + m_obj = obj; + if (m_obj) + m_obj->AddRef(); + if (oldObj) + oldObj->Release(); + return *this; + } + + operator T *() const + { + return m_obj; + } + + T *operator->() const + { + return m_obj; + } + + T &operator*() const + { + return *m_obj; + } + + bool operator!() const + { + return m_obj == NULL; + } + + 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; + } + }; + + class WarpUUID + { + BNWARPUUID uuid; + + public: + WarpUUID() = default; + + WarpUUID(BNWARPUUID uuid) : uuid(uuid) {} + + std::string ToString() const; + + bool operator==(const WarpUUID &other) const + { + return BNWARPUUIDEqual(&uuid, &other.uuid); + } + + bool operator!=(const WarpUUID &other) const + { + return !(*this == other); + } + + BNWARPUUID* RawMut() + { + return &uuid; + } + + const BNWARPUUID* Raw() const + { + return &uuid; + } + }; + + typedef WarpUUID Source; + typedef WarpUUID BasicBlockGUID; + typedef WarpUUID FunctionGUID; + typedef WarpUUID ConstraintGUID; + typedef WarpUUID TypeGUID; + + class Target : public WarpRefCountObject<BNWARPTarget, BNWARPNewTargetReference, + BNWARPFreeTargetReference> + { + public: + explicit Target(BNWARPTarget *target); + + static Ref<Target> FromPlatform(const BinaryNinja::Platform& platform); + }; + + struct Constraint + { + ConstraintGUID guid; + std::optional<int64_t> offset; + + Constraint(ConstraintGUID guid, std::optional<int64_t> offset); + + static Constraint FromAPIObject(BNWARPConstraint* constraint); + }; + + struct FunctionComment + { + std::string text; + int64_t offset; + + FunctionComment(std::string text, int64_t offset); + + static FunctionComment FromAPIObject(BNWARPFunctionComment* comment); + }; + + class Function : public WarpRefCountObject<BNWARPFunction, BNWARPNewFunctionReference, BNWARPFreeFunctionReference> + { + public: + explicit Function(BNWARPFunction *function); + + bool operator==(const Function &other) const + { + return BNWARPFunctionsEqual(m_object, other.m_object); + } + + FunctionGUID GetGUID() const; + + std::string GetSymbolName() const; + + BinaryNinja::Ref<BinaryNinja::Symbol> GetSymbol(const BinaryNinja::Function &function) const; + + BinaryNinja::Ref<BinaryNinja::Type> GetType(const BinaryNinja::Function &function) const; + + std::vector<Constraint> GetConstraints() const; + + std::vector<FunctionComment> GetComments() const; + + static Ref<Function> Get(const BinaryNinja::Function &function); + + static Ref<Function> GetMatched(const BinaryNinja::Function &function); + + void Apply(const BinaryNinja::Function &function) const; + + static void RemoveMatch(const BinaryNinja::Function &function); + }; + + class Container : public WarpRefCountObject<BNWARPContainer, BNWARPNewContainerReference, + BNWARPFreeContainerReference> + { + public: + explicit Container(BNWARPContainer *container); + + /// Retrieve all available containers. + static std::vector<Ref<Container> > All(); + + std::string GetName() const; + + std::vector<Source> GetSources() const; + + std::optional<Source> AddSource(const std::string &sourcePath) const; + + bool CommitSource(const Source &source) const; + + bool IsSourceUncommitted(const Source &source) const; + + bool IsSourceWritable(const Source &source) const; + + std::optional<std::string> SourcePath(const Source &source) const; + + bool AddFunctions(const Target &target, const Source &source, const std::vector<Ref<Function> > &functions) const; + + bool AddTypes(const BinaryNinja::BinaryView &view, const Source &source, + const std::vector<BinaryNinja::Ref<BinaryNinja::Type> > &types) const; + + bool RemoveFunctions(const Target &target, const Source &source, const std::vector<Ref<Function> > &functions) const; + + bool RemoveTypes(const Source &source, const std::vector<TypeGUID> &guids) const; + + std::vector<Source> GetSourcesWithFunctionGUID(const Target& target, const FunctionGUID &guid) const; + + std::vector<Source> GetSourcesWithTypeGUID(const TypeGUID &guid) const; + + std::vector<Ref<Function> > GetFunctionsWithGUID(const Target& target, const Source &source, const FunctionGUID &guid) const; + + BinaryNinja::Ref<BinaryNinja::Type> GetTypeWithGUID(const BinaryNinja::Architecture &arch, const Source &source, + const TypeGUID &guid) const; + + std::vector<TypeGUID> GetTypeGUIDsWithName(const Source &source, const std::string &name) const; + }; + + void RunMatcher(const BinaryNinja::BinaryView& view); + + bool IsInstructionVariant(const BinaryNinja::LowLevelILFunction &function, BinaryNinja::ExprId idx); + + bool IsInstructionBlacklisted(const BinaryNinja::LowLevelILFunction &function, BinaryNinja::ExprId idx); + + std::optional<FunctionGUID> GetAnalysisFunctionGUID(const BinaryNinja::Function &function); + + std::optional<BasicBlockGUID> GetBasicBlockGUID(const BinaryNinja::BasicBlock &basicBlock); +} |
