summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api.pro22
-rw-r--r--binaryninjaapi.cpp751
-rw-r--r--binaryninjaapi.h381
3 files changed, 1154 insertions, 0 deletions
diff --git a/api.pro b/api.pro
new file mode 100644
index 00000000..6e20687d
--- /dev/null
+++ b/api.pro
@@ -0,0 +1,22 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2015-02-03T19:45:44
+#
+#-------------------------------------------------
+
+QT -= core gui
+
+TARGET = binaryninjaapi
+TEMPLATE = lib
+CONFIG += staticlib
+
+SOURCES += binaryninjaapi.cpp
+
+HEADERS += binaryninjaapi.h
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
+
+INCLUDEPATH += $$PWD/../core
+DEPENDPATH += $$PWD/../core
diff --git a/binaryninjaapi.cpp b/binaryninjaapi.cpp
new file mode 100644
index 00000000..532f4403
--- /dev/null
+++ b/binaryninjaapi.cpp
@@ -0,0 +1,751 @@
+#include "binaryninjaapi.h"
+
+using namespace BinaryNinja;
+using namespace std;
+
+
+DataBuffer::DataBuffer()
+{
+ m_buffer = BNCreateDataBuffer(nullptr, 0);
+}
+
+
+DataBuffer::DataBuffer(size_t len)
+{
+ m_buffer = BNCreateDataBuffer(nullptr, len);
+}
+
+
+DataBuffer::DataBuffer(const DataBuffer& buf)
+{
+ m_buffer = BNDuplicateDataBuffer(buf.m_buffer);
+}
+
+
+DataBuffer::DataBuffer(BNDataBuffer* buf)
+{
+ m_buffer = buf;
+}
+
+
+DataBuffer::~DataBuffer()
+{
+ BNFreeDataBuffer(m_buffer);
+}
+
+
+DataBuffer& DataBuffer::operator=(const DataBuffer& buf)
+{
+ BNFreeDataBuffer(m_buffer);
+ m_buffer = BNDuplicateDataBuffer(buf.m_buffer);
+ return *this;
+}
+
+
+void* DataBuffer::GetData()
+{
+ return BNGetDataBufferContents(m_buffer);
+}
+
+
+const void* DataBuffer::GetData() const
+{
+ return BNGetDataBufferContents(m_buffer);
+}
+
+
+void* DataBuffer::GetDataAt(size_t offset)
+{
+ return BNGetDataBufferContentsAt(m_buffer, offset);
+}
+
+
+size_t DataBuffer::GetLength() const
+{
+ return BNGetDataBufferLength(m_buffer);
+}
+
+
+void DataBuffer::SetSize(size_t len)
+{
+ BNSetDataBufferLength(m_buffer, len);
+}
+
+
+void DataBuffer::Append(const void* data, size_t len)
+{
+ BNAppendDataBufferContents(m_buffer, data, len);
+}
+
+
+void DataBuffer::Append(const DataBuffer& buf)
+{
+ BNAppendDataBuffer(m_buffer, buf.m_buffer);
+}
+
+
+DataBuffer DataBuffer::GetSlice(size_t start, size_t len)
+{
+ BNDataBuffer* result = BNGetDataBufferSlice(m_buffer, start, len);
+ return DataBuffer(result);
+}
+
+
+uint8_t& DataBuffer::operator[](size_t offset)
+{
+ return ((uint8_t*)GetData())[offset];
+}
+
+
+const uint8_t& DataBuffer::operator[](size_t offset) const
+{
+ return ((const uint8_t*)GetData())[offset];
+}
+
+
+char* NavigationHandler::GetCurrentViewCallback(void* ctxt)
+{
+ NavigationHandler* handler = (NavigationHandler*)ctxt;
+ string result = handler->GetCurrentView();
+ return BNAllocString(result.c_str());
+}
+
+
+uint64_t NavigationHandler::GetCurrentOffsetCallback(void* ctxt)
+{
+ NavigationHandler* handler = (NavigationHandler*)ctxt;
+ return handler->GetCurrentOffset();
+}
+
+
+bool NavigationHandler::NavigateCallback(void* ctxt, const char* view, uint64_t offset)
+{
+ NavigationHandler* handler = (NavigationHandler*)ctxt;
+ return handler->Navigate(view, offset);
+}
+
+
+NavigationHandler::NavigationHandler()
+{
+ m_callbacks.context = this;
+ m_callbacks.getCurrentView = GetCurrentViewCallback;
+ m_callbacks.getCurrentOffset = GetCurrentOffsetCallback;
+ m_callbacks.navigate = NavigateCallback;
+}
+
+
+void UndoAction::UndoCallback(void* ctxt)
+{
+ UndoAction* action = (UndoAction*)ctxt;
+ action->Undo();
+}
+
+
+void UndoAction::RedoCallback(void* ctxt)
+{
+ UndoAction* action = (UndoAction*)ctxt;
+ action->Redo();
+}
+
+
+void UndoAction::Add(BNFileMetadata* file)
+{
+ BNAddUndoAction(file, this, UndoCallback, RedoCallback);
+}
+
+
+FileMetadata::FileMetadata()
+{
+ m_file = BNCreateFileMetadata();
+}
+
+
+FileMetadata::FileMetadata(BNFileMetadata* file)
+{
+ m_file = file;
+}
+
+
+FileMetadata::~FileMetadata()
+{
+ BNFreeFileMetadata(m_file);
+}
+
+
+void FileMetadata::SetNavigationHandler(NavigationHandler* handler)
+{
+ BNSetFileMetadataNavigationHandler(m_file, handler->GetCallbacks());
+}
+
+
+bool FileMetadata::IsModified() const
+{
+ return BNIsFileModified(m_file);
+}
+
+
+void FileMetadata::MarkFileModified()
+{
+ BNMarkFileModified(m_file);
+}
+
+
+void FileMetadata::MarkFileSaved()
+{
+ BNMarkFileSaved(m_file);
+}
+
+
+void FileMetadata::BeginUndoActions()
+{
+ BNBeginUndoActions(m_file);
+}
+
+
+void FileMetadata::AddUndoAction(UndoAction* action)
+{
+ action->Add(m_file);
+}
+
+
+void FileMetadata::CommitUndoActions()
+{
+ BNCommitUndoActions(m_file);
+}
+
+
+bool FileMetadata::Undo()
+{
+ return BNUndo(m_file);
+}
+
+
+bool FileMetadata::Redo()
+{
+ return BNRedo(m_file);
+}
+
+
+string FileMetadata::GetCurrentView()
+{
+ char* view = BNGetCurrentView(m_file);
+ string result = view;
+ BNFreeString(view);
+ return result;
+}
+
+
+uint64_t FileMetadata::GetCurrentOffset()
+{
+ return BNGetCurrentOffset(m_file);
+}
+
+
+bool FileMetadata::Navigate(const string& view, uint64_t offset)
+{
+ return BNNavigate(m_file, view.c_str(), offset);
+}
+
+
+void BinaryDataNotification::DataWrittenCallback(void* ctxt, BNBinaryView* object, uint64_t offset, size_t len)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new CoreBinaryView(BNNewViewReference(object));
+ notify->OnBinaryDataWritten(view, offset, len);
+}
+
+
+void BinaryDataNotification::DataInsertedCallback(void* ctxt, BNBinaryView* object, uint64_t offset, size_t len)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new CoreBinaryView(BNNewViewReference(object));
+ notify->OnBinaryDataInserted(view, offset, len);
+}
+
+
+void BinaryDataNotification::DataRemovedCallback(void* ctxt, BNBinaryView* object, uint64_t offset, uint64_t len)
+{
+ BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
+ Ref<BinaryView> view = new CoreBinaryView(BNNewViewReference(object));
+ notify->OnBinaryDataRemoved(view, offset, len);
+}
+
+
+BinaryDataNotification::BinaryDataNotification()
+{
+ m_callbacks.context = this;
+ m_callbacks.dataWritten = DataWrittenCallback;
+ m_callbacks.dataInserted = DataInsertedCallback;
+ m_callbacks.dataRemoved = DataRemovedCallback;
+}
+
+
+uint64_t FileAccessor::GetLengthCallback(void* ctxt)
+{
+ FileAccessor* file = (FileAccessor*)ctxt;
+ return file->GetLength();
+}
+
+
+size_t FileAccessor::ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len)
+{
+ FileAccessor* file = (FileAccessor*)ctxt;
+ return file->Read(dest, offset, len);
+}
+
+
+size_t FileAccessor::WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len)
+{
+ FileAccessor* file = (FileAccessor*)ctxt;
+ return file->Write(offset, src, len);
+}
+
+
+FileAccessor::FileAccessor()
+{
+ m_callbacks.context = this;
+ m_callbacks.getLength = GetLengthCallback;
+ m_callbacks.read = ReadCallback;
+ m_callbacks.write = WriteCallback;
+}
+
+
+FileAccessor::FileAccessor(BNFileAccessor* accessor): m_callbacks(*accessor)
+{
+}
+
+
+CoreFileAccessor::CoreFileAccessor(BNFileAccessor* accessor): FileAccessor(accessor)
+{
+}
+
+
+uint64_t CoreFileAccessor::GetLength() const
+{
+ return m_callbacks.getLength(m_callbacks.context);
+}
+
+
+size_t CoreFileAccessor::Read(void* dest, uint64_t offset, size_t len)
+{
+ return m_callbacks.read(m_callbacks.context, dest, offset, len);
+}
+
+
+size_t CoreFileAccessor::Write(uint64_t offset, const void* src, size_t len)
+{
+ return m_callbacks.write(m_callbacks.context, offset, src, len);
+}
+
+
+BinaryView::BinaryView(FileMetadata* file)
+{
+ BNCustomBinaryView view;
+ view.context = this;
+ view.read = ReadCallback;
+ view.write = WriteCallback;
+ view.insert = InsertCallback;
+ view.remove = RemoveCallback;
+ view.getModification = GetModificationCallback;
+ view.getStart = GetStartCallback;
+ view.getLength = GetLengthCallback;
+ view.save = SaveCallback;
+
+ m_file = file;
+ m_view = BNCreateCustomBinaryView(m_file->GetFileObject(), &view);
+}
+
+
+BinaryView::BinaryView(BNBinaryView* view)
+{
+ m_view = view;
+ m_file = new FileMetadata(BNNewFileReference(BNGetFileForView(m_view)));
+}
+
+
+BinaryView::~BinaryView()
+{
+ BNFreeBinaryView(m_view);
+}
+
+
+size_t BinaryView::ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->Read(dest, offset, len);
+}
+
+
+size_t BinaryView::WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->Write(offset, src, len);
+}
+
+
+size_t BinaryView::InsertCallback(void* ctxt, uint64_t offset, const void* src, size_t len)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->Insert(offset, src, len);
+}
+
+
+size_t BinaryView::RemoveCallback(void* ctxt, uint64_t offset, uint64_t len)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->Remove(offset, len);
+}
+
+
+BNModificationStatus BinaryView::GetModificationCallback(void* ctxt, uint64_t offset)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->GetModification(offset);
+}
+
+
+uint64_t BinaryView::GetStartCallback(void* ctxt)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->GetStart();
+}
+
+
+uint64_t BinaryView::GetLengthCallback(void* ctxt)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ return view->GetLength();
+}
+
+
+bool BinaryView::SaveCallback(void* ctxt, BNFileAccessor* file)
+{
+ BinaryView* view = (BinaryView*)ctxt;
+ CoreFileAccessor accessor(file);
+ return view->Save(&accessor);
+}
+
+
+bool BinaryView::IsModified() const
+{
+ return m_file->IsModified();
+}
+
+
+void BinaryView::BeginUndoActions()
+{
+ m_file->BeginUndoActions();
+}
+
+
+void BinaryView::AddUndoAction(UndoAction* action)
+{
+ m_file->AddUndoAction(action);
+}
+
+
+void BinaryView::CommitUndoActions()
+{
+ m_file->CommitUndoActions();
+}
+
+
+bool BinaryView::Undo()
+{
+ return m_file->Undo();
+}
+
+
+bool BinaryView::Redo()
+{
+ return m_file->Redo();
+}
+
+
+string BinaryView::GetCurrentView()
+{
+ return m_file->GetCurrentView();
+}
+
+
+uint64_t BinaryView::GetCurrentOffset()
+{
+ return m_file->GetCurrentOffset();
+}
+
+
+bool BinaryView::Navigate(const string& view, uint64_t offset)
+{
+ return m_file->Navigate(view, offset);
+}
+
+
+BNDefaultEndianness BinaryView::GetDefaultEndianness() const
+{
+ return BNGetDefaultEndianness(m_view);
+}
+
+
+void BinaryView::SetDefaultEndianness(BNDefaultEndianness endian)
+{
+ BNSetDefaultEndianness(m_view, endian);
+}
+
+
+uint8_t BinaryView::Read8(uint64_t offset)
+{
+ return BNRead8(m_view, offset);
+}
+
+
+uint16_t BinaryView::Read16(uint64_t offset)
+{
+ return BNRead16(m_view, offset);
+}
+
+
+uint32_t BinaryView::Read32(uint64_t offset)
+{
+ return BNRead32(m_view, offset);
+}
+
+
+uint64_t BinaryView::Read64(uint64_t offset)
+{
+ return BNRead64(m_view, offset);
+}
+
+
+uint16_t BinaryView::ReadLE16(uint64_t offset)
+{
+ return BNReadLE16(m_view, offset);
+}
+
+
+uint32_t BinaryView::ReadLE32(uint64_t offset)
+{
+ return BNReadLE32(m_view, offset);
+}
+
+
+uint64_t BinaryView::ReadLE64(uint64_t offset)
+{
+ return BNReadLE64(m_view, offset);
+}
+
+
+uint16_t BinaryView::ReadBE16(uint64_t offset)
+{
+ return BNReadBE16(m_view, offset);
+}
+
+
+uint32_t BinaryView::ReadBE32(uint64_t offset)
+{
+ return BNReadBE32(m_view, offset);
+}
+
+
+uint64_t BinaryView::ReadBE64(uint64_t offset)
+{
+ return BNReadBE64(m_view, offset);
+}
+
+
+DataBuffer BinaryView::ReadBuffer(uint64_t offset, size_t len)
+{
+ BNDataBuffer* result = BNReadBuffer(m_view, offset, len);
+ return DataBuffer(result);
+}
+
+
+bool BinaryView::Write8(uint64_t offset, uint8_t val)
+{
+ return BNWrite8(m_view, offset, val);
+}
+
+
+bool BinaryView::Write16(uint64_t offset, uint16_t val)
+{
+ return BNWrite16(m_view, offset, val);
+}
+
+
+bool BinaryView::Write32(uint64_t offset, uint32_t val)
+{
+ return BNWrite32(m_view, offset, val);
+}
+
+
+bool BinaryView::Write64(uint64_t offset, uint64_t val)
+{
+ return BNWrite64(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteLE16(uint64_t offset, uint16_t val)
+{
+ return BNWriteLE16(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteLE32(uint64_t offset, uint32_t val)
+{
+ return BNWriteLE32(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteLE64(uint64_t offset, uint64_t val)
+{
+ return BNWriteLE64(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteBE16(uint64_t offset, uint16_t val)
+{
+ return BNWriteBE16(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteBE32(uint64_t offset, uint32_t val)
+{
+ return BNWriteBE32(m_view, offset, val);
+}
+
+
+bool BinaryView::WriteBE64(uint64_t offset, uint64_t val)
+{
+ return BNWriteBE64(m_view, offset, val);
+}
+
+
+size_t BinaryView::WriteBuffer(uint64_t offset, const DataBuffer& data)
+{
+ return BNWriteBuffer(m_view, offset, data.GetBufferObject());
+}
+
+
+size_t BinaryView::InsertBuffer(uint64_t offset, const DataBuffer& data)
+{
+ return BNInsertBuffer(m_view, offset, data.GetBufferObject());
+}
+
+
+vector<BNModificationStatus> BinaryView::GetModification(uint64_t offset, size_t len)
+{
+ BNModificationStatus* mod = new BNModificationStatus[len];
+ len = BNGetModificationArray(m_view, offset, mod, len);
+
+ vector<BNModificationStatus> result;
+ for (size_t i = 0; i < len; i++)
+ result.push_back(mod[i]);
+
+ delete[] mod;
+ return result;
+}
+
+
+uint64_t BinaryView::GetEnd() const
+{
+ return BNGetEndOffset(m_view);
+}
+
+
+bool BinaryView::Save(const string& path)
+{
+ return BNSaveToFilename(m_view, path.c_str());
+}
+
+
+void BinaryView::RegisterNotification(BinaryDataNotification* notify)
+{
+ BNRegisterDataNotification(m_view, notify->GetCallbacks());
+}
+
+
+void BinaryView::UnregisterNotification(BinaryDataNotification* notify)
+{
+ BNUnregisterDataNotification(m_view, notify->GetCallbacks());
+}
+
+
+CoreBinaryView::CoreBinaryView(BNBinaryView* view): BinaryView(view)
+{
+}
+
+
+size_t CoreBinaryView::Read(void* dest, uint64_t offset, size_t len)
+{
+ return BNReadData(m_view, dest, offset, len);
+}
+
+
+size_t CoreBinaryView::Write(uint64_t offset, const void* data, size_t len)
+{
+ return BNWriteData(m_view, offset, data, len);
+}
+
+
+size_t CoreBinaryView::Insert(uint64_t offset, const void* data, size_t len)
+{
+ return BNInsertData(m_view, offset, data, len);
+}
+
+
+size_t CoreBinaryView::Remove(uint64_t offset, uint64_t len)
+{
+ return BNRemoveData(m_view, offset, len);
+}
+
+
+BNModificationStatus CoreBinaryView::GetModification(uint64_t offset)
+{
+ return BNGetModification(m_view, offset);
+}
+
+
+uint64_t CoreBinaryView::GetStart() const
+{
+ return BNGetStartOffset(m_view);
+}
+
+
+uint64_t CoreBinaryView::GetLength() const
+{
+ return BNGetViewLength(m_view);
+}
+
+
+bool CoreBinaryView::Save(FileAccessor* file)
+{
+ return BNSaveToFile(m_view, file->GetCallbacks());
+}
+
+
+BinaryData::BinaryData(FileMetadata* file): CoreBinaryView(BNCreateBinaryDataView(file->GetFileObject()))
+{
+}
+
+
+BinaryData::BinaryData(FileMetadata* file, const DataBuffer& data):
+ CoreBinaryView(BNCreateBinaryDataViewFromBuffer(file->GetFileObject(), data.GetBufferObject()))
+{
+}
+
+
+BinaryData::BinaryData(FileMetadata* file, const void* data, size_t len):
+ CoreBinaryView(BNCreateBinaryDataViewFromData(file->GetFileObject(), data, len))
+{
+}
+
+
+BinaryData::BinaryData(FileMetadata* file, const string& path):
+ CoreBinaryView(BNCreateBinaryDataViewFromFilename(file->GetFileObject(), path.c_str()))
+{
+}
+
+
+BinaryData::BinaryData(FileMetadata* file, FileAccessor* accessor):
+ CoreBinaryView(BNCreateBinaryDataViewFromFile(file->GetFileObject(), accessor->GetCallbacks()))
+{
+}
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
new file mode 100644
index 00000000..72a03f48
--- /dev/null
+++ b/binaryninjaapi.h
@@ -0,0 +1,381 @@
+#pragma once
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stddef.h>
+#include <string>
+#include <vector>
+#include "binaryninjacore.h"
+
+
+namespace BinaryNinja
+{
+ class RefCountObject
+ {
+ public:
+ int m_refs;
+ RefCountObject(): m_refs(0) {}
+ virtual ~RefCountObject() {}
+
+ void AddRef()
+ {
+ #ifdef WIN32
+ InterlockedIncrement((LONG*)&m_refs);
+ #else
+ __sync_fetch_and_add(&m_refs, 1);
+ #endif
+ }
+
+ void Release()
+ {
+ #ifdef WIN32
+ if (InterlockedDecrement((LONG*)&m_refs) == 0)
+ delete this;
+ #else
+ if (__sync_fetch_and_add(&m_refs, -1) == 1)
+ delete this;
+ #endif
+ }
+ };
+
+ template <class T>
+ class Ref
+ {
+ T* m_obj;
+
+ public:
+ Ref<T>(): m_obj(NULL)
+ {
+ }
+
+ Ref<T>(T* obj): m_obj(obj)
+ {
+ if (m_obj)
+ m_obj->AddRef();
+ }
+
+ Ref<T>(const Ref<T>& obj): m_obj(obj.m_obj)
+ {
+ if (m_obj)
+ m_obj->AddRef();
+ }
+
+ ~Ref<T>()
+ {
+ if (m_obj)
+ m_obj->Release();
+ }
+
+ Ref<T>& operator=(const Ref<T>& obj)
+ {
+ T* oldObj = m_obj;
+ m_obj = obj.m_obj;
+ if (m_obj)
+ m_obj->AddRef();
+ if (oldObj)
+ oldObj->Release();
+ return *this;
+ }
+
+ Ref<T>& operator=(T* obj)
+ {
+ 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;
+ }
+
+ T* GetPtr() const
+ {
+ return m_obj;
+ }
+ };
+
+ class DataBuffer
+ {
+ BNDataBuffer* m_buffer;
+
+ public:
+ DataBuffer();
+ DataBuffer(size_t len);
+ DataBuffer(const DataBuffer& buf);
+ DataBuffer(BNDataBuffer* buf);
+ ~DataBuffer();
+
+ DataBuffer& operator=(const DataBuffer& buf);
+
+ BNDataBuffer* GetBufferObject() const { return m_buffer; }
+
+ void* GetData();
+ const void* GetData() const;
+ void* GetDataAt(size_t offset);
+ size_t GetLength() const;
+
+ void SetSize(size_t len);
+ void Append(const void* data, size_t len);
+ void Append(const DataBuffer& buf);
+
+ DataBuffer GetSlice(size_t start, size_t len);
+
+ uint8_t& operator[](size_t offset);
+ const uint8_t& operator[](size_t offset) const;
+ };
+
+ class NavigationHandler
+ {
+ private:
+ BNNavigationHandler m_callbacks;
+
+ static char* GetCurrentViewCallback(void* ctxt);
+ static uint64_t GetCurrentOffsetCallback(void* ctxt);
+ static bool NavigateCallback(void* ctxt, const char* view, uint64_t offset);
+
+ public:
+ NavigationHandler();
+ virtual ~NavigationHandler() {}
+
+ BNNavigationHandler* GetCallbacks() { return &m_callbacks; }
+
+ virtual std::string GetCurrentView() = 0;
+ virtual uint64_t GetCurrentOffset() = 0;
+ virtual bool Navigate(const std::string& view, uint64_t offset) = 0;
+ };
+
+ class UndoAction
+ {
+ private:
+ static void UndoCallback(void* ctxt);
+ static void RedoCallback(void* ctxt);
+
+ public:
+ virtual ~UndoAction() {}
+
+ void Add(BNFileMetadata* file);
+
+ virtual void Undo() = 0;
+ virtual void Redo() = 0;
+ };
+
+ class FileMetadata: public RefCountObject
+ {
+ BNFileMetadata* m_file;
+
+ public:
+ FileMetadata();
+ FileMetadata(BNFileMetadata* file);
+ ~FileMetadata();
+
+ BNFileMetadata* GetFileObject() const { return m_file; }
+
+ void SetNavigationHandler(NavigationHandler* handler);
+
+ bool IsModified() const;
+ void MarkFileModified();
+ void MarkFileSaved();
+
+ void BeginUndoActions();
+ void AddUndoAction(UndoAction* action);
+ void CommitUndoActions();
+
+ bool Undo();
+ bool Redo();
+
+ std::string GetCurrentView();
+ uint64_t GetCurrentOffset();
+ bool Navigate(const std::string& view, uint64_t offset);
+ };
+
+ class BinaryView;
+
+ class BinaryDataNotification
+ {
+ private:
+ BNBinaryDataNotification m_callbacks;
+
+ static void DataWrittenCallback(void* ctxt, BNBinaryView* data, uint64_t offset, size_t len);
+ static void DataInsertedCallback(void* ctxt, BNBinaryView* data, uint64_t offset, size_t len);
+ static void DataRemovedCallback(void* ctxt, BNBinaryView* data, uint64_t offset, uint64_t len);
+
+ public:
+ BinaryDataNotification();
+ virtual ~BinaryDataNotification() {}
+
+ BNBinaryDataNotification* GetCallbacks() { return &m_callbacks; }
+
+ virtual void OnBinaryDataWritten(BinaryView* view, uint64_t offset, size_t len) = 0;
+ virtual void OnBinaryDataInserted(BinaryView* view, uint64_t offset, size_t len) = 0;
+ virtual void OnBinaryDataRemoved(BinaryView* view, uint64_t offset, uint64_t len) = 0;
+ };
+
+ class FileAccessor
+ {
+ protected:
+ BNFileAccessor m_callbacks;
+
+ private:
+ static uint64_t GetLengthCallback(void* ctxt);
+ static size_t ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len);
+ static size_t WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len);
+
+ public:
+ FileAccessor();
+ FileAccessor(BNFileAccessor* accessor);
+ virtual ~FileAccessor() {}
+
+ BNFileAccessor* GetCallbacks() { return &m_callbacks; }
+
+ virtual bool IsValid() const = 0;
+ virtual uint64_t GetLength() const = 0;
+ virtual size_t Read(void* dest, uint64_t offset, size_t len) = 0;
+ virtual size_t Write(uint64_t offset, const void* src, size_t len) = 0;
+ };
+
+ class CoreFileAccessor: public FileAccessor
+ {
+ public:
+ CoreFileAccessor(BNFileAccessor* accessor);
+
+ virtual bool IsValid() const override { return true; }
+ virtual uint64_t GetLength() const override;
+ virtual size_t Read(void* dest, uint64_t offset, size_t len) override;
+ virtual size_t Write(uint64_t offset, const void* src, size_t len) override;
+ };
+
+ class BinaryView: public RefCountObject
+ {
+ protected:
+ BNBinaryView* m_view;
+ Ref<FileMetadata> m_file;
+
+ BinaryView(FileMetadata* file);
+ BinaryView(BNBinaryView* view);
+
+ private:
+ static size_t ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len);
+ static size_t WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len);
+ static size_t InsertCallback(void* ctxt, uint64_t offset, const void* src, size_t len);
+ static size_t RemoveCallback(void* ctxt, uint64_t offset, uint64_t len);
+ static BNModificationStatus GetModificationCallback(void* ctxt, uint64_t offset);
+ static uint64_t GetStartCallback(void* ctxt);
+ static uint64_t GetLengthCallback(void* ctxt);
+ static bool SaveCallback(void* ctxt, BNFileAccessor* file);
+
+ public:
+ virtual ~BinaryView();
+
+ FileMetadata* GetFile() const { return m_file; }
+ BNBinaryView* GetViewObject() const { return m_view; }
+
+ bool IsModified() const;
+
+ void BeginUndoActions();
+ void AddUndoAction(UndoAction* action);
+ void CommitUndoActions();
+
+ bool Undo();
+ bool Redo();
+
+ std::string GetCurrentView();
+ uint64_t GetCurrentOffset();
+ bool Navigate(const std::string& view, uint64_t offset);
+
+ BNDefaultEndianness GetDefaultEndianness() const;
+ void SetDefaultEndianness(BNDefaultEndianness endian);
+
+ uint8_t Read8(uint64_t offset);
+ uint16_t Read16(uint64_t offset);
+ uint32_t Read32(uint64_t offset);
+ uint64_t Read64(uint64_t offset);
+ uint16_t ReadLE16(uint64_t offset);
+ uint32_t ReadLE32(uint64_t offset);
+ uint64_t ReadLE64(uint64_t offset);
+ uint16_t ReadBE16(uint64_t offset);
+ uint32_t ReadBE32(uint64_t offset);
+ uint64_t ReadBE64(uint64_t offset);
+ virtual size_t Read(void* dest, uint64_t offset, size_t len) = 0;
+ DataBuffer ReadBuffer(uint64_t offset, size_t len);
+
+ bool Write8(uint64_t offset, uint8_t val);
+ bool Write16(uint64_t offset, uint16_t val);
+ bool Write32(uint64_t offset, uint32_t val);
+ bool Write64(uint64_t offset, uint64_t val);
+ bool WriteLE16(uint64_t offset, uint16_t val);
+ bool WriteLE32(uint64_t offset, uint32_t val);
+ bool WriteLE64(uint64_t offset, uint64_t val);
+ bool WriteBE16(uint64_t offset, uint16_t val);
+ bool WriteBE32(uint64_t offset, uint32_t val);
+ bool WriteBE64(uint64_t offset, uint64_t val);
+ virtual size_t Write(uint64_t offset, const void* data, size_t len) { (void)offset; (void)data; (void)len; return 0; }
+ size_t WriteBuffer(uint64_t offset, const DataBuffer& data);
+
+ virtual size_t Insert(uint64_t offset, const void* data, size_t len) { (void)offset; (void)data; (void)len; return 0; }
+ size_t InsertBuffer(uint64_t offset, const DataBuffer& data);
+
+ virtual size_t Remove(uint64_t offset, uint64_t len) { (void)offset; (void)len; return 0; }
+
+ virtual BNModificationStatus GetModification(uint64_t offset) { (void)offset; return Original; }
+ std::vector<BNModificationStatus> GetModification(uint64_t offset, size_t len);
+
+ virtual uint64_t GetStart() const { return 0; }
+ uint64_t GetEnd() const;
+ virtual uint64_t GetLength() const = 0;
+
+ virtual bool Save(FileAccessor* file) { (void)file; return false; }
+ bool Save(const std::string& path);
+
+ void RegisterNotification(BinaryDataNotification* notify);
+ void UnregisterNotification(BinaryDataNotification* notify);
+ };
+
+ class CoreBinaryView: public BinaryView
+ {
+ public:
+ CoreBinaryView(BNBinaryView* view);
+
+ virtual size_t Read(void* dest, uint64_t offset, size_t len) override;
+ virtual size_t Write(uint64_t offset, const void* data, size_t len) override;
+ virtual size_t Insert(uint64_t offset, const void* data, size_t len) override;
+ virtual size_t Remove(uint64_t offset, uint64_t len) override;
+
+ virtual BNModificationStatus GetModification(uint64_t offset) override;
+
+ virtual uint64_t GetStart() const override;
+ virtual uint64_t GetLength() const override;
+
+ virtual bool Save(FileAccessor* file) override;
+ };
+
+ class BinaryData: public CoreBinaryView
+ {
+ public:
+ BinaryData(FileMetadata* file);
+ BinaryData(FileMetadata* file, const DataBuffer& data);
+ BinaryData(FileMetadata* file, const void* data, size_t len);
+ BinaryData(FileMetadata* file, const std::string& path);
+ BinaryData(FileMetadata* file, FileAccessor* accessor);
+ };
+}