diff options
| -rw-r--r-- | api.pro | 22 | ||||
| -rw-r--r-- | binaryninjaapi.cpp | 751 | ||||
| -rw-r--r-- | binaryninjaapi.h | 381 |
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); + }; +} |
