// Copyright (c) 2015-2016 Vector 35 LLC // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. #pragma once #ifdef WIN32 #include #endif #include #include #include #include #include #include #include "binaryninjacore.h" #include "json/json.h" #ifdef _MSC_VER #define NOEXCEPT #else #define NOEXCEPT noexcept #endif 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 CoreRefCountObject { void AddRefInternal() { #ifdef WIN32 InterlockedIncrement((LONG*)&m_refs); #else __sync_fetch_and_add(&m_refs, 1); #endif } void ReleaseInternal() { #ifdef WIN32 if (InterlockedDecrement((LONG*)&m_refs) == 0) delete this; #else if (__sync_fetch_and_add(&m_refs, -1) == 1) delete this; #endif } public: int m_refs; T* m_object; CoreRefCountObject(): m_refs(0), m_object(nullptr) {} virtual ~CoreRefCountObject() {} T* GetObject() { return m_object; } void AddRef() { if (m_object && (m_refs != 0)) AddObjectReference(m_object); AddRefInternal(); } void Release() { if (m_object) FreeObjectReference(m_object); ReleaseInternal(); } void AddRefForRegistration() { AddRefInternal(); } void ReleaseForRegistration() { m_object = nullptr; ReleaseInternal(); } }; template class StaticCoreRefCountObject { void AddRefInternal() { #ifdef WIN32 InterlockedIncrement((LONG*)&m_refs); #else __sync_fetch_and_add(&m_refs, 1); #endif } void ReleaseInternal() { #ifdef WIN32 if (InterlockedDecrement((LONG*)&m_refs) == 0) delete this; #else if (__sync_fetch_and_add(&m_refs, -1) == 1) delete this; #endif } public: int m_refs; T* m_object; StaticCoreRefCountObject(): m_refs(0), m_object(nullptr) {} virtual ~StaticCoreRefCountObject() {} T* GetObject() { return m_object; } void AddRef() { AddRefInternal(); } void Release() { ReleaseInternal(); } void AddRefForRegistration() { AddRefInternal(); } }; template class Ref { T* m_obj; public: Ref(): m_obj(NULL) { } Ref(T* obj): m_obj(obj) { if (m_obj) m_obj->AddRef(); } Ref(const Ref& obj): m_obj(obj.m_obj) { if (m_obj) m_obj->AddRef(); } ~Ref() { if (m_obj) m_obj->Release(); } Ref& operator=(const Ref& obj) { T* oldObj = m_obj; m_obj = obj.m_obj; if (m_obj) m_obj->AddRef(); if (oldObj) oldObj->Release(); return *this; } Ref& 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 LogListener { static void LogMessageCallback(void* ctxt, BNLogLevel level, const char* msg); static void CloseLogCallback(void* ctxt); static BNLogLevel GetLogLevelCallback(void* ctxt); public: virtual ~LogListener() {} static void RegisterLogListener(LogListener* listener); static void UnregisterLogListener(LogListener* listener); static void UpdateLogListeners(); virtual void LogMessage(BNLogLevel level, const std::string& msg) = 0; virtual void CloseLog() {} virtual BNLogLevel GetLogLevel() { return WarningLog; } }; class Architecture; class Platform; class Type; class DataBuffer; void Log(BNLogLevel level, const char* fmt, ...); void LogDebug(const char* fmt, ...); void LogInfo(const char* fmt, ...); void LogWarn(const char* fmt, ...); void LogError(const char* fmt, ...); void LogAlert(const char* fmt, ...); void LogToStdout(BNLogLevel minimumLevel); void LogToStderr(BNLogLevel minimumLevel); bool LogToFile(BNLogLevel minimumLevel, const std::string& path, bool append = false); void CloseLogs(); std::string EscapeString(const std::string& s); std::string UnescapeString(const std::string& s); bool PreprocessSource(const std::string& source, const std::string& fileName, std::string& output, std::string& errors, const std::vector& includeDirs = std::vector()); void InitCorePlugins(); void InitUserPlugins(); std::string GetBundledPluginDirectory(); void SetBundledPluginDirectory(const std::string& path); std::string GetUserPluginDirectory(); std::string GetPathRelativeToBundledPluginDirectory(const std::string& path); std::string GetPathRelativeToUserPluginDirectory(const std::string& path); bool ExecuteWorkerProcess(const std::string& path, const std::vector& args, const DataBuffer& input, std::string& output, std::string& errors); std::string GetVersionString(); uint32_t GetBuildId(); bool AreAutoUpdatesEnabled(); void SetAutoUpdatesEnabled(bool enabled); uint64_t GetTimeSinceLastUpdateCheck(); void UpdatesChecked(); std::string GetActiveUpdateChannel(); void SetActiveUpdateChannel(const std::string& channel); void SetCurrentPluginLoadOrder(BNPluginLoadOrder order); void AddRequiredPluginDependency(const std::string& name); void AddOptionalPluginDependency(const std::string& name); class DataBuffer { BNDataBuffer* m_buffer; public: DataBuffer(); DataBuffer(size_t len); DataBuffer(const void* data, 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); const void* GetDataAt(size_t offset) const; size_t GetLength() const; void SetSize(size_t len); void Clear(); void Append(const void* data, size_t len); void Append(const DataBuffer& buf); void AppendByte(uint8_t val); DataBuffer GetSlice(size_t start, size_t len); uint8_t& operator[](size_t offset); const uint8_t& operator[](size_t offset) const; std::string ToEscapedString() const; static DataBuffer FromEscapedString(const std::string& src); std::string ToBase64() const; static DataBuffer FromBase64(const std::string& src); bool ZlibCompress(DataBuffer& output) const; bool ZlibDecompress(DataBuffer& output) const; }; class TemporaryFile: public CoreRefCountObject { public: TemporaryFile(); TemporaryFile(const DataBuffer& contents); TemporaryFile(const std::string& contents); TemporaryFile(BNTemporaryFile* file); bool IsValid() const { return m_object != nullptr; } std::string GetPath() const; DataBuffer GetContents(); }; 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 BinaryView; class UndoAction { private: std::string m_typeName; BNActionType m_actionType; static void FreeCallback(void* ctxt); static void UndoCallback(void* ctxt, BNBinaryView* data); static void RedoCallback(void* ctxt, BNBinaryView* data); static char* SerializeCallback(void* ctxt); public: UndoAction(const std::string& name, BNActionType action); virtual ~UndoAction() {} const std::string& GetTypeName() const { return m_typeName; } BNActionType GetActionType() const { return m_actionType; } BNUndoAction GetCallbacks(); void Add(BNBinaryView* view); virtual void Undo(BinaryView* data) = 0; virtual void Redo(BinaryView* data) = 0; virtual Json::Value Serialize() = 0; }; class UndoActionType { protected: std::string m_nameForRegister; static bool DeserializeCallback(void* ctxt, const char* data, BNUndoAction* result); public: UndoActionType(const std::string& name); virtual ~UndoActionType() {} static void Register(UndoActionType* type); virtual UndoAction* Deserialize(const Json::Value& data) = 0; }; class FileMetadata: public CoreRefCountObject { public: FileMetadata(); FileMetadata(const std::string& filename); FileMetadata(BNFileMetadata* file); void Close(); void SetNavigationHandler(NavigationHandler* handler); std::string GetFilename() const; void SetFilename(const std::string& name); bool IsModified() const; bool IsAnalysisChanged() const; void MarkFileModified(); void MarkFileSaved(); bool IsBackedByDatabase() const; bool CreateDatabase(const std::string& name, BinaryView* data); Ref OpenExistingDatabase(const std::string& path); bool SaveAutoSnapshot(BinaryView* data); void BeginUndoActions(); void CommitUndoActions(); bool Undo(); bool Redo(); std::string GetCurrentView(); uint64_t GetCurrentOffset(); bool Navigate(const std::string& view, uint64_t offset); BinaryNinja::Ref GetViewOfType(const std::string& name); }; class BinaryView; class Function; 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); static void FunctionAddedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); static void FunctionRemovedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); static void FunctionUpdatedCallback(void* ctxt, BNBinaryView* data, BNFunction* func); static void StringFoundCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); static void StringRemovedCallback(void* ctxt, BNBinaryView* data, BNStringType type, uint64_t offset, size_t len); public: BinaryDataNotification(); virtual ~BinaryDataNotification() {} BNBinaryDataNotification* GetCallbacks() { return &m_callbacks; } virtual void OnBinaryDataWritten(BinaryView* view, uint64_t offset, size_t len) { (void)view; (void)offset; (void)len; } virtual void OnBinaryDataInserted(BinaryView* view, uint64_t offset, size_t len) { (void)view; (void)offset; (void)len; } virtual void OnBinaryDataRemoved(BinaryView* view, uint64_t offset, uint64_t len) { (void)view; (void)offset; (void)len; } virtual void OnAnalysisFunctionAdded(BinaryView* view, Function* func) { (void)view; (void)func; } virtual void OnAnalysisFunctionRemoved(BinaryView* view, Function* func) { (void)view; (void)func; } virtual void OnAnalysisFunctionUpdated(BinaryView* view, Function* func) { (void)view; (void)func; } virtual void OnStringFound(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } virtual void OnStringRemoved(BinaryView* data, BNStringType type, uint64_t offset, size_t len) { (void)data; (void)type; (void)offset; (void)len; } }; 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 Function; class BasicBlock; class Symbol: public CoreRefCountObject { public: Symbol(BNSymbolType type, const std::string& shortName, const std::string& fullName, const std::string& rawName, uint64_t addr); Symbol(BNSymbolType type, const std::string& name, uint64_t addr); Symbol(BNSymbol* sym); BNSymbolType GetType() const; std::string GetShortName() const; std::string GetFullName() const; std::string GetRawName() const; uint64_t GetAddress() const; bool IsAutoDefined() const; void SetAutoDefined(bool val); static Ref ImportedFunctionFromImportAddressSymbol(Symbol* sym, uint64_t addr); }; struct ReferenceSource { Ref func; Ref arch; uint64_t addr; }; class BinaryView: public CoreRefCountObject { protected: Ref m_file; BinaryView(const std::string& typeName, FileMetadata* file); virtual size_t PerformRead(void* dest, uint64_t offset, size_t len) { (void)dest; (void)offset; (void)len; return 0; } virtual size_t PerformWrite(uint64_t offset, const void* data, size_t len) { (void)offset; (void)data; (void)len; return 0; } virtual size_t PerformInsert(uint64_t offset, const void* data, size_t len) { (void)offset; (void)data; (void)len; return 0; } virtual size_t PerformRemove(uint64_t offset, uint64_t len) { (void)offset; (void)len; return 0; } virtual BNModificationStatus PerformGetModification(uint64_t offset) { (void)offset; return Original; } virtual bool PerformIsValidOffset(uint64_t offset); virtual bool PerformIsOffsetReadable(uint64_t offset); virtual bool PerformIsOffsetWritable(uint64_t offset); virtual bool PerformIsOffsetExecutable(uint64_t offset); virtual uint64_t PerformGetNextValidOffset(uint64_t offset); virtual uint64_t PerformGetStart() const { return 0; } virtual uint64_t PerformGetLength() const { return 0; } virtual uint64_t PerformGetEntryPoint() const { return 0; } virtual bool PerformIsExecutable() const { return false; } virtual BNEndianness PerformGetDefaultEndianness() const; virtual size_t PerformGetAddressSize() const; virtual bool PerformSave(FileAccessor* file) { (void)file; return false; } void NotifyDataWritten(uint64_t offset, size_t len); void NotifyDataInserted(uint64_t offset, size_t len); void NotifyDataRemoved(uint64_t offset, uint64_t len); private: static bool InitCallback(void* ctxt); static void FreeCallback(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); 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 bool IsValidOffsetCallback(void* ctxt, uint64_t offset); static bool IsOffsetReadableCallback(void* ctxt, uint64_t offset); static bool IsOffsetWritableCallback(void* ctxt, uint64_t offset); static bool IsOffsetExecutableCallback(void* ctxt, uint64_t offset); static uint64_t GetNextValidOffsetCallback(void* ctxt, uint64_t offset); static uint64_t GetStartCallback(void* ctxt); static uint64_t GetLengthCallback(void* ctxt); static uint64_t GetEntryPointCallback(void* ctxt); static bool IsExecutableCallback(void* ctxt); static BNEndianness GetDefaultEndiannessCallback(void* ctxt); static size_t GetAddressSizeCallback(void* ctxt); static bool SaveCallback(void* ctxt, BNFileAccessor* file); public: BinaryView(BNBinaryView* view); virtual bool Init() { return true; } FileMetadata* GetFile() const { return m_file; } std::string GetTypeName() const; bool IsModified() const; bool IsAnalysisChanged() const; bool IsBackedByDatabase() const; bool CreateDatabase(const std::string& path); bool SaveAutoSnapshot(); 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); size_t Read(void* dest, uint64_t offset, size_t len); DataBuffer ReadBuffer(uint64_t offset, size_t len); size_t Write(uint64_t offset, const void* data, size_t len); size_t WriteBuffer(uint64_t offset, const DataBuffer& data); size_t Insert(uint64_t offset, const void* data, size_t len); size_t InsertBuffer(uint64_t offset, const DataBuffer& data); size_t Remove(uint64_t offset, uint64_t len); BNModificationStatus GetModification(uint64_t offset); std::vector GetModification(uint64_t offset, size_t len); bool IsValidOffset(uint64_t offset) const; bool IsOffsetReadable(uint64_t offset) const; bool IsOffsetWritable(uint64_t offset) const; bool IsOffsetExecutable(uint64_t offset) const; uint64_t GetNextValidOffset(uint64_t offset) const; uint64_t GetStart() const; uint64_t GetEnd() const; uint64_t GetLength() const; uint64_t GetEntryPoint() const; Ref GetDefaultArchitecture() const; void SetDefaultArchitecture(Architecture* arch); Ref GetDefaultPlatform() const; void SetDefaultPlatform(Platform* platform); BNEndianness GetDefaultEndianness() const; size_t GetAddressSize() const; bool IsExecutable() const; bool Save(FileAccessor* file); bool Save(const std::string& path); void RegisterNotification(BinaryDataNotification* notify); void UnregisterNotification(BinaryDataNotification* notify); void AddFunctionForAnalysis(Platform* platform, uint64_t addr); void AddEntryPointForAnalysis(Platform* platform, uint64_t start); void RemoveAnalysisFunction(Function* func); void CreateUserFunction(Platform* platform, uint64_t start); void UpdateAnalysis(); void AbortAnalysis(); std::vector> GetAnalysisFunctionList(); bool HasFunctions() const; Ref GetAnalysisFunction(Platform* platform, uint64_t addr); Ref GetRecentAnalysisFunctionForAddress(uint64_t addr); std::vector> GetAnalysisFunctionsForAddress(uint64_t addr); Ref GetAnalysisEntryPoint(); Ref GetRecentBasicBlockForAddress(uint64_t addr); std::vector> GetBasicBlocksForAddress(uint64_t addr); std::vector GetCodeReferences(uint64_t addr); std::vector GetCodeReferences(uint64_t addr, uint64_t len); Ref GetSymbolByAddress(uint64_t addr); Ref GetSymbolByRawName(const std::string& name); std::vector> GetSymbolsByName(const std::string& name); std::vector> GetSymbols(); std::vector> GetSymbols(uint64_t start, uint64_t len); std::vector> GetSymbolsOfType(BNSymbolType type); std::vector> GetSymbolsOfType(BNSymbolType type, uint64_t start, uint64_t len); void DefineAutoSymbol(Symbol* sym); void UndefineAutoSymbol(Symbol* sym); void DefineUserSymbol(Symbol* sym); void UndefineUserSymbol(Symbol* sym); void DefineImportedFunction(Symbol* importAddressSym, Function* func); bool IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr); bool IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr); bool IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr); bool IsSkipAndReturnZeroPatchAvailable(Architecture* arch, uint64_t addr); bool IsSkipAndReturnValuePatchAvailable(Architecture* arch, uint64_t addr); bool ConvertToNop(Architecture* arch, uint64_t addr); bool AlwaysBranch(Architecture* arch, uint64_t addr); bool InvertBranch(Architecture* arch, uint64_t addr); bool SkipAndReturnValue(Architecture* arch, uint64_t addr, uint64_t value); size_t GetInstructionLength(Architecture* arch, uint64_t addr); std::vector GetStrings(); std::vector GetStrings(uint64_t start, uint64_t len); }; class BinaryData: public BinaryView { 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); }; class Platform; class BinaryViewType: public StaticCoreRefCountObject { protected: std::string m_nameForRegister, m_longNameForRegister; static BNBinaryView* CreateCallback(void* ctxt, BNBinaryView* data); static bool IsValidCallback(void* ctxt, BNBinaryView* data); BinaryViewType(BNBinaryViewType* type); public: BinaryViewType(const std::string& name, const std::string& longName); virtual ~BinaryViewType() {} static void Register(BinaryViewType* type); static Ref GetByName(const std::string& name); static std::vector> GetViewTypes(); static std::vector> GetViewTypesForData(BinaryView* data); static void RegisterArchitecture(const std::string& name, uint32_t id, Architecture* arch); void RegisterArchitecture(uint32_t id, Architecture* arch); Ref GetArchitecture(uint32_t id); static void RegisterPlatform(const std::string& name, uint32_t id, Architecture* arch, Platform* platform); static void RegisterDefaultPlatform(const std::string& name, Architecture* arch, Platform* platform); void RegisterPlatform(uint32_t id, Architecture* arch, Platform* platform); void RegisterDefaultPlatform(Architecture* arch, Platform* platform); Ref GetPlatform(uint32_t id, Architecture* arch); std::string GetName(); std::string GetLongName(); virtual BinaryView* Create(BinaryView* data) = 0; virtual bool IsTypeValidForData(BinaryView* data) = 0; }; class CoreBinaryViewType: public BinaryViewType { public: CoreBinaryViewType(BNBinaryViewType* type); virtual BinaryView* Create(BinaryView* data) override; virtual bool IsTypeValidForData(BinaryView* data) override; }; class ReadException: public std::exception { public: ReadException(): std::exception() {} virtual const char* what() const NOEXCEPT { return "read out of bounds"; } }; class BinaryReader { Ref m_view; BNBinaryReader* m_stream; public: BinaryReader(BinaryView* data, BNEndianness endian = LittleEndian); ~BinaryReader(); BNEndianness GetEndianness() const; void SetEndianness(BNEndianness endian); void Read(void* dest, size_t len); DataBuffer Read(size_t len); std::string ReadString(size_t len); uint8_t Read8(); uint16_t Read16(); uint32_t Read32(); uint64_t Read64(); uint16_t ReadLE16(); uint32_t ReadLE32(); uint64_t ReadLE64(); uint16_t ReadBE16(); uint32_t ReadBE32(); uint64_t ReadBE64(); bool TryRead(void* dest, size_t len); bool TryRead(DataBuffer& dest, size_t len); bool TryReadString(std::string& dest, size_t len); bool TryRead8(uint8_t& result); bool TryRead16(uint16_t& result); bool TryRead32(uint32_t& result); bool TryRead64(uint64_t& result); bool TryReadLE16(uint16_t& result); bool TryReadLE32(uint32_t& result); bool TryReadLE64(uint64_t& result); bool TryReadBE16(uint16_t& result); bool TryReadBE32(uint32_t& result); bool TryReadBE64(uint64_t& result); uint64_t GetOffset() const; void Seek(uint64_t offset); void SeekRelative(int64_t offset); bool IsEndOfFile() const; }; class WriteException: public std::exception { public: WriteException(): std::exception() {} virtual const char* what() const NOEXCEPT { return "write out of bounds"; } }; class BinaryWriter { Ref m_view; BNBinaryWriter* m_stream; public: BinaryWriter(BinaryView* data, BNEndianness endian = LittleEndian); ~BinaryWriter(); BNEndianness GetEndianness() const; void SetEndianness(BNEndianness endian); void Write(const void* src, size_t len); void Write(const DataBuffer& buf); void Write(const std::string& str); void Write8(uint8_t val); void Write16(uint16_t val); void Write32(uint32_t val); void Write64(uint64_t val); void WriteLE16(uint16_t val); void WriteLE32(uint32_t val); void WriteLE64(uint64_t val); void WriteBE16(uint16_t val); void WriteBE32(uint32_t val); void WriteBE64(uint64_t val); bool TryWrite(const void* src, size_t len); bool TryWrite(const DataBuffer& buf); bool TryWrite(const std::string& str); bool TryWrite8(uint8_t val); bool TryWrite16(uint16_t val); bool TryWrite32(uint32_t val); bool TryWrite64(uint64_t val); bool TryWriteLE16(uint16_t val); bool TryWriteLE32(uint32_t val); bool TryWriteLE64(uint64_t val); bool TryWriteBE16(uint16_t val); bool TryWriteBE32(uint32_t val); bool TryWriteBE64(uint64_t val); uint64_t GetOffset() const; void Seek(uint64_t offset); void SeekRelative(int64_t offset); }; struct TransformParameter { std::string name, longName; size_t fixedLength; // Variable length if zero }; class Transform: public StaticCoreRefCountObject { protected: BNTransformType m_typeForRegister; std::string m_nameForRegister, m_longNameForRegister, m_groupForRegister; Transform(BNTransform* xform); static BNTransformParameterInfo* GetParametersCallback(void* ctxt, size_t* count); static void FreeParametersCallback(BNTransformParameterInfo* params, size_t count); static bool DecodeCallback(void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); static bool EncodeCallback(void* ctxt, BNDataBuffer* input, BNDataBuffer* output, BNTransformParameter* params, size_t paramCount); static std::vector EncryptionKeyParameters(size_t fixedKeyLength = 0); static std::vector EncryptionKeyAndIVParameters(size_t fixedKeyLength = 0, size_t fixedIVLength = 0); public: Transform(BNTransformType type, const std::string& name, const std::string& longName, const std::string& group); static void Register(Transform* xform); static Ref GetByName(const std::string& name); static std::vector> GetTransformTypes(); BNTransformType GetType() const; std::string GetName() const; std::string GetLongName() const; std::string GetGroup() const; virtual std::vector GetParameters() const; virtual bool Decode(const DataBuffer& input, DataBuffer& output, const std::map& params = std::map()); virtual bool Encode(const DataBuffer& input, DataBuffer& output, const std::map& params = std::map()); }; class CoreTransform: public Transform { public: CoreTransform(BNTransform* xform); virtual std::vector GetParameters() const override; virtual bool Decode(const DataBuffer& input, DataBuffer& output, const std::map& params = std::map()) override; virtual bool Encode(const DataBuffer& input, DataBuffer& output, const std::map& params = std::map()) override; }; struct InstructionInfo: public BNInstructionInfo { InstructionInfo(); void AddBranch(BNBranchType type, uint64_t target = 0, Architecture* arch = nullptr, bool hasDelaySlot = false); }; struct InstructionTextToken { BNInstructionTextTokenType type; std::string text; uint64_t value; InstructionTextToken(); InstructionTextToken(BNInstructionTextTokenType type, const std::string& text, uint64_t value = 0); }; class LowLevelILFunction; class FunctionRecognizer; class CallingConvention; typedef size_t ExprId; class Architecture: public StaticCoreRefCountObject { protected: std::string m_nameForRegister; Architecture(BNArchitecture* arch); static void InitCallback(void* ctxt, BNArchitecture* obj); static BNEndianness GetEndiannessCallback(void* ctxt); static size_t GetAddressSizeCallback(void* ctxt); static size_t GetDefaultIntegerSizeCallback(void* ctxt); static bool GetInstructionInfoCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t maxLen, BNInstructionInfo* result); static bool GetInstructionTextCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNInstructionTextToken** result, size_t* count); static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count); static bool GetInstructionLowLevelILCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il); static char* GetRegisterNameCallback(void* ctxt, uint32_t reg); static char* GetFlagNameCallback(void* ctxt, uint32_t flag); static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags); static uint32_t* GetFullWidthRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetAllRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetAllFlagsCallback(void* ctxt, size_t* count); static uint32_t* GetAllFlagWriteTypesCallback(void* ctxt, size_t* count); static void FreeRegisterListCallback(void* ctxt, uint32_t* regs); static void GetRegisterInfoCallback(void* ctxt, uint32_t reg, BNRegisterInfo* result); static uint32_t GetStackPointerRegisterCallback(void* ctxt); static uint32_t GetLinkRegisterCallback(void* ctxt); static bool AssembleCallback(void* ctxt, const char* code, uint64_t addr, BNDataBuffer* result, char** errors); static bool IsNeverBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); static bool IsAlwaysBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); static bool IsInvertBranchPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); static bool IsSkipAndReturnZeroPatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); static bool IsSkipAndReturnValuePatchAvailableCallback(void* ctxt, const uint8_t* data, uint64_t addr, size_t len); static bool ConvertToNopCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); static bool AlwaysBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); static bool InvertBranchCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len); static bool SkipAndReturnValueCallback(void* ctxt, uint8_t* data, uint64_t addr, size_t len, uint64_t value); public: Architecture(const std::string& name); static void Register(Architecture* arch); static Ref GetByName(const std::string& name); static std::vector> GetList(); std::string GetName() const; virtual BNEndianness GetEndianness() const = 0; virtual size_t GetAddressSize() const = 0; virtual size_t GetDefaultIntegerSize() const; virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) = 0; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector& result) = 0; virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il); virtual std::string GetRegisterName(uint32_t reg); virtual std::string GetFlagName(uint32_t flag); virtual std::string GetFlagWriteTypeName(uint32_t flags); virtual std::vector GetFullWidthRegisters(); virtual std::vector GetAllRegisters(); virtual std::vector GetAllFlags(); virtual std::vector GetAllFlagWriteTypes(); virtual BNRegisterInfo GetRegisterInfo(uint32_t reg); virtual uint32_t GetStackPointerRegister(); virtual uint32_t GetLinkRegister(); std::vector GetModifiedRegistersOnWrite(uint32_t reg); uint32_t GetRegisterByName(const std::string& name); virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors); virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); virtual bool IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); virtual bool IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); virtual bool IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len); virtual bool IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len); virtual bool ConvertToNop(uint8_t* data, uint64_t addr, size_t len); virtual bool AlwaysBranch(uint8_t* data, uint64_t addr, size_t len); virtual bool InvertBranch(uint8_t* data, uint64_t addr, size_t len); virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value); void RegisterFunctionRecognizer(FunctionRecognizer* recog); bool IsBinaryViewTypeConstantDefined(const std::string& type, const std::string& name); uint64_t GetBinaryViewTypeConstant(const std::string& type, const std::string& name, uint64_t defaultValue = 0); void SetBinaryViewTypeConstant(const std::string& type, const std::string& name, uint64_t value); bool ParseTypesFromSource(const std::string& source, const std::string& fileName, std::map>& types, std::map>& variables, std::map>& functions, std::string& errors, const std::vector& includeDirs = std::vector()); bool ParseTypesFromSourceFile(const std::string& fileName, std::map>& types, std::map>& variables, std::map>& functions, std::string& errors, const std::vector& includeDirs = std::vector()); void RegisterCallingConvention(CallingConvention* cc); std::vector> GetCallingConventions(); Ref GetCallingConventionByName(const std::string& name); void SetDefaultCallingConvention(CallingConvention* cc); void SetCdeclCallingConvention(CallingConvention* cc); void SetStdcallCallingConvention(CallingConvention* cc); void SetFastcallCallingConvention(CallingConvention* cc); Ref GetDefaultCallingConvention(); Ref GetCdeclCallingConvention(); Ref GetStdcallCallingConvention(); Ref GetFastcallCallingConvention(); Ref GetStandalonePlatform(); }; class CoreArchitecture: public Architecture { public: CoreArchitecture(BNArchitecture* arch); virtual BNEndianness GetEndianness() const override; virtual size_t GetAddressSize() const override; virtual size_t GetDefaultIntegerSize() const override; virtual bool GetInstructionInfo(const uint8_t* data, uint64_t addr, size_t maxLen, InstructionInfo& result) override; virtual bool GetInstructionText(const uint8_t* data, uint64_t addr, size_t& len, std::vector& result) override; virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override; virtual std::string GetRegisterName(uint32_t reg) override; virtual std::string GetFlagName(uint32_t flag) override; virtual std::string GetFlagWriteTypeName(uint32_t flags) override; virtual std::vector GetFullWidthRegisters() override; virtual std::vector GetAllRegisters() override; virtual std::vector GetAllFlags() override; virtual std::vector GetAllFlagWriteTypes() override; virtual BNRegisterInfo GetRegisterInfo(uint32_t reg) override; virtual uint32_t GetStackPointerRegister() override; virtual uint32_t GetLinkRegister() override; virtual bool Assemble(const std::string& code, uint64_t addr, DataBuffer& result, std::string& errors) override; virtual bool IsNeverBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; virtual bool IsAlwaysBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; virtual bool IsInvertBranchPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; virtual bool IsSkipAndReturnZeroPatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; virtual bool IsSkipAndReturnValuePatchAvailable(const uint8_t* data, uint64_t addr, size_t len) override; virtual bool ConvertToNop(uint8_t* data, uint64_t addr, size_t len) override; virtual bool AlwaysBranch(uint8_t* data, uint64_t addr, size_t len) override; virtual bool InvertBranch(uint8_t* data, uint64_t addr, size_t len) override; virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value) override; }; class Structure; class Enumeration; struct NameAndType { std::string name; Ref type; }; class Type: public CoreRefCountObject { public: Type(BNType* type); BNTypeClass GetClass() const; uint64_t GetWidth() const; size_t GetAlignment() const; bool IsSigned() const; bool IsConst() const; bool IsFloat() const; Ref GetChildType() const; Ref GetCallingConvention() const; std::vector GetParameters() const; bool HasVariableArguments() const; bool CanReturn() const; Ref GetStructure() const; Ref GetEnumeration() const; uint64_t GetElementCount() const; std::string GetString() const; std::string GetStringBeforeName() const; std::string GetStringAfterName() const; Ref Duplicate() const; static Ref VoidType(); static Ref BoolType(); static Ref IntegerType(size_t width, bool sign); static Ref FloatType(size_t width); static Ref StructureType(Structure* strct); static Ref EnumerationType(Architecture* arch, Enumeration* enm, size_t width = 0); static Ref PointerType(Architecture* arch, Type* type, bool cnst = false); static Ref ArrayType(Type* type, uint64_t elem); static Ref FunctionType(Type* returnValue, CallingConvention* callingConvention, const std::vector& params, bool varArg = false); }; struct StructureMember { Ref type; std::string name; uint64_t offset; }; class Structure: public CoreRefCountObject { public: Structure(BNStructure* s); std::string GetName() const; void SetName(const std::string& name); std::vector GetMembers() const; uint64_t GetWidth() const; size_t GetAlignment() const; bool IsPacked() const; void SetPacked(bool packed); bool IsUnion() const; void SetUnion(bool u); void AddMember(Type* type, const std::string& name); void AddMemberAtOffset(Type* type, const std::string& name, uint64_t offset); void RemoveMember(size_t idx); }; struct EnumerationMember { std::string name; uint64_t value; bool isDefault; }; class Enumeration: public CoreRefCountObject { public: Enumeration(BNEnumeration* e); std::string GetName() const; void SetName(const std::string& name); std::vector GetMembers() const; void AddMember(const std::string& name); void AddMemberWithValue(const std::string& name, uint64_t value); }; class Function; struct BasicBlockEdge { BNBranchType type; uint64_t target; Ref arch; }; class BasicBlock: public CoreRefCountObject { public: BasicBlock(BNBasicBlock* block); Ref GetFunction() const; Ref GetArchitecture() const; uint64_t GetStart() const; uint64_t GetEnd() const; uint64_t GetLength() const; std::vector GetOutgoingEdges() const; bool HasUndeterminedOutgoingEdges() const; void MarkRecentUse(); }; struct StackVariable { Ref type; std::string name; int64_t offset; bool autoDefined; }; struct StackVariableReference { uint32_t sourceOperand; Ref type; std::string name; int64_t startingOffset; int64_t referencedOffset; }; class FunctionGraph; class Function: public CoreRefCountObject { public: Function(BNFunction* func); Ref GetArchitecture() const; Ref GetPlatform() const; uint64_t GetStart() const; Ref GetSymbol() const; bool WasAutomaticallyDiscovered() const; bool CanReturn() const; bool HasExplicitlyDefinedType() const; std::vector> GetBasicBlocks() const; void MarkRecentUse(); std::string GetCommentForAddress(uint64_t addr) const; std::vector GetCommentedAddresses() const; void SetCommentForAddress(uint64_t addr, const std::string& comment); Ref GetLowLevelIL() const; std::vector> GetLowLevelILBasicBlocks() const; size_t GetLowLevelILForInstruction(Architecture* arch, uint64_t addr); std::vector GetLowLevelILExitsForInstruction(Architecture* arch, uint64_t addr); BNRegisterValue GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg); BNRegisterValue GetRegisterValueAfterInstruction(Architecture* arch, uint64_t addr, uint32_t reg); BNRegisterValue GetRegisterValueAtLowLevelILInstruction(size_t i, uint32_t reg); BNRegisterValue GetRegisterValueAfterLowLevelILInstruction(size_t i, uint32_t reg); std::vector GetRegistersReadByInstruction(Architecture* arch, uint64_t addr); std::vector GetRegistersWrittenByInstruction(Architecture* arch, uint64_t addr); std::vector GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr); Ref GetType() const; void ApplyImportedTypes(Symbol* sym); void ApplyAutoDiscoveredType(Type* type); Ref CreateFunctionGraph(); std::map GetStackLayout(); void CreateAutoStackVariable(int64_t offset, Type* type, const std::string& name); void CreateUserStackVariable(int64_t offset, Type* type, const std::string& name); void DeleteAutoStackVariable(int64_t offset); void DeleteUserStackVariable(int64_t offset); bool GetStackVariableAtFrameOffset(int64_t offset, StackVariable& var); }; struct FunctionGraphTextLine { uint64_t addr; std::vector tokens; }; struct FunctionGraphEdge { BNBranchType type; uint64_t target; Ref arch; std::vector points; }; class FunctionGraphBlock: public CoreRefCountObject { public: FunctionGraphBlock(BNFunctionGraphBlock* block); Ref GetArchitecture() const; uint64_t GetStart() const; uint64_t GetEnd() const; int GetX() const; int GetY() const; int GetWidth() const; int GetHeight() const; std::vector GetLines() const; std::vector GetOutgoingEdges() const; }; class FunctionGraph: public RefCountObject { BNFunctionGraph* m_graph; std::function m_completeFunc; static void CompleteCallback(void* ctxt); public: FunctionGraph(BNFunctionGraph* graph); ~FunctionGraph(); BNFunctionGraph* GetGraphObject() const { return m_graph; } Ref GetFunction() const; int GetHorizontalBlockMargin() const; int GetVerticalBlockMargin() const; void SetBlockMargins(int horiz, int vert); size_t GetMaximumSymbolWidth() const; void SetMaximumSymbolWidth(size_t width); void StartLayout(BNFunctionGraphType = NormalFunctionGraph); bool IsLayoutComplete(); void OnComplete(const std::function& func); void Abort(); std::vector> GetBlocks() const; int GetWidth() const; int GetHeight() const; std::vector> GetBlocksInRegion(int left, int top, int right, int bottom); bool IsOptionSet(BNFunctionGraphOption option) const; void SetOption(BNFunctionGraphOption option, bool state = true); }; struct LowLevelILLabel: public BNLowLevelILLabel { LowLevelILLabel(); }; class LowLevelILFunction: public CoreRefCountObject { public: LowLevelILFunction(); LowLevelILFunction(BNLowLevelILFunction* func); uint64_t GetCurrentAddress() const; void SetCurrentAddress(uint64_t addr); ExprId AddExpr(BNLowLevelILOperation operation, size_t size, uint32_t flags, ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0); ExprId AddInstruction(ExprId expr); ExprId Nop(); ExprId SetRegister(size_t size, uint32_t reg, ExprId val, uint32_t flags = 0); ExprId SetRegisterSplit(size_t size, uint32_t high, uint32_t low, ExprId val); ExprId SetFlag(uint32_t flag, ExprId val); ExprId Load(size_t size, ExprId addr); ExprId Store(size_t size, ExprId addr, ExprId val); ExprId Push(size_t size, ExprId val); ExprId Pop(size_t size); ExprId Register(size_t size, uint32_t reg); ExprId Const(size_t size, uint64_t val); ExprId Flag(uint32_t reg); ExprId FlagBit(size_t size, uint32_t flag, uint32_t bitIndex); ExprId Add(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId AddCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId Sub(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId SubBorrow(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId And(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId Or(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId Xor(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId ShiftLeft(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId LogicalShiftRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId ArithShiftRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId RotateLeft(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId RotateLeftCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId RotateRight(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId RotateRightCarry(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId Mult(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId MultDoublePrecUnsigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId MultDoublePrecSigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId DivUnsigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId DivDoublePrecUnsigned(size_t size, ExprId high, ExprId low, ExprId div, uint32_t flags = 0); ExprId DivSigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId DivDoublePrecSigned(size_t size, ExprId high, ExprId low, ExprId div, uint32_t flags = 0); ExprId ModUnsigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId ModDoublePrecUnsigned(size_t size, ExprId high, ExprId low, ExprId div, uint32_t flags = 0); ExprId ModSigned(size_t size, ExprId a, ExprId b, uint32_t flags = 0); ExprId ModDoublePrecSigned(size_t size, ExprId high, ExprId low, ExprId div, uint32_t flags = 0); ExprId Neg(size_t size, ExprId a, uint32_t flags = 0); ExprId Not(size_t size, ExprId a, uint32_t flags = 0); ExprId SignExtend(size_t size, ExprId a); ExprId ZeroExtend(size_t size, ExprId a); ExprId Jump(ExprId dest); ExprId Call(ExprId dest); ExprId Return(size_t dest); ExprId NoReturn(); ExprId FlagCondition(BNLowLevelILFlagCondition cond); ExprId CompareEqual(size_t size, ExprId a, ExprId b); ExprId CompareNotEqual(size_t size, ExprId a, ExprId b); ExprId CompareSignedLessThan(size_t size, ExprId a, ExprId b); ExprId CompareUnsignedLessThan(size_t size, ExprId a, ExprId b); ExprId CompareSignedLessEqual(size_t size, ExprId a, ExprId b); ExprId CompareUnsignedLessEqual(size_t size, ExprId a, ExprId b); ExprId CompareSignedGreaterEqual(size_t size, ExprId a, ExprId b); ExprId CompareUnsignedGreaterEqual(size_t size, ExprId a, ExprId b); ExprId CompareSignedGreaterThan(size_t size, ExprId a, ExprId b); ExprId CompareUnsignedGreaterThan(size_t size, ExprId a, ExprId b); ExprId TestBit(size_t size, ExprId a, ExprId b); ExprId SystemCall(); ExprId Breakpoint(); ExprId Trap(uint32_t num); ExprId Undefined(); ExprId Unimplemented(); ExprId UnimplementedMemoryRef(size_t size, ExprId addr); ExprId Goto(BNLowLevelILLabel& label); ExprId If(ExprId operand, BNLowLevelILLabel& t, BNLowLevelILLabel& f); void MarkLabel(BNLowLevelILLabel& label); ExprId Operand(uint32_t n, ExprId expr); BNLowLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; void AddLabelForAddress(Architecture* arch, ExprId addr); BNLowLevelILLabel* GetLabelForAddress(Architecture* arch, ExprId addr); void Finalize(); bool GetExprText(Architecture* arch, ExprId expr, std::vector& tokens); bool GetInstructionText(Architecture* arch, size_t i, std::vector& tokens); }; class FunctionRecognizer { static bool RecognizeLowLevelILCallback(void* ctxt, BNBinaryView* data, BNFunction* func, BNLowLevelILFunction* il); public: FunctionRecognizer(); static void RegisterGlobalRecognizer(FunctionRecognizer* recog); static void RegisterArchitectureFunctionRecognizer(Architecture* arch, FunctionRecognizer* recog); virtual bool RecognizeLowLevelIL(BinaryView* data, Function* func, LowLevelILFunction* il); }; class UpdateException: public std::exception { const std::string m_desc; public: UpdateException(const std::string& desc): std::exception(), m_desc(desc) {} virtual const char* what() const NOEXCEPT { return m_desc.c_str(); } }; struct UpdateChannel { std::string name; std::string description; std::string latestVersion; static std::vector GetList(); bool AreUpdatesAvailable(); BNUpdateResult UpdateToVersion(const std::string& version); BNUpdateResult UpdateToVersion(const std::string& version, const std::function& progress); BNUpdateResult UpdateToLatestVersion(); BNUpdateResult UpdateToLatestVersion(const std::function& progress); }; struct UpdateVersion { std::string version; std::string notes; time_t time; static std::vector GetChannelVersions(const std::string& channel); }; struct PluginCommandContext { Ref view; uint64_t address, length; Ref function; PluginCommandContext(); }; class PluginCommand { BNPluginCommand m_command; struct RegisteredDefaultCommand { std::function action; std::function isValid; }; struct RegisteredAddressCommand { std::function action; std::function isValid; }; struct RegisteredRangeCommand { std::function action; std::function isValid; }; struct RegisteredFunctionCommand { std::function action; std::function isValid; }; static void DefaultPluginCommandActionCallback(void* ctxt, BNBinaryView* view); static void AddressPluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr); static void RangePluginCommandActionCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len); static void FunctionPluginCommandActionCallback(void* ctxt, BNBinaryView* view, BNFunction* func); static bool DefaultPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view); static bool AddressPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr); static bool RangePluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, uint64_t addr, uint64_t len); static bool FunctionPluginCommandIsValidCallback(void* ctxt, BNBinaryView* view, BNFunction* func); public: PluginCommand(const BNPluginCommand& cmd); PluginCommand(const PluginCommand& cmd); ~PluginCommand(); static void Register(const std::string& name, const std::string& description, const std::function& action); static void Register(const std::string& name, const std::string& description, const std::function& action, const std::function& isValid); static void RegisterForAddress(const std::string& name, const std::string& description, const std::function& action); static void RegisterForAddress(const std::string& name, const std::string& description, const std::function& action, const std::function& isValid); static void RegisterForRange(const std::string& name, const std::string& description, const std::function& action); static void RegisterForRange(const std::string& name, const std::string& description, const std::function& action, const std::function& isValid); static void RegisterForFunction(const std::string& name, const std::string& description, const std::function& action); static void RegisterForFunction(const std::string& name, const std::string& description, const std::function& action, const std::function& isValid); static std::vector GetList(); static std::vector GetValidList(const PluginCommandContext& ctxt); std::string GetName() const { return m_command.name; } std::string GetDescription() const { return m_command.description; } bool IsValid(const PluginCommandContext& ctxt) const; void Execute(const PluginCommandContext& ctxt) const; }; class CallingConvention: public CoreRefCountObject { protected: CallingConvention(BNCallingConvention* cc); CallingConvention(Architecture* arch, const std::string& name); static void FreeCallback(void* ctxt); static uint32_t* GetCallerSavedRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetIntegerArgumentRegistersCallback(void* ctxt, size_t* count); static uint32_t* GetFloatArgumentRegistersCallback(void* ctxt, size_t* count); static void FreeRegisterListCallback(void* ctxt, uint32_t* regs); static bool AreArgumentRegistersSharedIndexCallback(void* ctxt); static bool IsStackReservedForArgumentRegistersCallback(void* ctxt); static uint32_t GetIntegerReturnValueRegisterCallback(void* ctxt); static uint32_t GetHighIntegerReturnValueRegisterCallback(void* ctxt); static uint32_t GetFloatReturnValueRegisterCallback(void* ctxt); public: Ref GetArchitecture() const; std::string GetName() const; virtual std::vector GetCallerSavedRegisters(); virtual std::vector GetIntegerArgumentRegisters(); virtual std::vector GetFloatArgumentRegisters(); virtual bool AreArgumentRegistersSharedIndex(); virtual bool IsStackReservedForArgumentRegisters(); virtual uint32_t GetIntegerReturnValueRegister() = 0; virtual uint32_t GetHighIntegerReturnValueRegister(); virtual uint32_t GetFloatReturnValueRegister(); }; class CoreCallingConvention: public CallingConvention { public: CoreCallingConvention(BNCallingConvention* cc); virtual std::vector GetCallerSavedRegisters() override; virtual std::vector GetIntegerArgumentRegisters() override; virtual std::vector GetFloatArgumentRegisters() override; virtual bool AreArgumentRegistersSharedIndex() override; virtual bool IsStackReservedForArgumentRegisters() override; virtual uint32_t GetIntegerReturnValueRegister() override; virtual uint32_t GetHighIntegerReturnValueRegister() override; virtual uint32_t GetFloatReturnValueRegister() override; }; class Platform: public CoreRefCountObject { protected: Platform(Architecture* arch, const std::string& name); public: Platform(BNPlatform* platform); Ref GetArchitecture() const; std::string GetName() const; static void Register(const std::string& os, Platform* platform); static Ref GetByName(const std::string& name); static std::vector> GetList(); static std::vector> GetList(Architecture* arch); static std::vector> GetList(const std::string& os); static std::vector> GetList(const std::string& os, Architecture* arch); static std::vector GetOSList(); Ref GetDefaultCallingConvention() const; Ref GetCdeclCallingConvention() const; Ref GetStdcallCallingConvention() const; Ref GetFastcallCallingConvention() const; std::vector> GetCallingConventions() const; Ref GetSystemCallConvention() const; void RegisterCallingConvention(CallingConvention* cc); void RegisterDefaultCallingConvention(CallingConvention* cc); void RegisterCdeclCallingConvention(CallingConvention* cc); void RegisterStdcallCallingConvention(CallingConvention* cc); void RegisterFastcallCallingConvention(CallingConvention* cc); void SetSystemCallConvention(CallingConvention* cc); Ref GetRelatedPlatform(Architecture* arch); void AddRelatedPlatform(Architecture* arch, Platform* platform); }; }