// Copyright (c) 2015-2026 Vector 35 Inc
//
// 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.
#include
#include
#include
#include "binaryninjaapi.h"
using namespace BinaryNinja;
using namespace std;
struct SymbolQueueResolveContext
{
std::function resolve;
};
struct SymbolQueueAddContext
{
std::function add;
};
uint64_t BinaryDataNotification::NotificationBarrierCallback(void* ctxt, BNBinaryView* object)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
return notify->OnNotificationBarrier(view);
}
void BinaryDataNotification::DataWrittenCallback(void* ctxt, BNBinaryView* object, uint64_t offset, size_t len)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(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 view = new BinaryView(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 view = new BinaryView(BNNewViewReference(object));
notify->OnBinaryDataRemoved(view, offset, len);
}
void BinaryDataNotification::FunctionAddedCallback(void* ctxt, BNBinaryView* object, BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref funcObj = new Function(BNNewFunctionReference(func));
notify->OnAnalysisFunctionAdded(view, funcObj);
}
void BinaryDataNotification::FunctionRemovedCallback(void* ctxt, BNBinaryView* object, BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref funcObj = new Function(BNNewFunctionReference(func));
notify->OnAnalysisFunctionRemoved(view, funcObj);
}
void BinaryDataNotification::FunctionUpdatedCallback(void* ctxt, BNBinaryView* object, BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref funcObj = new Function(BNNewFunctionReference(func));
notify->OnAnalysisFunctionUpdated(view, funcObj);
}
void BinaryDataNotification::FunctionUpdateRequestedCallback(void* ctxt, BNBinaryView* object, BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref funcObj = new Function(BNNewFunctionReference(func));
notify->OnAnalysisFunctionUpdateRequested(view, funcObj);
}
void BinaryDataNotification::DataVariableAddedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
DataVariable varObj(var->address,
Confidence(new Type(BNNewTypeReference(var->type)), var->typeConfidence), var->autoDiscovered);
notify->OnDataVariableAdded(view, varObj);
}
void BinaryDataNotification::DataVariableRemovedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
DataVariable varObj(var->address,
Confidence(new Type(BNNewTypeReference(var->type)), var->typeConfidence), var->autoDiscovered);
notify->OnDataVariableRemoved(view, varObj);
}
void BinaryDataNotification::DataVariableUpdatedCallback(void* ctxt, BNBinaryView* object, BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
DataVariable varObj(var->address,
Confidence(new Type(BNNewTypeReference(var->type)), var->typeConfidence), var->autoDiscovered);
notify->OnDataVariableUpdated(view, varObj);
}
void BinaryDataNotification::DataMetadataUpdatedCallback(void* ctxt, BNBinaryView* object, uint64_t offset)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnDataMetadataUpdated(view, offset);
}
void BinaryDataNotification::TagTypeUpdatedCallback(void* ctxt, BNBinaryView* object, BNTagType* tagType)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref tagTypeRef = new TagType(BNNewTagTypeReference(tagType));
notify->OnTagTypeUpdated(view, tagTypeRef);
}
void BinaryDataNotification::TagAddedCallback(void* ctxt, BNBinaryView* object, BNTagReference* tagRef)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnTagAdded(view, TagReference(*tagRef));
}
void BinaryDataNotification::TagUpdatedCallback(void* ctxt, BNBinaryView* object, BNTagReference* tagRef)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnTagUpdated(view, TagReference(*tagRef));
}
void BinaryDataNotification::TagRemovedCallback(void* ctxt, BNBinaryView* object, BNTagReference* tagRef)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnTagRemoved(view, TagReference(*tagRef));
}
void BinaryDataNotification::SymbolAddedCallback(void* ctxt, BNBinaryView* object, BNSymbol* symobj)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref sym = new Symbol(BNNewSymbolReference(symobj));
notify->OnSymbolAdded(view, sym);
}
void BinaryDataNotification::SymbolUpdatedCallback(void* ctxt, BNBinaryView* object, BNSymbol* symobj)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref sym = new Symbol(BNNewSymbolReference(symobj));
notify->OnSymbolUpdated(view, sym);
}
void BinaryDataNotification::SymbolRemovedCallback(void* ctxt, BNBinaryView* object, BNSymbol* symobj)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
Ref sym = new Symbol(BNNewSymbolReference(symobj));
notify->OnSymbolRemoved(view, sym);
}
void BinaryDataNotification::StringFoundCallback(
void* ctxt, BNBinaryView* object, BNStringType type, uint64_t offset, size_t len)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnStringFound(view, type, offset, len);
}
void BinaryDataNotification::StringRemovedCallback(
void* ctxt, BNBinaryView* object, BNStringType type, uint64_t offset, size_t len)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(object));
notify->OnStringRemoved(view, type, offset, len);
}
void BinaryDataNotification::DerivedStringFoundCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
notify->OnDerivedStringFound(view, DerivedString::FromAPIObject(str, false));
}
void BinaryDataNotification::DerivedStringRemovedCallback(void* ctxt, BNBinaryView* data, BNDerivedString* str)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
notify->OnDerivedStringRemoved(view, DerivedString::FromAPIObject(str, false));
}
void BinaryDataNotification::TypeDefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref typeObj = new Type(BNNewTypeReference(type));
notify->OnTypeDefined(view, QualifiedName::FromAPIObject(name), typeObj);
}
void BinaryDataNotification::TypeUndefinedCallback(void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref typeObj = new Type(BNNewTypeReference(type));
notify->OnTypeUndefined(view, QualifiedName::FromAPIObject(name), typeObj);
}
void BinaryDataNotification::TypeReferenceChangedCallback(
void* ctxt, BNBinaryView* data, BNQualifiedName* name, BNType* type)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref typeObj = new Type(BNNewTypeReference(type));
notify->OnTypeReferenceChanged(view, QualifiedName::FromAPIObject(name), typeObj);
}
void BinaryDataNotification::TypeFieldReferenceChangedCallback(
void* ctxt, BNBinaryView* data, BNQualifiedName* name, uint64_t offset)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
notify->OnTypeFieldReferenceChanged(view, QualifiedName::FromAPIObject(name), offset);
}
void BinaryDataNotification::SegmentAddedCallback(void* ctxt, BNBinaryView* data, BNSegment* segment)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref segmentObj = new Segment(BNNewSegmentReference(segment));
notify->OnSegmentAdded(view, segmentObj);
}
void BinaryDataNotification::SegmentUpdatedCallback(void* ctxt, BNBinaryView* data, BNSegment* segment)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref segmentObj = new Segment(BNNewSegmentReference(segment));
notify->OnSegmentUpdated(view, segmentObj);
}
void BinaryDataNotification::SegmentRemovedCallback(void* ctxt, BNBinaryView* data, BNSegment* segment)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref segmentObj = new Segment(BNNewSegmentReference(segment));
notify->OnSegmentRemoved(view, segmentObj);
}
void BinaryDataNotification::SectionAddedCallback(void* ctxt, BNBinaryView* data, BNSection* section)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref sectionObj = new Section(BNNewSectionReference(section));
notify->OnSectionAdded(view, sectionObj);
}
void BinaryDataNotification::SectionUpdatedCallback(void* ctxt, BNBinaryView* data, BNSection* section)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref sectionObj = new Section(BNNewSectionReference(section));
notify->OnSectionUpdated(view, sectionObj);
}
void BinaryDataNotification::SectionRemovedCallback(void* ctxt, BNBinaryView* data, BNSection* section)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref sectionObj = new Section(BNNewSectionReference(section));
notify->OnSectionRemoved(view, sectionObj);
}
void BinaryDataNotification::ComponentNameUpdatedCallback(void* ctxt, BNBinaryView* data, char *previousName, BNComponent* bnComponent)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
std::string prevName = previousName;
BNFreeString(previousName);
notify->OnComponentNameUpdated(view, prevName, component);
}
void BinaryDataNotification::ComponentAddedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnComponent)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
notify->OnComponentAdded(view, component);
}
void BinaryDataNotification::ComponentRemovedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnFormerParent,
BNComponent* bnComponent)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref formerParent = new Component(BNNewComponentReference(bnFormerParent));
Ref component = new Component(BNNewComponentReference(bnComponent));
notify->OnComponentRemoved(view, formerParent, component);
}
void BinaryDataNotification::ComponentMovedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnFormerParent,
BNComponent* bnNewParent, BNComponent* bnComponent)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref formerParent = new Component(BNNewComponentReference(bnFormerParent));
Ref newParent = new Component(BNNewComponentReference(bnNewParent));
Ref component = new Component(BNNewComponentReference(bnComponent));
notify->OnComponentMoved(view, formerParent, newParent, component);
}
void BinaryDataNotification::ComponentFunctionAddedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnComponent,
BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
Ref function = new Function(BNNewFunctionReference(func));
notify->OnComponentFunctionAdded(view, component, function);
}
void BinaryDataNotification::ComponentFunctionRemovedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnComponent,
BNFunction* func)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
Ref function = new Function(BNNewFunctionReference(func));
notify->OnComponentFunctionRemoved(view, component, function);
}
void BinaryDataNotification::ComponentDataVariableAddedCallback(void* ctxt, BNBinaryView* data, BNComponent* bnComponent,
BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
DataVariable varObj(var->address,
Confidence(new Type(BNNewTypeReference(var->type)), var->typeConfidence), var->autoDiscovered);
notify->OnComponentDataVariableAdded(view, component, varObj);
}
void BinaryDataNotification::ComponentDataVariableRemovedCallback(void* ctxt, BNBinaryView* data,
BNComponent* bnComponent, BNDataVariable* var)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref component = new Component(BNNewComponentReference(bnComponent));
DataVariable varObj(var->address,
Confidence(new Type(BNNewTypeReference(var->type)), var->typeConfidence), var->autoDiscovered);
notify->OnComponentDataVariableRemoved(view, component, varObj);
}
void BinaryDataNotification::ExternalLibraryAddedCallback(void* ctxt, BNBinaryView* data, BNExternalLibrary* library)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref libraryObj = new ExternalLibrary(BNNewExternalLibraryReference(library));
notify->OnExternalLibraryAdded(view, libraryObj);
}
void BinaryDataNotification::ExternalLibraryUpdatedCallback(void* ctxt, BNBinaryView* data, BNExternalLibrary* library)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref libraryObj = new ExternalLibrary(BNNewExternalLibraryReference(library));
notify->OnExternalLibraryUpdated(view, libraryObj);
}
void BinaryDataNotification::ExternalLibraryRemovedCallback(void* ctxt, BNBinaryView* data, BNExternalLibrary* library)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref libraryObj = new ExternalLibrary(BNNewExternalLibraryReference(library));
notify->OnExternalLibraryRemoved(view, libraryObj);
}
void BinaryDataNotification::ExternalLocationAddedCallback(void* ctxt, BNBinaryView* data, BNExternalLocation* location)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref locationObj = new ExternalLocation(BNNewExternalLocationReference(location));
notify->OnExternalLocationAdded(view, locationObj);
}
void BinaryDataNotification::ExternalLocationUpdatedCallback(void* ctxt, BNBinaryView* data, BNExternalLocation* location)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref locationObj = new ExternalLocation(BNNewExternalLocationReference(location));
notify->OnExternalLocationUpdated(view, locationObj);
}
void BinaryDataNotification::ExternalLocationRemovedCallback(void* ctxt, BNBinaryView* data, BNExternalLocation* location)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref locationObj = new ExternalLocation(BNNewExternalLocationReference(location));
notify->OnExternalLocationRemoved(view, locationObj);
}
void BinaryDataNotification::TypeArchiveAttachedCallback(void* ctxt, BNBinaryView* data, const char* id, const char* path)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
notify->OnTypeArchiveAttached(view, id, path);
}
void BinaryDataNotification::TypeArchiveDetachedCallback(void* ctxt, BNBinaryView* data, const char* id, const char* path)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
notify->OnTypeArchiveDetached(view, id, path);
}
void BinaryDataNotification::TypeArchiveConnectedCallback(void* ctxt, BNBinaryView* data, BNTypeArchive* archive)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref apiArchive = new TypeArchive(BNNewTypeArchiveReference(archive));
notify->OnTypeArchiveConnected(view, apiArchive);
}
void BinaryDataNotification::TypeArchiveDisconnectedCallback(void* ctxt, BNBinaryView* data, BNTypeArchive* archive)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref apiArchive = new TypeArchive(BNNewTypeArchiveReference(archive));
notify->OnTypeArchiveDisconnected(view, apiArchive);
}
void BinaryDataNotification::UndoEntryAddedCallback(void* ctxt, BNBinaryView* data, BNUndoEntry* entry)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref apiEntry = new UndoEntry(BNNewUndoEntryReference(entry));
notify->OnUndoEntryAdded(view, apiEntry);
}
void BinaryDataNotification::UndoEntryTakenCallback(void* ctxt, BNBinaryView* data, BNUndoEntry* entry)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref apiEntry = new UndoEntry(BNNewUndoEntryReference(entry));
notify->OnUndoEntryTaken(view, apiEntry);
}
void BinaryDataNotification::RedoEntryTakenCallback(void* ctxt, BNBinaryView* data, BNUndoEntry* entry)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view = new BinaryView(BNNewViewReference(data));
Ref apiEntry = new UndoEntry(BNNewUndoEntryReference(entry));
notify->OnRedoEntryTaken(view, apiEntry);
}
void BinaryDataNotification::RebasedCallback(void *ctxt, BNBinaryView *oldView, BNBinaryView *newView)
{
BinaryDataNotification* notify = (BinaryDataNotification*)ctxt;
Ref view1 = new BinaryView(BNNewViewReference(oldView));
Ref view2 = new BinaryView(BNNewViewReference(newView));
notify->OnRebased(view1, view2);
}
BinaryDataNotification::BinaryDataNotification()
{
m_callbacks.context = this;
m_callbacks.notificationBarrier = nullptr;
m_callbacks.dataWritten = DataWrittenCallback;
m_callbacks.dataInserted = DataInsertedCallback;
m_callbacks.dataRemoved = DataRemovedCallback;
m_callbacks.functionAdded = FunctionAddedCallback;
m_callbacks.functionRemoved = FunctionRemovedCallback;
m_callbacks.functionUpdated = FunctionUpdatedCallback;
m_callbacks.functionUpdateRequested = FunctionUpdateRequestedCallback;
m_callbacks.dataVariableAdded = DataVariableAddedCallback;
m_callbacks.dataVariableRemoved = DataVariableRemovedCallback;
m_callbacks.dataVariableUpdated = DataVariableUpdatedCallback;
m_callbacks.dataMetadataUpdated = DataMetadataUpdatedCallback;
m_callbacks.tagTypeUpdated = TagTypeUpdatedCallback;
m_callbacks.tagAdded = TagAddedCallback;
m_callbacks.tagUpdated = TagUpdatedCallback;
m_callbacks.tagRemoved = TagRemovedCallback;
m_callbacks.symbolAdded = SymbolAddedCallback;
m_callbacks.symbolUpdated = SymbolUpdatedCallback;
m_callbacks.symbolRemoved = SymbolRemovedCallback;
m_callbacks.stringFound = StringFoundCallback;
m_callbacks.stringRemoved = StringRemovedCallback;
m_callbacks.derivedStringFound = DerivedStringFoundCallback;
m_callbacks.derivedStringRemoved = DerivedStringRemovedCallback;
m_callbacks.typeDefined = TypeDefinedCallback;
m_callbacks.typeUndefined = TypeUndefinedCallback;
m_callbacks.typeReferenceChanged = TypeReferenceChangedCallback;
m_callbacks.typeFieldReferenceChanged = TypeFieldReferenceChangedCallback;
m_callbacks.segmentAdded = SegmentAddedCallback;
m_callbacks.segmentUpdated = SegmentUpdatedCallback;
m_callbacks.segmentRemoved = SegmentRemovedCallback;
m_callbacks.sectionAdded = SectionAddedCallback;
m_callbacks.sectionUpdated = SectionUpdatedCallback;
m_callbacks.sectionRemoved = SectionRemovedCallback;
m_callbacks.componentNameUpdated = ComponentNameUpdatedCallback;
m_callbacks.componentAdded = ComponentAddedCallback;
m_callbacks.componentRemoved = ComponentRemovedCallback;
m_callbacks.componentMoved = ComponentMovedCallback;
m_callbacks.componentFunctionAdded = ComponentFunctionAddedCallback;
m_callbacks.componentFunctionRemoved = ComponentFunctionRemovedCallback;
m_callbacks.componentDataVariableAdded = ComponentDataVariableAddedCallback;
m_callbacks.componentDataVariableRemoved = ComponentDataVariableRemovedCallback;
m_callbacks.externalLibraryAdded = ExternalLibraryAddedCallback;
m_callbacks.externalLibraryUpdated = ExternalLibraryUpdatedCallback;
m_callbacks.externalLibraryRemoved = ExternalLibraryRemovedCallback;
m_callbacks.externalLocationAdded = ExternalLocationAddedCallback;
m_callbacks.externalLocationUpdated = ExternalLocationUpdatedCallback;
m_callbacks.externalLocationRemoved = ExternalLocationRemovedCallback;
m_callbacks.typeArchiveAttached = TypeArchiveAttachedCallback;
m_callbacks.typeArchiveDetached = TypeArchiveDetachedCallback;
m_callbacks.typeArchiveConnected = TypeArchiveConnectedCallback;
m_callbacks.typeArchiveDisconnected = TypeArchiveDisconnectedCallback;
m_callbacks.undoEntryAdded = UndoEntryAddedCallback;
m_callbacks.undoEntryTaken = UndoEntryTakenCallback;
m_callbacks.redoEntryTaken = RedoEntryTakenCallback;
m_callbacks.rebased = RebasedCallback;
}
BinaryDataNotification::BinaryDataNotification(NotificationTypes notifications)
{
m_callbacks.context = this;
m_callbacks.notificationBarrier = (notifications & NotificationType::NotificationBarrier) ? NotificationBarrierCallback : nullptr;
m_callbacks.dataWritten = (notifications & NotificationType::DataWritten) ? DataWrittenCallback : nullptr;
m_callbacks.dataInserted = (notifications & NotificationType::DataInserted) ? DataInsertedCallback : nullptr;
m_callbacks.dataRemoved = (notifications & NotificationType::DataRemoved) ? DataRemovedCallback : nullptr;
m_callbacks.functionAdded = (notifications & NotificationType::FunctionAdded) ? FunctionAddedCallback : nullptr;
m_callbacks.functionRemoved = (notifications & NotificationType::FunctionRemoved) ? FunctionRemovedCallback : nullptr;
m_callbacks.functionUpdated = (notifications & NotificationType::FunctionUpdated) ? FunctionUpdatedCallback : nullptr;
m_callbacks.functionUpdateRequested = (notifications & NotificationType::FunctionUpdateRequested) ? FunctionUpdateRequestedCallback : nullptr;
m_callbacks.dataVariableAdded = (notifications & NotificationType::DataVariableAdded) ? DataVariableAddedCallback : nullptr;
m_callbacks.dataVariableRemoved = (notifications & NotificationType::DataVariableRemoved) ? DataVariableRemovedCallback : nullptr;
m_callbacks.dataVariableUpdated = (notifications & NotificationType::DataVariableUpdated) ? DataVariableUpdatedCallback : nullptr;
m_callbacks.dataMetadataUpdated = (notifications & NotificationType::DataMetadataUpdated) ? DataMetadataUpdatedCallback : nullptr;
m_callbacks.tagTypeUpdated = (notifications & NotificationType::TagTypeUpdated) ? TagTypeUpdatedCallback : nullptr;
m_callbacks.tagAdded = (notifications & NotificationType::TagAdded) ? TagAddedCallback : nullptr;
m_callbacks.tagUpdated = (notifications & NotificationType::TagUpdated) ? TagUpdatedCallback : nullptr;
m_callbacks.tagRemoved = (notifications & NotificationType::TagRemoved) ? TagRemovedCallback : nullptr;
m_callbacks.symbolAdded = (notifications & NotificationType::SymbolAdded) ? SymbolAddedCallback : nullptr;
m_callbacks.symbolUpdated = (notifications & NotificationType::SymbolUpdated) ? SymbolUpdatedCallback : nullptr;
m_callbacks.symbolRemoved = (notifications & NotificationType::SymbolRemoved) ? SymbolRemovedCallback : nullptr;
m_callbacks.stringFound = (notifications & NotificationType::StringFound) ? StringFoundCallback : nullptr;
m_callbacks.stringRemoved = (notifications & NotificationType::StringRemoved) ? StringRemovedCallback : nullptr;
m_callbacks.derivedStringFound = (notifications & NotificationType::DerivedStringFound) ? DerivedStringFoundCallback : nullptr;
m_callbacks.derivedStringRemoved = (notifications & NotificationType::DerivedStringRemoved) ? DerivedStringRemovedCallback : nullptr;
m_callbacks.typeDefined = (notifications & NotificationType::TypeDefined) ? TypeDefinedCallback : nullptr;
m_callbacks.typeUndefined = (notifications & NotificationType::TypeUndefined) ? TypeUndefinedCallback : nullptr;
m_callbacks.typeReferenceChanged = (notifications & NotificationType::TypeReferenceChanged) ? TypeReferenceChangedCallback : nullptr;
m_callbacks.typeFieldReferenceChanged = (notifications & NotificationType::TypeFieldReferenceChanged) ? TypeFieldReferenceChangedCallback : nullptr;
m_callbacks.segmentAdded = (notifications & NotificationType::SegmentAdded) ? SegmentAddedCallback : nullptr;
m_callbacks.segmentUpdated = (notifications & NotificationType::SegmentUpdated) ? SegmentUpdatedCallback : nullptr;
m_callbacks.segmentRemoved = (notifications & NotificationType::SegmentRemoved) ? SegmentRemovedCallback : nullptr;
m_callbacks.sectionAdded = (notifications & NotificationType::SectionAdded) ? SectionAddedCallback : nullptr;
m_callbacks.sectionUpdated = (notifications & NotificationType::SectionUpdated) ? SectionUpdatedCallback : nullptr;
m_callbacks.sectionRemoved = (notifications & NotificationType::SectionRemoved) ? SectionRemovedCallback : nullptr;
m_callbacks.componentNameUpdated = (notifications & NotificationType::ComponentNameUpdated) ? ComponentNameUpdatedCallback : nullptr;
m_callbacks.componentAdded = (notifications & NotificationType::ComponentAdded) ? ComponentAddedCallback : nullptr;
m_callbacks.componentRemoved = (notifications & NotificationType::ComponentRemoved) ? ComponentRemovedCallback : nullptr;
m_callbacks.componentMoved = (notifications & NotificationType::ComponentMoved) ? ComponentMovedCallback : nullptr;
m_callbacks.componentFunctionAdded = (notifications & NotificationType::ComponentFunctionAdded) ? ComponentFunctionAddedCallback : nullptr;
m_callbacks.componentFunctionRemoved = (notifications & NotificationType::ComponentFunctionRemoved) ? ComponentFunctionRemovedCallback : nullptr;
m_callbacks.componentDataVariableAdded = (notifications & NotificationType::ComponentDataVariableAdded) ? ComponentDataVariableAddedCallback : nullptr;
m_callbacks.componentDataVariableRemoved = (notifications & NotificationType::ComponentDataVariableRemoved) ? ComponentDataVariableRemovedCallback : nullptr;
m_callbacks.externalLibraryAdded = (notifications & NotificationType::ExternalLibraryAdded) ? ExternalLibraryAddedCallback : nullptr;
m_callbacks.externalLibraryUpdated = (notifications & NotificationType::ExternalLibraryUpdated) ? ExternalLibraryUpdatedCallback : nullptr;
m_callbacks.externalLibraryRemoved = (notifications & NotificationType::ExternalLibraryRemoved) ? ExternalLibraryRemovedCallback : nullptr;
m_callbacks.externalLocationAdded = (notifications & NotificationType::ExternalLocationAdded) ? ExternalLocationAddedCallback : nullptr;
m_callbacks.externalLocationUpdated = (notifications & NotificationType::ExternalLocationUpdated) ? ExternalLocationUpdatedCallback : nullptr;
m_callbacks.externalLocationRemoved = (notifications & NotificationType::ExternalLocationRemoved) ? ExternalLocationRemovedCallback : nullptr;
m_callbacks.typeArchiveAttached = (notifications & NotificationType::TypeArchiveAttached) ? TypeArchiveAttachedCallback : nullptr;
m_callbacks.typeArchiveDetached = (notifications & NotificationType::TypeArchiveDetached) ? TypeArchiveDetachedCallback : nullptr;
m_callbacks.typeArchiveConnected = (notifications & NotificationType::TypeArchiveConnected) ? TypeArchiveConnectedCallback : nullptr;
m_callbacks.typeArchiveDisconnected = (notifications & NotificationType::TypeArchiveDisconnected) ? TypeArchiveDisconnectedCallback : nullptr;
m_callbacks.undoEntryAdded = (notifications & NotificationType::UndoEntryAdded) ? UndoEntryAddedCallback : nullptr;
m_callbacks.undoEntryTaken = (notifications & NotificationType::UndoEntryTaken) ? UndoEntryTakenCallback : nullptr;
m_callbacks.redoEntryTaken = (notifications & NotificationType::RedoEntryTaken) ? RedoEntryTakenCallback : nullptr;
m_callbacks.rebased = (notifications & NotificationType::Rebased) ? RebasedCallback : nullptr;
}
StringRef::StringRef()
{
m_ref = nullptr;
}
StringRef::StringRef(BNStringRef* ref)
{
m_ref = ref;
}
StringRef::StringRef(const std::string& str)
{
m_ref = BNCreateStringRefOfLength(str.c_str(), str.size());
}
StringRef::StringRef(const StringRef& other)
{
m_ref = other.m_ref ? BNDuplicateStringRef(other.m_ref) : nullptr;
}
StringRef::StringRef(StringRef&& other)
{
m_ref = other.m_ref;
other.m_ref = nullptr;
}
StringRef::~StringRef()
{
if (m_ref)
{
BNFreeStringRef(m_ref);
}
}
StringRef& StringRef::operator=(const StringRef& other)
{
if (m_ref)
{
BNFreeStringRef(m_ref);
m_ref = nullptr;
}
if (other.m_ref)
{
m_ref = BNDuplicateStringRef(other.m_ref);
}
return *this;
}
StringRef& StringRef::operator=(StringRef&& other)
{
if (m_ref)
{
BNFreeStringRef(m_ref);
}
m_ref = other.m_ref;
other.m_ref = nullptr;
return *this;
}
const char* StringRef::c_str() const
{
if (!m_ref)
return ""; // todo: nullptr?
return BNGetStringRefContents(m_ref);
}
size_t StringRef::size() const
{
if (!m_ref)
return 0;
return BNGetStringRefSize(m_ref);
}
Symbol::Symbol(BNSymbolType type, const string& shortName, const string& fullName, const string& rawName, uint64_t addr,
BNSymbolBinding binding, const NameSpace& nameSpace, uint64_t ordinal)
{
BNNameSpace ns = nameSpace.GetAPIObject();
m_object = BNCreateSymbol(type, shortName.c_str(), fullName.c_str(), rawName.c_str(), addr, binding, &ns, ordinal);
NameSpace::FreeAPIObject(&ns);
}
Symbol::Symbol(BNSymbolType type, const std::string& name, uint64_t addr, BNSymbolBinding binding,
const NameSpace& nameSpace, uint64_t ordinal)
{
BNNameSpace ns = nameSpace.GetAPIObject();
m_object = BNCreateSymbol(type, name.c_str(), name.c_str(), name.c_str(), addr, binding, &ns, ordinal);
NameSpace::FreeAPIObject(&ns);
}
Symbol::Symbol(BNSymbolType type, const string& shortName, const string& fullName, const string& rawName, uint64_t addr,
BNNameSpace* nameSpace, BNSymbolBinding binding, uint64_t ordinal)
{
m_object = BNCreateSymbol(type, shortName.c_str(), fullName.c_str(), rawName.c_str(), addr, binding, nameSpace, ordinal);
}
Symbol::Symbol(BNSymbolType type, const std::string& name, uint64_t addr, BNNameSpace* nameSpace, BNSymbolBinding binding, uint64_t ordinal)
{
m_object = BNCreateSymbol(type, name.c_str(), name.c_str(), name.c_str(), addr, binding, nameSpace, ordinal);
}
Symbol::Symbol(BNSymbol* sym)
{
m_object = sym;
}
BNSymbolType Symbol::GetType() const
{
return BNGetSymbolType(m_object);
}
BNSymbolBinding Symbol::GetBinding() const
{
return BNGetSymbolBinding(m_object);
}
NameSpace Symbol::GetNameSpace() const
{
BNNameSpace name = BNGetSymbolNameSpace(m_object);
NameSpace result = NameSpace::FromAPIObject(&name);
BNFreeNameSpace(&name);
return result;
}
string Symbol::GetShortName() const
{
char* name = BNGetSymbolShortName(m_object);
string result = name;
BNFreeString(name);
return result;
}
StringRef Symbol::GetShortNameRef() const
{
BNStringRef* name = BNGetSymbolShortNameRef(m_object);
return StringRef(name);
}
string Symbol::GetFullName() const
{
char* name = BNGetSymbolFullName(m_object);
string result = name;
BNFreeString(name);
return result;
}
StringRef Symbol::GetFullNameRef() const
{
BNStringRef* name = BNGetSymbolFullNameRef(m_object);
return StringRef(name);
}
string Symbol::GetRawName() const
{
char* name = BNGetSymbolRawName(m_object);
string result = name;
BNFreeString(name);
return result;
}
StringRef Symbol::GetRawNameRef() const
{
BNStringRef* name = BNGetSymbolRawNameRef(m_object);
return StringRef(name);
}
uint64_t Symbol::GetAddress() const
{
return BNGetSymbolAddress(m_object);
}
uint64_t Symbol::GetOrdinal() const
{
return BNGetSymbolOrdinal(m_object);
}
bool Symbol::IsAutoDefined() const
{
return BNIsSymbolAutoDefined(m_object);
}
Ref Symbol::ImportedFunctionFromImportAddressSymbol(Symbol* sym, uint64_t addr)
{
return new Symbol(BNImportedFunctionFromImportAddressSymbol(sym->GetObject(), addr));
}
AnalysisCompletionEvent::AnalysisCompletionEvent(BinaryView* view, const std::function& callback) :
m_callback(callback)
{
m_object = BNAddAnalysisCompletionEvent(view->GetObject(), this, CompletionCallback);
}
void AnalysisCompletionEvent::CompletionCallback(void* ctxt)
{
AnalysisCompletionEvent* event = (AnalysisCompletionEvent*)ctxt;
unique_lock lock(event->m_mutex);
event->m_callback();
event->m_callback = []() {
};
}
void AnalysisCompletionEvent::Cancel()
{
unique_lock lock(m_mutex);
m_callback = []() {
};
// This allows the API side to free the BinaryNinja::AnalysisCompletionEvent object
BNCancelAnalysisCompletionEvent(m_object);
}
TagType::TagType(BNTagType* tagType)
{
m_object = tagType;
}
TagType::TagType(BinaryView* view)
{
m_object = BNCreateTagType(view->GetObject());
}
TagType::TagType(BinaryView* view, const std::string& name, const std::string& icon, bool visible, TagType::Type type)
{
m_object = BNCreateTagType(view->GetObject());
SetName(name);
SetIcon(icon);
SetVisible(visible);
SetType(type);
}
BinaryView* TagType::GetView() const
{
return new BinaryView(BNTagTypeGetView(m_object));
}
std::string TagType::GetId() const
{
char* str = BNTagTypeGetId(m_object);
string result = str;
BNFreeString(str);
return result;
}
std::string TagType::GetName() const
{
char* str = BNTagTypeGetName(m_object);
string result = str;
BNFreeString(str);
return result;
}
void TagType::SetName(const std::string& name)
{
BNTagTypeSetName(m_object, name.c_str());
}
std::string TagType::GetIcon() const
{
char* str = BNTagTypeGetIcon(m_object);
string result = str;
BNFreeString(str);
return result;
}
void TagType::SetIcon(const std::string& icon)
{
BNTagTypeSetIcon(m_object, icon.c_str());
}
bool TagType::GetVisible() const
{
return BNTagTypeGetVisible(m_object);
}
void TagType::SetVisible(bool visible)
{
BNTagTypeSetVisible(m_object, visible);
}
TagType::Type TagType::GetType() const
{
return BNTagTypeGetType(m_object);
}
void TagType::SetType(TagType::Type type)
{
BNTagTypeSetType(m_object, type);
}
Tag::Tag(BNTag* tag)
{
m_object = tag;
}
Tag::Tag(Ref type, const std::string& data)
{
m_object = BNCreateTag(type->GetObject(), data.c_str());
}
std::string Tag::GetId() const
{
char* id = BNTagGetId(m_object);
std::string result = id;
BNFreeString(id);
return result;
}
Ref Tag::GetType() const
{
return new TagType(BNTagGetType(m_object));
}
std::string Tag::GetData() const
{
char* str = BNTagGetData(m_object);
string result = str;
BNFreeString(str);
return result;
}
void Tag::SetData(const std::string& data)
{
BNTagSetData(m_object, data.c_str());
}
BNTag** Tag::CreateTagList(const std::vector& tags, size_t* count)
{
*count = tags.size();
BNTag** result = new BNTag*[tags.size()];
for (size_t i = 0; i < tags.size(); i++)
result[i] = tags[i]->GetObject();
return result;
}
std::vector Tag::ConvertTagList(BNTag** tags, size_t count)
{
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.emplace_back(new Tag(BNNewTagReference(tags[i])));
return result;
}
void Tag::FreeTagList(BNTag** tags, size_t count)
{
delete[] tags;
(void)count;
}
std::vector Tag::ConvertAndFreeTagList(BNTag** tags, size_t count)
{
auto result = ConvertTagList(tags, count);
BNFreeTagList(tags, count);
return result;
}
TagReference::TagReference() {}
TagReference::TagReference(const BNTagReference& ref)
{
refType = ref.refType;
autoDefined = ref.autoDefined;
tag = ref.tag ? new Tag(BNNewTagReference(ref.tag)) : nullptr;
arch = ref.arch ? new CoreArchitecture(ref.arch) : nullptr;
func = ref.func ? new Function(BNNewFunctionReference(ref.func)) : nullptr;
addr = ref.addr;
}
bool TagReference::EqualsByData(const TagReference& other) const
{
if (refType != other.refType)
return false;
if (autoDefined != other.autoDefined)
return false;
if (addr != other.addr)
return false;
if (func != other.func)
return false;
if (arch != other.arch)
return false;
if (tag->GetData() != other.tag->GetData())
return false;
return true;
}
bool TagReference::operator==(const TagReference& other) const
{
if (refType != other.refType)
return false;
if (autoDefined != other.autoDefined)
return false;
if (tag != other.tag)
return false;
switch (refType)
{
case AddressTagReference:
return func == other.func && arch == other.arch && addr == other.addr;
case FunctionTagReference:
return func == other.func;
case DataTagReference:
return addr == other.addr;
default:
return false;
}
}
bool TagReference::operator!=(const TagReference& other) const
{
return !((*this) == other);
}
TagReference::operator BNTagReference() const
{
BNTagReference ret;
ret.refType = refType;
ret.autoDefined = autoDefined;
ret.tag = tag->GetObject();
ret.arch = arch ? arch->GetObject() : nullptr;
ret.func = func ? func->GetObject() : nullptr;
ret.addr = addr;
return ret;
}
BNTagReference* TagReference::CreateTagReferenceList(const std::vector& tags, size_t* count)
{
*count = tags.size();
BNTagReference* refs = new BNTagReference[*count];
for (size_t i = 0; i < *count; i++)
{
refs[i] = tags[i];
}
return refs;
}
std::vector TagReference::ConvertTagReferenceList(BNTagReference* tags, size_t count)
{
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.emplace_back(tags[i]);
}
return result;
}
void TagReference::FreeTagReferenceList(BNTagReference* tags, size_t count)
{
delete[] tags;
(void)count;
}
std::vector TagReference::ConvertAndFreeTagReferenceList(BNTagReference* tags, size_t count)
{
auto result = ConvertTagReferenceList(tags, count);
BNFreeTagReferences(tags, count);
return result;
}
Segment::Segment(BNSegment* seg)
{
m_object = seg;
}
uint64_t Segment::GetStart() const
{
return BNSegmentGetStart(m_object);
}
uint64_t Segment::GetLength() const
{
return BNSegmentGetLength(m_object);
}
uint64_t Segment::GetEnd() const
{
return BNSegmentGetEnd(m_object);
}
uint64_t Segment::GetDataEnd() const
{
return BNSegmentGetDataEnd(m_object);
}
uint64_t Segment::GetDataOffset() const
{
return BNSegmentGetDataOffset(m_object);
}
uint64_t Segment::GetDataLength() const
{
return BNSegmentGetDataLength(m_object);
}
uint32_t Segment::GetFlags() const
{
return BNSegmentGetFlags(m_object);
}
bool Segment::IsAutoDefined() const
{
return BNSegmentIsAutoDefined(m_object);
}
Section::Section(BNSection* sec)
{
m_object = sec;
}
std::string Section::GetName() const
{
char* str = BNSectionGetName(m_object);
string result = str;
BNFreeString(str);
return result;
}
std::string Section::GetType() const
{
char* str = BNSectionGetType(m_object);
string result = str;
BNFreeString(str);
return result;
}
uint64_t Section::GetStart() const
{
return BNSectionGetStart(m_object);
}
uint64_t Section::GetLength() const
{
return BNSectionGetLength(m_object);
}
uint64_t Section::GetEnd() const
{
return BNSectionGetEnd(m_object);
}
uint64_t Section::GetInfoData() const
{
return BNSectionGetInfoData(m_object);
}
uint64_t Section::GetAlignment() const
{
return BNSectionGetAlign(m_object);
}
uint64_t Section::GetEntrySize() const
{
return BNSectionGetEntrySize(m_object);
}
std::string Section::GetLinkedSection() const
{
char* str = BNSectionGetLinkedSection(m_object);
string result = str;
BNFreeString(str);
return result;
}
std::string Section::GetInfoSection() const
{
char* str = BNSectionGetInfoSection(m_object);
string result = str;
BNFreeString(str);
return result;
}
BNSectionSemantics Section::GetSemantics() const
{
return BNSectionGetSemantics(m_object);
}
bool Section::AutoDefined() const
{
return BNSectionIsAutoDefined(m_object);
}
BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryView* parentView)
{
BNCustomBinaryView view;
view.context = this;
view.init = InitCallback;
view.freeObject = FreeCallback;
view.externalRefTaken = nullptr;
view.externalRefReleased = nullptr;
view.read = ReadCallback;
view.write = WriteCallback;
view.insert = InsertCallback;
view.remove = RemoveCallback;
view.getModification = GetModificationCallback;
view.isValidOffset = IsValidOffsetCallback;
view.isOffsetReadable = IsOffsetReadableCallback;
view.isOffsetWritable = IsOffsetWritableCallback;
view.isOffsetExecutable = IsOffsetExecutableCallback;
view.isOffsetBackedByFile = IsOffsetBackedByFileCallback;
view.getNextValidOffset = GetNextValidOffsetCallback;
view.getStart = GetStartCallback;
view.getLength = GetLengthCallback;
view.getEntryPoint = GetEntryPointCallback;
view.isExecutable = IsExecutableCallback;
view.getDefaultEndianness = GetDefaultEndiannessCallback;
view.isRelocatable = IsRelocatableCallback;
view.getAddressSize = GetAddressSizeCallback;
view.save = SaveCallback;
view.onAfterSnapshotDataApplied = OnAfterSnapshotDataAppliedCallback;
m_file = file;
AddRefForRegistration();
m_object = BNCreateCustomBinaryView(
typeName.c_str(), m_file->GetObject(), parentView ? parentView->GetObject() : nullptr, &view);
m_memoryMap = std::make_unique(m_object);
}
BinaryView::BinaryView(BNBinaryView* view)
{
m_object = view;
m_file = new FileMetadata(BNGetFileForView(m_object));
m_memoryMap = std::make_unique(m_object);
}
bool BinaryView::InitCallback(void* ctxt)
{
try
{
CallbackRef view(ctxt);
return view->Init();
}
catch (const std::exception& e)
{
LogError("BinaryView::Init failed: %s", e.what());
return false;
}
catch (...)
{
LogError("BinaryView::Init failed with unknown exception");
return false;
}
}
void BinaryView::OnAfterSnapshotDataAppliedCallback(void* ctxt)
{
try
{
CallbackRef view(ctxt);
view->OnAfterSnapshotDataApplied();
}
catch (const std::exception& e)
{
LogError("BinaryView::OnAfterSnapshotDataApplied failed: %s", e.what());
}
catch (...)
{
LogError("BinaryView::OnAfterSnapshotDataApplied failed with unknown exception");
}
}
void BinaryView::FreeCallback(void* ctxt)
{
BinaryView* view = (BinaryView*)ctxt;
view->ReleaseForRegistration();
}
size_t BinaryView::ReadCallback(void* ctxt, void* dest, uint64_t offset, size_t len)
{
CallbackRef view(ctxt);
return view->PerformRead(dest, offset, len);
}
size_t BinaryView::WriteCallback(void* ctxt, uint64_t offset, const void* src, size_t len)
{
CallbackRef view(ctxt);
return view->PerformWrite(offset, src, len);
}
size_t BinaryView::InsertCallback(void* ctxt, uint64_t offset, const void* src, size_t len)
{
CallbackRef view(ctxt);
return view->PerformInsert(offset, src, len);
}
size_t BinaryView::RemoveCallback(void* ctxt, uint64_t offset, uint64_t len)
{
CallbackRef view(ctxt);
return view->PerformRemove(offset, len);
}
BNModificationStatus BinaryView::GetModificationCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformGetModification(offset);
}
bool BinaryView::IsValidOffsetCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformIsValidOffset(offset);
}
bool BinaryView::IsOffsetReadableCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformIsOffsetReadable(offset);
}
bool BinaryView::IsOffsetWritableCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformIsOffsetWritable(offset);
}
bool BinaryView::IsOffsetExecutableCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformIsOffsetExecutable(offset);
}
bool BinaryView::IsOffsetBackedByFileCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformIsOffsetBackedByFile(offset);
}
uint64_t BinaryView::GetNextValidOffsetCallback(void* ctxt, uint64_t offset)
{
CallbackRef view(ctxt);
return view->PerformGetNextValidOffset(offset);
}
uint64_t BinaryView::GetStartCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformGetStart();
}
uint64_t BinaryView::GetLengthCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformGetLength();
}
uint64_t BinaryView::GetEntryPointCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformGetEntryPoint();
}
bool BinaryView::IsExecutableCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformIsExecutable();
}
BNEndianness BinaryView::GetDefaultEndiannessCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformGetDefaultEndianness();
}
bool BinaryView::IsRelocatableCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformIsRelocatable();
}
size_t BinaryView::GetAddressSizeCallback(void* ctxt)
{
CallbackRef view(ctxt);
return view->PerformGetAddressSize();
}
bool BinaryView::SaveCallback(void* ctxt, BNFileAccessor* file)
{
try
{
CallbackRef view(ctxt);
CoreFileAccessor accessor(file);
return view->PerformSave(&accessor);
}
catch (const std::exception& e)
{
LogError("BinaryView::Save failed: %s", e.what());
return false;
}
catch (...)
{
LogError("BinaryView::Save failed with unknown exception");
return false;
}
}
bool BinaryView::PerformIsValidOffset(uint64_t offset)
{
uint8_t val;
return PerformRead(&val, offset, 1) == 1;
}
bool BinaryView::PerformIsOffsetReadable(uint64_t offset)
{
return PerformIsValidOffset(offset);
}
bool BinaryView::PerformIsOffsetWritable(uint64_t offset)
{
return PerformIsValidOffset(offset);
}
bool BinaryView::PerformIsOffsetExecutable(uint64_t offset)
{
return PerformIsValidOffset(offset);
}
bool BinaryView::PerformIsOffsetBackedByFile(uint64_t offset)
{
return PerformIsValidOffset(offset);
}
uint64_t BinaryView::PerformGetNextValidOffset(uint64_t offset)
{
if (offset < PerformGetStart())
return PerformGetStart();
return offset;
}
BNEndianness BinaryView::PerformGetDefaultEndianness() const
{
Ref arch = GetDefaultArchitecture();
if (arch)
return arch->GetEndianness();
return LittleEndian;
}
bool BinaryView::PerformIsRelocatable() const
{
return false;
}
size_t BinaryView::PerformGetAddressSize() const
{
Ref arch = GetDefaultArchitecture();
if (arch)
return arch->GetAddressSize();
if (GetEnd() > (1LL Save(file);
return false;
}
void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc)
{
DefineRelocation(arch, info, target, reloc);
}
void BinaryView::PerformDefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref target, uint64_t reloc)
{
DefineRelocation(arch, info, target, reloc);
}
void BinaryView::NotifyDataWritten(uint64_t offset, size_t len)
{
BNNotifyDataWritten(m_object, offset, len);
}
void BinaryView::NotifyDataInserted(uint64_t offset, size_t len)
{
BNNotifyDataInserted(m_object, offset, len);
}
void BinaryView::NotifyDataRemoved(uint64_t offset, uint64_t len)
{
BNNotifyDataRemoved(m_object, offset, len);
}
Ref BinaryView::GetParentView() const
{
BNBinaryView* view = BNGetParentView(m_object);
if (!view)
return nullptr;
return new BinaryView(view);
}
string BinaryView::GetTypeName() const
{
char* str = BNGetViewType(m_object);
string result = str;
BNFreeString(str);
return result;
}
bool BinaryView::IsModified() const
{
return BNIsViewModified(m_object);
}
bool BinaryView::IsAnalysisChanged() const
{
return m_file->IsAnalysisChanged();
}
bool BinaryView::CreateDatabase(const string& path, Ref settings)
{
auto parent = GetParentView();
if (parent)
return parent->CreateDatabase(path, settings);
return m_file->CreateDatabase(path, this, settings);
}
bool BinaryView::CreateDatabase(const string& path,
const ProgressFunction& progressCallback, Ref settings)
{
auto parent = GetParentView();
if (parent)
return parent->CreateDatabase(path, settings);
return m_file->CreateDatabase(path, this, progressCallback, settings);
}
bool BinaryView::SaveAutoSnapshot(Ref settings)
{
return m_file->SaveAutoSnapshot(this, settings);
}
bool BinaryView::SaveAutoSnapshot(
const ProgressFunction& progressCallback, Ref settings)
{
return m_file->SaveAutoSnapshot(this, progressCallback, settings);
}
bool BinaryView::RunUndoableTransaction(std::function func)
{
return m_file->RunUndoableTransaction(func);
}
string BinaryView::BeginUndoActions(bool anonymousAllowed)
{
return m_file->BeginUndoActions(anonymousAllowed);
}
void BinaryView::CommitUndoActions(const string& id)
{
m_file->CommitUndoActions(id);
}
void BinaryView::RevertUndoActions(const string& id)
{
m_file->RevertUndoActions(id);
}
void BinaryView::ForgetUndoActions(const std::string &id)
{
m_file->ForgetUndoActions(id);
}
bool BinaryView::CanUndo()
{
return m_file->CanUndo();
}
bool BinaryView::Undo()
{
return m_file->Undo();
}
bool BinaryView::CanRedo()
{
return m_file->CanRedo();
}
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);
}
DataBuffer BinaryView::ReadBuffer(uint64_t offset, size_t len)
{
BNDataBuffer* result = BNReadViewBuffer(m_object, offset, len);
return DataBuffer(result);
}
const uint8_t* BinaryView::GetDataPointer() const
{
return BNGetViewDataPointer(m_object);
}
size_t BinaryView::GetDataLength() const
{
return BNGetViewDataLength(m_object);
}
size_t BinaryView::WriteBuffer(uint64_t offset, const DataBuffer& data)
{
return BNWriteViewBuffer(m_object, offset, data.GetBufferObject());
}
size_t BinaryView::InsertBuffer(uint64_t offset, const DataBuffer& data)
{
return BNInsertViewBuffer(m_object, offset, data.GetBufferObject());
}
vector BinaryView::GetEntropy(uint64_t offset, size_t len, size_t blockSize)
{
if (!blockSize)
blockSize = len;
float* entopy = new float[(len / blockSize) + 1];
len = BNGetEntropy(m_object, offset, len, blockSize, entopy);
vector result;
result.reserve(len);
for (size_t i = 0; i < len; i++)
result.push_back(entopy[i]);
delete[] entopy;
return result;
}
vector BinaryView::GetModification(uint64_t offset, size_t len)
{
BNModificationStatus* mod = new BNModificationStatus[len];
len = BNGetModificationArray(m_object, offset, mod, len);
vector result;
result.reserve(len);
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_object);
}
bool BinaryView::Save(const string& path)
{
return BNSaveToFilename(m_object, path.c_str());
}
bool BinaryView::FinalizeNewSegments()
{
return BNBinaryViewFinalizeNewSegments(m_object);
}
void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, uint64_t target, uint64_t reloc)
{
BNDefineRelocation(m_object, arch->GetObject(), &info, target, reloc);
}
void BinaryView::DefineRelocation(Architecture* arch, BNRelocationInfo& info, Ref target, uint64_t reloc)
{
BNDefineSymbolRelocation(m_object, arch->GetObject(), &info, target->GetObject(), reloc);
}
vector BinaryView::GetRelocationRanges() const
{
size_t count = 0;
BNRange* ranges = BNGetRelocationRanges(m_object, &count);
vector result(count);
for (size_t i = 0; i < count; i++)
{
result.push_back({ranges[i].start, ranges[i].end});
}
BNFreeRelocationRanges(ranges);
return result;
}
vector BinaryView::GetRelocationRangesAtAddress(uint64_t addr) const
{
size_t count = 0;
BNRange* ranges = BNGetRelocationRangesAtAddress(m_object, addr, &count);
vector result(count);
for (size_t i = 0; i < count; i++)
{
result.push_back({ranges[i].start, ranges[i].end});
}
BNFreeRelocationRanges(ranges);
return result;
}
vector BinaryView::GetRelocationRangesInRange(uint64_t addr, size_t size) const
{
size_t count = 0;
BNRange* ranges = BNGetRelocationRangesInRange(m_object, addr, size, &count);
vector result(count);
for (size_t i = 0; i < count; i++)
{
result.push_back({ranges[i].start, ranges[i].end});
}
BNFreeRelocationRanges(ranges);
return result;
}
bool BinaryView::RangeContainsRelocation(uint64_t addr, size_t size) const
{
return BNRangeContainsRelocation(m_object, addr, size);
}
std::vector BinaryView::GetRelocationsAt(uint64_t addr) const
{
size_t count = 0;
BNRelocation** relocations = BNGetRelocationsAt(m_object, addr, &count);
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.push_back(new Relocation(BNNewRelocationReference(relocations[i])));
}
BNFreeRelocationList(relocations, count);
return result;
}
void BinaryView::RegisterNotification(BinaryDataNotification* notify)
{
BNRegisterDataNotification(m_object, notify->GetCallbacks());
}
void BinaryView::UnregisterNotification(BinaryDataNotification* notify)
{
BNUnregisterDataNotification(m_object, notify->GetCallbacks());
}
size_t BinaryView::Read(void* dest, uint64_t offset, size_t len)
{
return BNReadViewData(m_object, dest, offset, len);
}
size_t BinaryView::Write(uint64_t offset, const void* data, size_t len)
{
return BNWriteViewData(m_object, offset, data, len);
}
size_t BinaryView::Insert(uint64_t offset, const void* data, size_t len)
{
return BNInsertViewData(m_object, offset, data, len);
}
size_t BinaryView::Remove(uint64_t offset, uint64_t len)
{
return BNRemoveViewData(m_object, offset, len);
}
BNModificationStatus BinaryView::GetModification(uint64_t offset)
{
return BNGetModification(m_object, offset);
}
bool BinaryView::IsValidOffset(uint64_t offset) const
{
return BNIsValidOffset(m_object, offset);
}
bool BinaryView::IsOffsetReadable(uint64_t offset) const
{
return BNIsOffsetReadable(m_object, offset);
}
bool BinaryView::IsOffsetWritable(uint64_t offset) const
{
return BNIsOffsetWritable(m_object, offset);
}
bool BinaryView::IsOffsetExecutable(uint64_t offset) const
{
return BNIsOffsetExecutable(m_object, offset);
}
bool BinaryView::IsOffsetBackedByFile(uint64_t offset) const
{
return BNIsOffsetBackedByFile(m_object, offset);
}
bool BinaryView::IsOffsetCodeSemantics(uint64_t offset) const
{
return BNIsOffsetCodeSemantics(m_object, offset);
}
bool BinaryView::IsOffsetExternSemantics(uint64_t offset) const
{
return BNIsOffsetExternSemantics(m_object, offset);
}
bool BinaryView::IsOffsetWritableSemantics(uint64_t offset) const
{
return BNIsOffsetWritableSemantics(m_object, offset);
}
bool BinaryView::IsOffsetReadOnlySemantics(uint64_t offset) const
{
return BNIsOffsetReadOnlySemantics(m_object, offset);
}
uint64_t BinaryView::GetNextValidOffset(uint64_t offset) const
{
return BNGetNextValidOffset(m_object, offset);
}
uint64_t BinaryView::GetImageBase() const
{
return BNGetImageBase(m_object);
}
uint64_t BinaryView::GetOriginalImageBase() const
{
return BNGetOriginalImageBase(m_object);
}
void BinaryView::SetOriginalImageBase(uint64_t imageBase)
{
return BNSetOriginalImageBase(m_object, imageBase);
}
uint64_t BinaryView::GetOriginalBase() const
{
return BNGetOriginalImageBase(m_object);
}
void BinaryView::SetOriginalBase(uint64_t base)
{
return BNSetOriginalImageBase(m_object, base);
}
uint64_t BinaryView::GetStart() const
{
return BNGetStartOffset(m_object);
}
uint64_t BinaryView::GetLength() const
{
return BNGetViewLength(m_object);
}
uint64_t BinaryView::GetEntryPoint() const
{
return BNGetEntryPoint(m_object);
}
Ref BinaryView::GetDefaultArchitecture() const
{
BNArchitecture* arch = BNGetDefaultArchitecture(m_object);
if (!arch)
return nullptr;
return new CoreArchitecture(arch);
}
void BinaryView::SetDefaultArchitecture(Architecture* arch)
{
if (arch)
BNSetDefaultArchitecture(m_object, arch->GetObject());
else
BNSetDefaultArchitecture(m_object, nullptr);
}
Ref BinaryView::GetDefaultPlatform() const
{
BNPlatform* platform = BNGetDefaultPlatform(m_object);
if (!platform)
return nullptr;
return new CorePlatform(platform);
}
void BinaryView::SetDefaultPlatform(Platform* platform)
{
if (platform)
BNSetDefaultPlatform(m_object, platform->GetObject());
else
BNSetDefaultPlatform(m_object, nullptr);
}
BNEndianness BinaryView::GetDefaultEndianness() const
{
return BNGetDefaultEndianness(m_object);
}
bool BinaryView::IsRelocatable() const
{
return BNIsRelocatable(m_object);
}
size_t BinaryView::GetAddressSize() const
{
return BNGetViewAddressSize(m_object);
}
bool BinaryView::IsExecutable() const
{
return BNIsExecutableView(m_object);
}
bool BinaryView::Save(FileAccessor* file)
{
return BNSaveToFile(m_object, file->GetCallbacks());
}
void BinaryView::AddAnalysisOption(const string& name)
{
BNAddAnalysisOption(m_object, name.c_str());
}
Ref BinaryView::AddFunctionForAnalysis(Platform* platform, uint64_t addr, bool autoDiscovered, Type* type)
{
BNFunction* func = BNAddFunctionForAnalysis(
m_object, platform->GetObject(), addr, autoDiscovered, type ? type->GetObject() : nullptr);
if (!func)
return nullptr;
return new Function(func);
}
void BinaryView::AddEntryPointForAnalysis(Platform* platform, uint64_t addr)
{
BNAddEntryPointForAnalysis(m_object, platform->GetObject(), addr);
}
void BinaryView::AddToEntryFunctions(Function* func)
{
BNAddToEntryFunctions(m_object, func->GetObject());
}
void BinaryView::RemoveAnalysisFunction(Function* func, bool updateRefs)
{
BNRemoveAnalysisFunction(m_object, func->GetObject(), updateRefs);
}
Ref BinaryView::CreateUserFunction(Platform* platform, uint64_t start)
{
BNFunction* func = BNCreateUserFunction(m_object, platform->GetObject(), start);
if (!func)
return nullptr;
return new Function(func);
}
void BinaryView::RemoveUserFunction(Function* func)
{
BNRemoveUserFunction(m_object, func->GetObject());
}
bool BinaryView::HasInitialAnalysis()
{
return BNHasInitialAnalysis(m_object);
}
void BinaryView::SetAnalysisHold(bool enable)
{
BNSetAnalysisHold(m_object, enable);
}
bool BinaryView::GetFunctionAnalysisUpdateDisabled()
{
return BNGetFunctionAnalysisUpdateDisabled(m_object);
}
void BinaryView::SetFunctionAnalysisUpdateDisabled(bool disabled)
{
BNSetFunctionAnalysisUpdateDisabled(m_object, disabled);
}
void BinaryView::UpdateAnalysisAndWait()
{
BNUpdateAnalysisAndWait(m_object);
}
void BinaryView::UpdateAnalysis()
{
BNUpdateAnalysis(m_object);
}
void BinaryView::AbortAnalysis()
{
BNAbortAnalysis(m_object);
}
bool BinaryView::AnalysisIsAborted() const
{
return BNAnalysisIsAborted(m_object);
}
void BinaryView::DefineDataVariable(uint64_t addr, const Confidence& type)
{
BNTypeWithConfidence tc;
tc.type = type->GetObject();
tc.confidence = type.GetConfidence();
BNDefineDataVariable(m_object, addr, &tc);
}
void BinaryView::DefineUserDataVariable(uint64_t addr, const Confidence& type)
{
BNTypeWithConfidence tc;
tc.type = type->GetObject();
tc.confidence = type.GetConfidence();
BNDefineUserDataVariable(m_object, addr, &tc);
}
void BinaryView::UndefineDataVariable(uint64_t addr, bool blacklist)
{
BNUndefineDataVariable(m_object, addr, blacklist);
}
void BinaryView::UndefineUserDataVariable(uint64_t addr)
{
BNUndefineUserDataVariable(m_object, addr);
}
map BinaryView::GetDataVariables()
{
size_t count;
BNDataVariable* vars = BNGetDataVariables(m_object, &count);
map result;
for (size_t i = 0; i < count; i++)
{
result.emplace(piecewise_construct, forward_as_tuple(vars[i].address),
forward_as_tuple(vars[i].address,
Confidence(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence),
vars[i].autoDiscovered));
}
BNFreeDataVariables(vars, count);
return result;
}
bool BinaryView::GetDataVariableAtAddress(uint64_t addr, DataVariable& var)
{
var.address = 0;
var.type = Confidence(nullptr, 0);
var.autoDiscovered = false;
BNDataVariable result;
if (!BNGetDataVariableAtAddress(m_object, addr, &result))
return false;
var.address = result.address;
var.type = Confidence(new Type(result.type), result.typeConfidence);
var.autoDiscovered = result.autoDiscovered;
return true;
}
vector BinaryView::GetAnalysisFunctionList()
{
size_t count;
BNFunction** list = BNGetAnalysisFunctionList(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Function(BNNewFunctionReference(list[i])));
BNFreeFunctionList(list, count);
return result;
}
AnalysisInfo BinaryView::GetAnalysisInfo()
{
AnalysisInfo result;
BNAnalysisInfo* info = BNGetAnalysisInfo(m_object);
result.state = info->state;
result.analysisTime = info->analysisTime;
result.activeInfo.reserve(info->count);
for (size_t i = 0; i < info->count; i++)
result.activeInfo.emplace_back(new Function(BNNewFunctionReference(info->activeInfo[i].func)),
info->activeInfo[i].analysisTime, info->activeInfo[i].submitCount, info->activeInfo[i].updateCount);
BNFreeAnalysisInfo(info);
return result;
}
bool BinaryView::HasFunctions() const
{
return BNHasFunctions(m_object);
}
bool BinaryView::HasSymbols() const
{
return BNHasSymbols(m_object);
}
bool BinaryView::HasDataVariables() const
{
return BNHasDataVariables(m_object);
}
Ref BinaryView::GetAnalysisFunction(Platform* platform, uint64_t addr)
{
if (!platform)
return nullptr;
BNFunction* func = BNGetAnalysisFunction(m_object, platform->GetObject(), addr);
if (!func)
return nullptr;
return new Function(func);
}
Ref BinaryView::GetRecentAnalysisFunctionForAddress(uint64_t addr)
{
BNFunction* func = BNGetRecentAnalysisFunctionForAddress(m_object, addr);
if (!func)
return nullptr;
return new Function(func);
}
vector BinaryView::GetAnalysisFunctionsForAddress(uint64_t addr)
{
size_t count;
BNFunction** list = BNGetAnalysisFunctionsForAddress(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Function(BNNewFunctionReference(list[i])));
BNFreeFunctionList(list, count);
return result;
}
vector BinaryView::GetAnalysisFunctionsContainingAddress(uint64_t addr)
{
size_t count;
BNFunction** list = BNGetAnalysisFunctionsContainingAddress(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Function(BNNewFunctionReference(list[i])));
BNFreeFunctionList(list, count);
return result;
}
Ref BinaryView::GetAnalysisEntryPoint()
{
BNFunction* func = BNGetAnalysisEntryPoint(m_object);
if (!func)
return nullptr;
return new Function(func);
}
vector BinaryView::GetAllEntryFunctions()
{
size_t count;
BNFunction** funcs = BNGetAllEntryFunctions(m_object, &count);
if (count == 0)
return {};
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Function(BNNewFunctionReference(funcs[i])));
BNFreeFunctionList(funcs, count);
return result;
}
Ref BinaryView::GetRecentBasicBlockForAddress(uint64_t addr)
{
BNBasicBlock* block = BNGetRecentBasicBlockForAddress(m_object, addr);
if (!block)
return nullptr;
return new BasicBlock(block);
}
vector BinaryView::GetBasicBlocksForAddress(uint64_t addr)
{
size_t count;
BNBasicBlock** blocks = BNGetBasicBlocksForAddress(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
BNFreeBasicBlockList(blocks, count);
return result;
}
vector BinaryView::GetBasicBlocksStartingAtAddress(uint64_t addr)
{
size_t count;
BNBasicBlock** blocks = BNGetBasicBlocksStartingAtAddress(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
BNFreeBasicBlockList(blocks, count);
return result;
}
vector BinaryView::GetCodeReferences(uint64_t addr)
{
size_t count;
BNReferenceSource* refs = BNGetCodeReferences(m_object, addr, &count, false, 0);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferences(uint64_t addr, uint64_t len)
{
size_t count;
BNReferenceSource* refs = BNGetCodeReferencesInRange(m_object, addr, len, &count, false, 0);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesWithLimit(uint64_t addr, std::optional maxItems)
{
size_t count;
BNReferenceSource* refs = BNGetCodeReferences(m_object, addr, &count, maxItems.has_value(), maxItems.value_or(0));
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesInRangeWithLimit(
uint64_t addr, uint64_t len, std::optional maxItems)
{
size_t count;
BNReferenceSource* refs =
BNGetCodeReferencesInRange(m_object, addr, len, &count, maxItems.has_value(), maxItems.value_or(0));
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesFrom(ReferenceSource src)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
uint64_t* refs = BNGetCodeReferencesFrom(m_object, &_src, &count);
vector result(refs, &refs[count]);
BNFreeAddressList(refs);
return result;
}
vector BinaryView::GetCodeReferencesFrom(ReferenceSource src, uint64_t len)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
uint64_t* refs = BNGetCodeReferencesFromInRange(m_object, &_src, len, &count);
vector result(refs, &refs[count]);
BNFreeAddressList(refs);
return result;
}
vector BinaryView::GetDataReferences(uint64_t addr)
{
size_t count;
uint64_t* refs = BNGetDataReferences(m_object, addr, &count, false, 0);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferences(uint64_t addr, uint64_t len)
{
size_t count;
uint64_t* refs = BNGetDataReferencesInRange(m_object, addr, len, &count, false, 0);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferencesWithLimit(uint64_t addr, std::optional maxItems)
{
size_t count;
uint64_t* refs = BNGetDataReferences(m_object, addr, &count, maxItems.has_value(), maxItems.value_or(0));
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferencesInRangeWithLimit(
uint64_t addr, uint64_t len, std::optional maxItems)
{
size_t count;
uint64_t* refs =
BNGetDataReferencesInRange(m_object, addr, len, &count, maxItems.has_value(), maxItems.value_or(0));
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferencesFrom(uint64_t addr)
{
size_t count;
uint64_t* refs = BNGetDataReferencesFrom(m_object, addr, &count);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferencesFrom(uint64_t addr, uint64_t len)
{
size_t count;
uint64_t* refs = BNGetDataReferencesFromInRange(m_object, addr, len, &count);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
void BinaryView::AddDataReference(uint64_t fromAddr, uint64_t toAddr)
{
BNAddDataReference(m_object, fromAddr, toAddr);
}
void BinaryView::RemoveDataReference(uint64_t fromAddr, uint64_t toAddr)
{
BNRemoveDataReference(m_object, fromAddr, toAddr);
}
void BinaryView::AddUserDataReference(uint64_t fromAddr, uint64_t toAddr)
{
BNAddUserDataReference(m_object, fromAddr, toAddr);
}
void BinaryView::RemoveUserDataReference(uint64_t fromAddr, uint64_t toAddr)
{
BNRemoveUserDataReference(m_object, fromAddr, toAddr);
}
vector BinaryView::GetCodeReferencesForType(const QualifiedName& type, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNReferenceSource* refs =
BNGetCodeReferencesForType(m_object, &nameObj, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
vector BinaryView::GetDataReferencesForType(const QualifiedName& type, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
uint64_t* refs = BNGetDataReferencesForType(m_object, &nameObj, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetTypeReferencesForType(
const QualifiedName& type, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeReferenceSource* refs =
BNGetTypeReferencesForType(m_object, &nameObj, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesForTypeField(
const QualifiedName& type, uint64_t offset, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeFieldReference* refs =
BNGetCodeReferencesForTypeField(m_object, &nameObj, offset, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeFieldReference src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
src.size = refs[i].size;
BNTypeWithConfidence& tc = refs[i].incomingType;
Ref type = tc.type ? new Type(BNNewTypeReference(tc.type)) : nullptr;
src.incomingType = Confidence(type, tc.confidence);
result.push_back(src);
}
BNFreeTypeFieldReferences(refs, count);
return result;
}
vector BinaryView::GetDataReferencesForTypeField(
const QualifiedName& type, uint64_t offset, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
uint64_t* refs =
BNGetDataReferencesForTypeField(m_object, &nameObj, offset, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetDataReferencesFromForTypeField(
const QualifiedName& type, uint64_t offset, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
uint64_t* refs = BNGetDataReferencesFromForTypeField(
m_object, &nameObj, offset, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result(refs, &refs[count]);
BNFreeDataReferences(refs);
return result;
}
vector BinaryView::GetTypeReferencesForTypeField(
const QualifiedName& type, uint64_t offset, std::optional maxItems)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeReferenceSource* refs =
BNGetTypeReferencesForTypeField(m_object, &nameObj, offset, &count, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
AllTypeReferences BinaryView::GetAllReferencesForType(const QualifiedName& type, std::optional maxItems)
{
BNQualifiedName nameObj = type.GetAPIObject();
BNAllTypeReferences refs =
BNGetAllReferencesForType(m_object, &nameObj, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
AllTypeReferences result;
result.codeRefs.reserve(refs.codeRefCount);
for (size_t i = 0; i < refs.codeRefCount; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs.codeRefs[i].func));
src.arch = new CoreArchitecture(refs.codeRefs[i].arch);
src.addr = refs.codeRefs[i].addr;
result.codeRefs.push_back(src);
}
result.dataRefs = vector(refs.dataRefs, &refs.dataRefs[refs.dataRefCount]);
result.typeRefs.reserve(refs.typeRefCount);
for (size_t i = 0; i < refs.typeRefCount; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs.typeRefs[i].name);
src.offset = refs.typeRefs[i].offset;
src.type = refs.typeRefs[i].type;
result.typeRefs.push_back(src);
}
BNFreeAllTypeReferences(&refs);
return result;
}
AllTypeFieldReferences BinaryView::GetAllReferencesForTypeField(
const QualifiedName& type, uint64_t offset, std::optional maxItems)
{
BNQualifiedName nameObj = type.GetAPIObject();
BNAllTypeFieldReferences refs =
BNGetAllReferencesForTypeField(m_object, &nameObj, offset, maxItems.has_value(), maxItems.value_or(0));
QualifiedName::FreeAPIObject(&nameObj);
AllTypeFieldReferences result;
result.codeRefs.reserve(refs.codeRefCount);
for (size_t i = 0; i < refs.codeRefCount; i++)
{
TypeFieldReference src;
src.func = new Function(BNNewFunctionReference(refs.codeRefs[i].func));
src.arch = new CoreArchitecture(refs.codeRefs[i].arch);
src.addr = refs.codeRefs[i].addr;
src.size = refs.codeRefs[i].size;
BNTypeWithConfidence& tc = refs.codeRefs[i].incomingType;
Ref type = tc.type ? new Type(BNNewTypeReference(tc.type)) : nullptr;
src.incomingType = Confidence(type, tc.confidence);
result.codeRefs.push_back(src);
}
result.dataRefsTo = vector(refs.dataRefsTo, &refs.dataRefsTo[refs.dataRefToCount]);
result.dataRefsFrom = vector(refs.dataRefsFrom, &refs.dataRefsFrom[refs.dataRefFromCount]);
result.typeRefs.reserve(refs.typeRefCount);
for (size_t i = 0; i < refs.typeRefCount; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs.typeRefs[i].name);
src.offset = refs.typeRefs[i].offset;
src.type = refs.typeRefs[i].type;
result.typeRefs.push_back(src);
}
BNFreeAllTypeFieldReferences(&refs);
return result;
}
vector BinaryView::GetCodeReferencesForTypeFrom(ReferenceSource src)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
BNTypeReferenceSource* refs = BNGetCodeReferencesForTypeFrom(m_object, &_src, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesForTypeFrom(ReferenceSource src, uint64_t len)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
BNTypeReferenceSource* refs = BNGetCodeReferencesForTypeFromInRange(m_object, &_src, len, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesForTypeFieldFrom(ReferenceSource src)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
BNTypeReferenceSource* refs = BNGetCodeReferencesForTypeFieldsFrom(m_object, &_src, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
vector BinaryView::GetCodeReferencesForTypeFieldFrom(ReferenceSource src, uint64_t len)
{
size_t count;
BNReferenceSource _src {src.func->m_object, src.arch->m_object, src.addr};
BNTypeReferenceSource* refs = BNGetCodeReferencesForTypeFieldsFromInRange(m_object, &_src, len, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
TypeReferenceSource src;
src.name = QualifiedName::FromAPIObject(&refs[i].name);
src.offset = refs[i].offset;
src.type = refs[i].type;
result.push_back(src);
}
BNFreeTypeReferences(refs, count);
return result;
}
vector BinaryView::GetAllFieldsReferenced(const QualifiedName& type)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
uint64_t* fields = BNGetAllFieldsReferenced(m_object, &nameObj, &count);
vector result(fields, &fields[count]);
// Data refs and the fields above are both an array of uint64_t, so they can be freed in
// the same way
BNFreeDataReferences(fields);
return result;
}
std::map BinaryView::GetAllSizesReferenced(const QualifiedName& type)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeFieldReferenceSizeInfo* fields = BNGetAllSizesReferenced(m_object, &nameObj, &count);
std::map result;
for (size_t i = 0; i < count; i++)
{
auto& sizes = result[fields[i].offset];
for (size_t j = 0; j < fields[i].count; j++)
{
sizes.push_back(fields[i].sizes[j]);
}
}
BNFreeTypeFieldReferenceSizeInfo(fields, count);
return result;
}
std::map BinaryView::GetAllTypesReferenced(const QualifiedName& type)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeFieldReferenceTypeInfo* fields = BNGetAllTypesReferenced(m_object, &nameObj, &count);
std::map result;
for (size_t i = 0; i < count; i++)
{
auto& types = result[fields[i].offset];
for (size_t j = 0; j < fields[i].count; j++)
{
BNTypeWithConfidence tc = fields[i].types[j];
Ref type = tc.type ? new Type(BNNewTypeReference(tc.type)) : nullptr;
types.push_back(Confidence(type, tc.confidence));
}
}
BNFreeTypeFieldReferenceTypeInfo(fields, count);
return result;
}
std::vector BinaryView::GetSizesReferenced(const QualifiedName& type, uint64_t offset)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
size_t* refs = BNGetSizesReferenced(m_object, &nameObj, offset, &count);
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result[i] = refs[i];
BNFreeTypeFieldReferenceSizes(refs, count);
return result;
}
std::vector BinaryView::GetTypesReferenced(const QualifiedName& type, uint64_t offset)
{
size_t count;
BNQualifiedName nameObj = type.GetAPIObject();
BNTypeWithConfidence* types = BNGetTypesReferenced(m_object, &nameObj, offset, &count);
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
BNTypeWithConfidence tc = types[i];
Ref type = tc.type ? new Type(BNNewTypeReference(tc.type)) : nullptr;
result.push_back(Confidence(type, tc.confidence));
}
BNFreeTypeFieldReferenceTypes(types, count);
return result;
}
unordered_set BinaryView::GetOutgoingDirectTypeReferences(const QualifiedName& type)
{
size_t count;
BNQualifiedName apiType = type.GetAPIObject();
BNQualifiedName* apiResult = BNGetOutgoingDirectTypeReferences(m_object, &apiType, &count);
QualifiedName::FreeAPIObject(&apiType);
if (!apiResult)
return {};
unordered_set result;
for (size_t i = 0; i < count; i ++)
{
result.insert(QualifiedName::FromAPIObject(&apiResult[i]));
}
BNFreeTypeNameList(apiResult, count);
return result;
}
unordered_set BinaryView::GetOutgoingRecursiveTypeReferences(const QualifiedName& type)
{
return GetOutgoingRecursiveTypeReferences(unordered_set{type});
}
unordered_set BinaryView::GetOutgoingRecursiveTypeReferences(const unordered_set& types)
{
size_t count;
vector apiTypes;
apiTypes.reserve(types.size());
for (auto& type: types)
{
apiTypes.push_back(type.GetAPIObject());
}
BNQualifiedName* apiResult = BNGetOutgoingRecursiveTypeReferences(m_object, apiTypes.data(), apiTypes.size(), &count);
for (auto& type: apiTypes)
{
QualifiedName::FreeAPIObject(&type);
}
if (!apiResult)
return {};
unordered_set result;
for (size_t i = 0; i < count; i ++)
{
result.insert(QualifiedName::FromAPIObject(&apiResult[i]));
}
BNFreeTypeNameList(apiResult, count);
return result;
}
unordered_set BinaryView::GetIncomingDirectTypeReferences(const QualifiedName& type)
{
size_t count;
BNQualifiedName apiType = type.GetAPIObject();
BNQualifiedName* apiResult = BNGetIncomingDirectTypeReferences(m_object, &apiType, &count);
QualifiedName::FreeAPIObject(&apiType);
if (!apiResult)
return {};
unordered_set result;
for (size_t i = 0; i < count; i ++)
{
result.insert(QualifiedName::FromAPIObject(&apiResult[i]));
}
BNFreeTypeNameList(apiResult, count);
return result;
}
unordered_set BinaryView::GetIncomingRecursiveTypeReferences(const QualifiedName& type)
{
return GetIncomingRecursiveTypeReferences(unordered_set{type});
}
unordered_set BinaryView::GetIncomingRecursiveTypeReferences(const unordered_set& types)
{
size_t count;
vector apiTypes;
apiTypes.reserve(types.size());
for (auto& type: types)
{
apiTypes.push_back(type.GetAPIObject());
}
BNQualifiedName* apiResult = BNGetIncomingRecursiveTypeReferences(m_object, apiTypes.data(), apiTypes.size(), &count);
for (auto& type: apiTypes)
{
QualifiedName::FreeAPIObject(&type);
}
if (!apiResult)
return {};
unordered_set result;
for (size_t i = 0; i < count; i ++)
{
result.insert(QualifiedName::FromAPIObject(&apiResult[i]));
}
BNFreeTypeNameList(apiResult, count);
return result;
}
vector BinaryView::GetCallees(ReferenceSource callSite)
{
size_t count;
BNReferenceSource src {callSite.func->m_object, callSite.arch->m_object, callSite.addr};
uint64_t* refs = BNGetCallees(m_object, &src, &count);
vector result(refs, &refs[count]);
BNFreeAddressList(refs);
return result;
}
vector BinaryView::GetCallers(uint64_t addr)
{
size_t count;
BNReferenceSource* refs = BNGetCallers(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
Ref BinaryView::GetSymbolByAddress(uint64_t addr, const NameSpace& nameSpace)
{
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol* sym = BNGetSymbolByAddress(m_object, addr, &ns);
NameSpace::FreeAPIObject(&ns);
if (!sym)
return nullptr;
return new Symbol(sym);
}
Ref BinaryView::GetSymbolByRawName(const string& name, const NameSpace& nameSpace)
{
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol* sym = BNGetSymbolByRawName(m_object, name.c_str(), &ns);
NameSpace::FreeAPIObject(&ns);
if (!sym)
return nullptr;
return new Symbol(sym);
}
vector BinaryView::GetSymbolsByName(const string& name, const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbolsByName(m_object, name.c_str(), &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
vector BinaryView::GetSymbolsByRawName(const string& name, const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbolsByRawName(m_object, name.c_str(), &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
vector BinaryView::GetSymbols(const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbols(m_object, &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
vector BinaryView::GetSymbols(uint64_t start, uint64_t len, const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbolsInRange(m_object, start, len, &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
vector BinaryView::GetSymbolsOfType(BNSymbolType type, const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbolsOfType(m_object, type, &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
vector BinaryView::GetSymbolsOfType(
BNSymbolType type, uint64_t start, uint64_t len, const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetSymbolsOfTypeInRange(m_object, type, start, len, &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
std::vector BinaryView::GetVisibleSymbols(const NameSpace& nameSpace)
{
size_t count;
BNNameSpace ns = nameSpace.GetAPIObject();
BNSymbol** syms = BNGetVisibleSymbols(m_object, &count, &ns);
NameSpace::FreeAPIObject(&ns);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Symbol(BNNewSymbolReference(syms[i])));
BNFreeSymbolList(syms, count);
return result;
}
void BinaryView::DefineAutoSymbol(Ref sym)
{
BNDefineAutoSymbol(m_object, sym->GetObject());
}
Ref BinaryView::DefineAutoSymbolAndVariableOrFunction(Ref platform, Ref sym, const Confidence& type)
{
BNTypeWithConfidence apiType = {type.GetValue() ? type.GetValue()->GetObject() : nullptr, type.GetConfidence()};
BNSymbol* result = BNDefineAutoSymbolAndVariableOrFunction(
m_object, platform ? platform->GetObject() : nullptr, sym->GetObject(), &apiType);
if (!result)
return nullptr;
return new Symbol(result);
}
void BinaryView::UndefineAutoSymbol(Ref sym)
{
BNUndefineAutoSymbol(m_object, sym->GetObject());
}
void BinaryView::DefineUserSymbol(Ref sym)
{
BNDefineUserSymbol(m_object, sym->GetObject());
}
void BinaryView::UndefineUserSymbol(Ref sym)
{
BNUndefineUserSymbol(m_object, sym->GetObject());
}
void BinaryView::DefineImportedFunction(Ref importAddressSym, Ref func, Ref type)
{
BNDefineImportedFunction(
m_object, importAddressSym->GetObject(), func->GetObject(), type ? type->GetObject() : nullptr);
}
Ref BinaryView::GetDebugInfo()
{
BNDebugInfo* result = BNGetDebugInfo(m_object);
if (!result)
return nullptr;
return new DebugInfo(result);
}
void BinaryView::ApplyDebugInfo(Ref newDebugInfo)
{
BNApplyDebugInfo(m_object, newDebugInfo->GetObject());
}
void BinaryView::SetDebugInfo(Ref newDebugInfo)
{
BNSetDebugInfo(m_object, newDebugInfo->GetObject());
}
bool BinaryView::IsApplyingDebugInfo() const
{
return BNIsApplyingDebugInfo(m_object);
}
void BinaryView::BeginBulkModifySymbols()
{
BNBeginBulkModifySymbols(m_object);
}
void BinaryView::EndBulkModifySymbols()
{
BNEndBulkModifySymbols(m_object);
}
void BinaryView::AddTagType(Ref tagType)
{
BNAddTagType(m_object, tagType->GetObject());
}
void BinaryView::RemoveTagType(Ref tagType)
{
BNRemoveTagType(m_object, tagType->GetObject());
}
Ref BinaryView::GetTagType(const std::string& name)
{
return GetTagTypeByName(name);
}
Ref BinaryView::GetTagType(const std::string& name, TagType::Type type)
{
return GetTagTypeByName(name, type);
}
Ref BinaryView::GetTagTypeByName(const std::string& name)
{
BNTagType* tagType = BNGetTagType(m_object, name.c_str());
if (!tagType)
return nullptr;
return Ref(new TagType(tagType));
}
Ref BinaryView::GetTagTypeByName(const std::string& name, TagType::Type type)
{
BNTagType* tagType = BNGetTagTypeWithType(m_object, name.c_str(), type);
if (!tagType)
return nullptr;
return Ref(new TagType(tagType));
}
Ref BinaryView::GetTagTypeById(const std::string& name)
{
BNTagType* tagType = BNGetTagTypeById(m_object, name.c_str());
if (!tagType)
return nullptr;
return Ref(new TagType(tagType));
}
Ref BinaryView::GetTagTypeById(const std::string& name, TagType::Type type)
{
BNTagType* tagType = BNGetTagTypeByIdWithType(m_object, name.c_str(), type);
if (!tagType)
return nullptr;
return Ref(new TagType(tagType));
}
std::vector BinaryView::GetTagTypes()
{
size_t count;
BNTagType** tagTypes = BNGetTagTypes(m_object, &count);
std::vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.push_back(new TagType(BNNewTagTypeReference(tagTypes[i])));
}
BNFreeTagTypeList(tagTypes, count);
return result;
}
void BinaryView::AddTag(Ref tag, bool user)
{
BNAddTag(m_object, tag->GetObject(), user);
}
void BinaryView::RemoveTag(Ref tag, bool user)
{
BNRemoveTag(m_object, tag->GetObject(), user);
}
Ref BinaryView::GetTag(const string& tagId)
{
BNTag* tag = BNGetTag(m_object, tagId.c_str());
if (!tag)
return nullptr;
return Ref(new Tag(tag));
}
std::vector BinaryView::GetAllTagReferences()
{
size_t count;
BNTagReference* refs = BNGetAllTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetAllAddressTagReferences()
{
size_t count;
BNTagReference* refs = BNGetAllAddressTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetAllFunctionTagReferences()
{
size_t count;
BNTagReference* refs = BNGetAllFunctionTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetAllTagReferencesOfType(Ref tagType)
{
size_t count;
BNTagReference* refs = BNGetAllTagReferencesOfType(m_object, tagType->GetObject(), &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetTagReferencesOfType(Ref tagType)
{
size_t count;
BNTagReference* refs = BNGetTagReferencesOfType(m_object, tagType->GetObject(), &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
size_t BinaryView::GetAllTagReferencesOfTypeCount(Ref tagType)
{
return BNGetAllTagReferencesOfTypeCount(m_object, tagType->GetObject());
}
std::map BinaryView::GetAllTagReferenceTypeCounts()
{
BNTagType** types;
size_t* counts;
size_t count;
BNGetAllTagReferenceTypeCounts(m_object, &types, &counts, &count);
std::map result;
for (size_t i = 0; i < count; i++)
{
result[new TagType(BNNewTagTypeReference(types[i]))] = counts[i];
}
BNFreeTagReferenceTypeCounts(types, counts, count);
return result;
}
size_t BinaryView::GetTagReferencesOfTypeCount(Ref tagType)
{
return BNGetTagReferencesOfTypeCount(m_object, tagType->GetObject());
}
std::vector BinaryView::GetDataTagReferences()
{
size_t count;
BNTagReference* refs = BNGetDataTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetAutoDataTagReferences()
{
size_t count;
BNTagReference* refs = BNGetAutoDataTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetUserDataTagReferences()
{
size_t count;
BNTagReference* refs = BNGetUserDataTagReferences(m_object, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetDataTags(uint64_t addr)
{
size_t count;
BNTag** tags = BNGetDataTags(m_object, addr, &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetAutoDataTags(uint64_t addr)
{
size_t count;
BNTag** tags = BNGetAutoDataTags(m_object, addr, &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetUserDataTags(uint64_t addr)
{
size_t count;
BNTag** tags = BNGetUserDataTags(m_object, addr, &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetDataTagsOfType(uint64_t addr, Ref tagType)
{
size_t count;
BNTag** tags = BNGetDataTagsOfType(m_object, addr, tagType->GetObject(), &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetAutoDataTagsOfType(uint64_t addr, Ref tagType)
{
size_t count;
BNTag** tags = BNGetAutoDataTagsOfType(m_object, addr, tagType->GetObject(), &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetUserDataTagsOfType(uint64_t addr, Ref tagType)
{
size_t count;
BNTag** tags = BNGetUserDataTagsOfType(m_object, addr, tagType->GetObject(), &count);
return Tag::ConvertAndFreeTagList(tags, count);
}
std::vector BinaryView::GetDataTagsInRange(uint64_t start, uint64_t end)
{
size_t count;
BNTagReference* refs = BNGetDataTagsInRange(m_object, start, end, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetAutoDataTagsInRange(uint64_t start, uint64_t end)
{
size_t count;
BNTagReference* refs = BNGetAutoDataTagsInRange(m_object, start, end, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
std::vector BinaryView::GetUserDataTagsInRange(uint64_t start, uint64_t end)
{
size_t count;
BNTagReference* refs = BNGetUserDataTagsInRange(m_object, start, end, &count);
return TagReference::ConvertAndFreeTagReferenceList(refs, count);
}
void BinaryView::AddAutoDataTag(uint64_t addr, Ref tag)
{
BNAddAutoDataTag(m_object, addr, tag->GetObject());
}
void BinaryView::RemoveAutoDataTag(uint64_t addr, Ref tag)
{
BNRemoveAutoDataTag(m_object, addr, tag->GetObject());
}
void BinaryView::RemoveAutoDataTagsOfType(uint64_t addr, Ref tagType)
{
BNRemoveAutoDataTagsOfType(m_object, addr, tagType->GetObject());
}
void BinaryView::AddUserDataTag(uint64_t addr, Ref tag)
{
BNAddUserDataTag(m_object, addr, tag->GetObject());
}
void BinaryView::RemoveUserDataTag(uint64_t addr, Ref tag)
{
BNRemoveUserDataTag(m_object, addr, tag->GetObject());
}
void BinaryView::RemoveUserDataTagsOfType(uint64_t addr, Ref tagType)
{
BNRemoveUserDataTagsOfType(m_object, addr, tagType->GetObject());
}
void BinaryView::RemoveTagReference(const TagReference& ref)
{
BNRemoveTagReference(m_object, (BNTagReference)ref);
}
Ref BinaryView::CreateAutoDataTag(
uint64_t addr, const std::string& tagTypeName, const std::string& data, bool unique)
{
Ref tagType = GetTagTypeByName(tagTypeName);
if (!tagType)
return nullptr;
return CreateAutoDataTag(addr, tagType, data, unique);
}
Ref BinaryView::CreateUserDataTag(
uint64_t addr, const std::string& tagTypeName, const std::string& data, bool unique)
{
Ref tagType = GetTagTypeByName(tagTypeName);
if (!tagType)
return nullptr;
return CreateUserDataTag(addr, tagType, data, unique);
}
Ref BinaryView::CreateAutoDataTag(uint64_t addr, Ref tagType, const std::string& data, bool unique)
{
if (unique)
{
auto tags = GetDataTags(addr);
for (const auto& tag : tags)
{
if (tag->GetType() == tagType && tag->GetData() == data)
return nullptr;
}
}
Ref tag = new Tag(tagType, data);
AddTag(tag);
AddAutoDataTag(addr, tag);
return tag;
}
Ref BinaryView::CreateUserDataTag(uint64_t addr, Ref tagType, const std::string& data, bool unique)
{
if (unique)
{
auto tags = GetDataTags(addr);
for (const auto& tag : tags)
{
if (tag->GetType() == tagType && tag->GetData() == data)
return nullptr;
}
}
Ref tag = new Tag(tagType, data);
AddTag(tag);
AddUserDataTag(addr, tag);
return tag;
}
std::optional BinaryView::GetComponentByGuid(std::string guid)
{
BNComponent* bncomponent = BNGetComponentByGuid(m_object, guid.c_str());
if (bncomponent)
{
auto component = new Component(bncomponent);
return std::optional{component};
}
return std::nullopt;
}
Ref BinaryView::GetRootComponent()
{
BNComponent* bncomponent = BNGetRootComponent(m_object);
return new Component(bncomponent);
}
std::optional BinaryView::GetComponentByPath(std::string path)
{
BNComponent* component = BNGetComponentByPath(this->m_object, path.c_str());
if (component)
return {new Component(component)};
return std::nullopt;
}
Ref BinaryView::CreateComponent()
{
auto bnComponent = BNCreateComponent(m_object);
return new Component(bnComponent);
}
Ref BinaryView::CreateComponent(std::string parentGUID)
{
BNComponent* bnComponent;
if (!parentGUID.empty())
bnComponent = BNCreateComponentWithParent(m_object, parentGUID.c_str());
else
bnComponent = BNCreateComponent(m_object);
return new Component(bnComponent);
}
Ref BinaryView::CreateComponent(Ref parent)
{
BNComponent* bnComponent;
if (parent)
bnComponent = BNCreateComponentWithParent(m_object, parent->GetGuid().c_str());
else
bnComponent = BNCreateComponent(m_object);
return new Component(bnComponent);
}
Ref BinaryView::CreateComponentWithName(std::string name, std::string parentGUID)
{
BNComponent* bnComponent;
if (!parentGUID.empty())
bnComponent = BNCreateComponentWithParentAndName(m_object, parentGUID.c_str(), name.c_str());
else
bnComponent = BNCreateComponentWithName(m_object, name.c_str());
return new Component(bnComponent);
}
Ref BinaryView::CreateComponentWithName(std::string name, Ref parent)
{
auto bnComponent = BNCreateComponentWithParentAndName(m_object, parent->GetGuid().c_str(), name.c_str());
return new Component(bnComponent);
}
bool BinaryView::RemoveComponent(Ref component)
{
return BNRemoveComponent(m_object, component->m_object);
}
bool BinaryView::RemoveComponent(std::string guid)
{
return BNRemoveComponentByGuid(m_object, guid.c_str());
}
std::vector BinaryView::GetFunctionParentComponents(Ref function) const
{
std::vector components;
size_t count;
BNComponent** list = BNGetFunctionParentComponents(m_object, function->m_object, &count);
components.reserve(count);
for (size_t i = 0; i < count; i++)
{
Ref component = new Component(BNNewComponentReference(list[i]));
components.push_back(component);
}
BNFreeComponents(list, count);
return components;
}
std::vector BinaryView::GetDataVariableParentComponents(DataVariable var) const
{
std::vector components;
size_t count;
BNComponent** list = BNGetDataVariableParentComponents(m_object, var.address, &count);
components.reserve(count);
for (size_t i = 0; i < count; i++)
{
Ref component = new Component(BNNewComponentReference(list[i]));
components.push_back(component);
}
BNFreeComponents(list, count);
return components;
}
std::optional BinaryView::CheckForStringAnnotationType(uint64_t addr, string& value, bool allowShortStrings, bool allowLargeStrings, size_t childWidth)
{
char* str = nullptr;
BNStringType type;
bool result = BNCheckForStringAnnotationType(m_object, addr, &str, &type,
allowShortStrings, allowLargeStrings, childWidth);
if (result)
{
value = string(str);
BNFreeString(str);
return type;
}
return std::nullopt;
}
bool BinaryView::CanAssemble(Architecture* arch)
{
return BNCanAssemble(m_object, arch->GetObject());
}
bool BinaryView::IsNeverBranchPatchAvailable(Architecture* arch, uint64_t addr)
{
return BNIsNeverBranchPatchAvailable(m_object, arch->GetObject(), addr);
}
bool BinaryView::IsAlwaysBranchPatchAvailable(Architecture* arch, uint64_t addr)
{
return BNIsAlwaysBranchPatchAvailable(m_object, arch->GetObject(), addr);
}
bool BinaryView::IsInvertBranchPatchAvailable(Architecture* arch, uint64_t addr)
{
return BNIsInvertBranchPatchAvailable(m_object, arch->GetObject(), addr);
}
bool BinaryView::IsSkipAndReturnZeroPatchAvailable(Architecture* arch, uint64_t addr)
{
return BNIsSkipAndReturnZeroPatchAvailable(m_object, arch->GetObject(), addr);
}
bool BinaryView::IsSkipAndReturnValuePatchAvailable(Architecture* arch, uint64_t addr)
{
return BNIsSkipAndReturnValuePatchAvailable(m_object, arch->GetObject(), addr);
}
bool BinaryView::ConvertToNop(Architecture* arch, uint64_t addr)
{
return BNConvertToNop(m_object, arch->GetObject(), addr);
}
bool BinaryView::AlwaysBranch(Architecture* arch, uint64_t addr)
{
return BNAlwaysBranch(m_object, arch->GetObject(), addr);
}
bool BinaryView::InvertBranch(Architecture* arch, uint64_t addr)
{
return BNInvertBranch(m_object, arch->GetObject(), addr);
}
bool BinaryView::SkipAndReturnValue(Architecture* arch, uint64_t addr, uint64_t value)
{
return BNSkipAndReturnValue(m_object, arch->GetObject(), addr, value);
}
size_t BinaryView::GetInstructionLength(Architecture* arch, uint64_t addr)
{
return BNGetInstructionLength(m_object, arch->GetObject(), addr);
}
bool BinaryView::GetStringAtAddress(uint64_t addr, BNStringReference& strRef)
{
return BNGetStringAtAddress(m_object, addr, &strRef);
}
vector BinaryView::GetStrings()
{
size_t count;
BNStringReference* strings = BNGetStrings(m_object, &count);
vector result;
result.insert(result.end(), strings, strings + count);
BNFreeStringReferenceList(strings);
return result;
}
vector BinaryView::GetStrings(uint64_t start, uint64_t len)
{
size_t count;
BNStringReference* strings = BNGetStringsInRange(m_object, start, len, &count);
vector result;
result.insert(result.end(), strings, strings + count);
BNFreeStringReferenceList(strings);
return result;
}
StringDetectionParameters StringDetectionParameters::FromSettings(Ref settings, Ref view)
{
StringDetectionParameters params;
params.minStringLength = settings->Get("analysis.limits.minStringLength", view);
params.utf8Enabled = settings->Get("analysis.unicode.utf8", view);
params.utf16Enabled = settings->Get("analysis.unicode.utf16", view);
params.utf32Enabled = settings->Get("analysis.unicode.utf32", view);
params.unicodeBlockNames = settings->Get("analysis.unicode.blocks", view);
return params;
}
StringDetector::StringDetector(const StringDetectionParameters& params)
{
BNStringDetectionParameters apiParams;
apiParams.minStringLength = params.minStringLength;
apiParams.utf8Enabled = params.utf8Enabled;
apiParams.utf16Enabled = params.utf16Enabled;
apiParams.utf32Enabled = params.utf32Enabled;
vector blockNames;
blockNames.reserve(params.unicodeBlockNames.size());
for (const auto& name : params.unicodeBlockNames)
blockNames.push_back(name.c_str());
apiParams.unicodeBlockNames = blockNames.data();
apiParams.unicodeBlockNameCount = blockNames.size();
m_object = BNCreateStringDetector(&apiParams);
}
StringDetector::~StringDetector()
{
if (m_object)
BNFreeStringDetector(m_object);
}
StringDetector::StringDetector(StringDetector&& other) noexcept : m_object(other.m_object)
{
other.m_object = nullptr;
}
StringDetector& StringDetector::operator=(StringDetector&& other) noexcept
{
if (this != &other)
{
if (m_object)
BNFreeStringDetector(m_object);
m_object = other.m_object;
other.m_object = nullptr;
}
return *this;
}
vector StringDetector::DetectStrings(const void* data, size_t dataLen, size_t blockLen,
uint64_t baseAddress, BNStringReference* lastFoundString) const
{
size_t count = 0;
BNStringReference* strings = BNStringDetectorDetectStrings(m_object, static_cast(data),
dataLen, blockLen, baseAddress, lastFoundString, &count);
vector result;
result.insert(result.end(), strings, strings + count);
BNFreeStringReferenceList(strings);
return result;
}
vector BinaryView::GetDerivedStrings()
{
size_t count;
BNDerivedString* strings = BNGetDerivedStrings(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(DerivedString::FromAPIObject(&strings[i], false));
BNFreeDerivedStringList(strings, count);
return result;
}
vector BinaryView::GetDerivedStringCodeReferences(
const DerivedString& str, std::optional maxItems)
{
BNDerivedString derivedStr = str.ToAPIObject(false);
size_t count;
BNReferenceSource* refs = BNGetDerivedStringCodeReferences(
m_object, &derivedStr, &count, maxItems.has_value(), maxItems.value_or(0));
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
ReferenceSource src;
src.func = new Function(BNNewFunctionReference(refs[i].func));
src.arch = new CoreArchitecture(refs[i].arch);
src.addr = refs[i].addr;
result.push_back(src);
}
BNFreeCodeReferences(refs, count);
return result;
}
// The caller of this function must hold a reference to the returned Ref.
// Otherwise, it can be freed before the callback is triggered, leading to a crash.
Ref BinaryView::AddAnalysisCompletionEvent(const function& callback)
{
return new AnalysisCompletionEvent(this, callback);
}
BNAnalysisProgress BinaryView::GetAnalysisProgress()
{
return BNGetAnalysisProgress(m_object);
}
BNAnalysisState BinaryView::GetAnalysisState()
{
return BNGetAnalysisState(m_object);
}
Ref BinaryView::GetBackgroundAnalysisTask()
{
BNBackgroundTask* task = BNGetBackgroundAnalysisTask(m_object);
if (!task)
return nullptr;
return new BackgroundTask(task);
}
uint64_t BinaryView::GetNextFunctionStartAfterAddress(uint64_t addr)
{
return BNGetNextFunctionStartAfterAddress(m_object, addr);
}
uint64_t BinaryView::GetNextBasicBlockStartAfterAddress(uint64_t addr)
{
return BNGetNextBasicBlockStartAfterAddress(m_object, addr);
}
uint64_t BinaryView::GetNextDataAfterAddress(uint64_t addr)
{
return BNGetNextDataAfterAddress(m_object, addr);
}
uint64_t BinaryView::GetNextDataVariableStartAfterAddress(uint64_t addr)
{
return BNGetNextDataVariableStartAfterAddress(m_object, addr);
}
uint64_t BinaryView::GetPreviousFunctionStartBeforeAddress(uint64_t addr)
{
return BNGetPreviousFunctionStartBeforeAddress(m_object, addr);
}
uint64_t BinaryView::GetPreviousBasicBlockStartBeforeAddress(uint64_t addr)
{
return BNGetPreviousBasicBlockStartBeforeAddress(m_object, addr);
}
uint64_t BinaryView::GetPreviousBasicBlockEndBeforeAddress(uint64_t addr)
{
return BNGetPreviousBasicBlockEndBeforeAddress(m_object, addr);
}
uint64_t BinaryView::GetPreviousDataBeforeAddress(uint64_t addr)
{
return BNGetPreviousDataBeforeAddress(m_object, addr);
}
uint64_t BinaryView::GetPreviousDataVariableStartBeforeAddress(uint64_t addr)
{
return BNGetPreviousDataVariableStartBeforeAddress(m_object, addr);
}
bool BinaryView::ParsePossibleValueSet(
const string& value, BNRegisterValueType state, PossibleValueSet& result, uint64_t here, string& errors)
{
BNPossibleValueSet res;
char* errorStr = nullptr;
if (!BNParsePossibleValueSet(m_object, value.c_str(), state, &res, here, &errorStr))
{
if (!errorStr)
errors = "";
else
errors = errorStr;
BNFreeString(errorStr);
return false;
}
result = PossibleValueSet::FromAPIObject(res);
errors = "";
return true;
}
bool BinaryView::ParseTypeString(const string& text, QualifiedNameAndType& result, string& errors,
const std::set& typesAllowRedefinition, bool importDependencies)
{
BNQualifiedNameAndType nt;
char* errorStr;
BNQualifiedNameList typesList;
typesList.count = typesAllowRedefinition.size();
typesList.names = new BNQualifiedName[typesList.count];
size_t i = 0;
for (auto& type : typesAllowRedefinition)
{
typesList.names[i] = type.GetAPIObject();
i++;
}
if (!BNParseTypeString(m_object, text.c_str(), &nt, &errorStr, &typesList, importDependencies))
{
errors = errorStr;
BNFreeString(errorStr);
delete[] typesList.names;
return false;
}
result.name = QualifiedName::FromAPIObject(&nt.name);
result.type = new Type(BNNewTypeReference(nt.type));
errors = "";
BNFreeQualifiedNameAndType(&nt);
delete[] typesList.names;
return true;
}
bool BinaryView::ParseTypeString(const string& source, map& types,
map& variables, map& functions, string& errors,
const std::set& typesAllowRedefinition, bool importDependencies)
{
BNTypeParserResult result;
char* errorStr = nullptr;
types.clear();
variables.clear();
functions.clear();
BNQualifiedNameList typesList;
typesList.count = typesAllowRedefinition.size();
typesList.names = new BNQualifiedName[typesList.count];
size_t i = 0;
for (auto& type : typesAllowRedefinition)
{
typesList.names[i] = type.GetAPIObject();
i++;
}
vector options;
vector includeDirs;
bool ok = BNParseTypesString(m_object, source.c_str(), options.data(), options.size(),
includeDirs.data(), includeDirs.size(), &result, &errorStr, &typesList, importDependencies);
if (errorStr)
{
errors = errorStr;
BNFreeString(errorStr);
}
delete[] typesList.names;
if (!ok)
return false;
for (size_t i = 0; i < result.typeCount; i++)
{
QualifiedName name = QualifiedName::FromAPIObject(&result.types[i].name);
types[name] = new Type(BNNewTypeReference(result.types[i].type));
}
for (size_t i = 0; i < result.variableCount; i++)
{
QualifiedName name = QualifiedName::FromAPIObject(&result.variables[i].name);
variables[name] = new Type(BNNewTypeReference(result.variables[i].type));
}
for (size_t i = 0; i < result.functionCount; i++)
{
QualifiedName name = QualifiedName::FromAPIObject(&result.functions[i].name);
functions[name] = new Type(BNNewTypeReference(result.functions[i].type));
}
BNFreeTypeParserResult(&result);
return true;
}
bool BinaryView::ParseTypesFromSource(const string& source, const vector& options, const vector& includeDirs,
TypeParserResult& result, string& errors, const std::set& typesAllowRedefinition, bool importDependencies)
{
BNQualifiedNameList typesList;
typesList.count = typesAllowRedefinition.size();
typesList.names = new BNQualifiedName[typesList.count];
size_t i = 0;
for (auto& type : typesAllowRedefinition)
{
typesList.names[i] = type.GetAPIObject();
i++;
}
vector coreOptions;
coreOptions.reserve(options.size());
for (auto& option : options)
coreOptions.push_back(option.c_str());
vector coreIncludeDirs;
coreIncludeDirs.reserve(includeDirs.size());
for (auto& includeDir : includeDirs)
coreIncludeDirs.push_back(includeDir.c_str());
BNTypeParserResult apiResult;
char* errorStr = nullptr;
bool ok = BNParseTypesString(m_object, source.c_str(), coreOptions.data(), coreOptions.size(),
coreIncludeDirs.data(), coreIncludeDirs.size(), &apiResult, &errorStr, &typesList, importDependencies);
if (errorStr)
{
errors = errorStr;
BNFreeString(errorStr);
}
delete[] typesList.names;
if (!ok)
return false;
result.types.clear();
for (size_t j = 0; j < apiResult.typeCount; ++j)
{
result.types.push_back({
QualifiedName::FromAPIObject(&apiResult.types[j].name),
new Type(BNNewTypeReference(apiResult.types[j].type)),
apiResult.types[j].isUser
});
}
result.variables.clear();
for (size_t j = 0; j < apiResult.variableCount; ++j)
{
result.variables.push_back({
QualifiedName::FromAPIObject(&apiResult.variables[j].name),
new Type(BNNewTypeReference(apiResult.variables[j].type)),
apiResult.variables[j].isUser
});
}
result.functions.clear();
for (size_t j = 0; j < apiResult.functionCount; ++j)
{
result.functions.push_back({
QualifiedName::FromAPIObject(&apiResult.functions[j].name),
new Type(BNNewTypeReference(apiResult.functions[j].type)),
apiResult.functions[j].isUser
});
}
BNFreeTypeParserResult(&apiResult);
return true;
}
TypeContainer BinaryView::GetTypeContainer()
{
return TypeContainer(BNGetAnalysisTypeContainer(m_object));
}
TypeContainer BinaryView::GetAutoTypeContainer()
{
return TypeContainer(BNGetAnalysisAutoTypeContainer(m_object));
}
TypeContainer BinaryView::GetUserTypeContainer()
{
return TypeContainer(BNGetAnalysisUserTypeContainer(m_object));
}
map BinaryView::GetTypes()
{
size_t count;
BNQualifiedNameAndType* types = BNGetAnalysisTypeList(m_object, &count);
map result;
for (size_t i = 0; i < count; i++)
{
QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
result[name] = new Type(BNNewTypeReference(types[i].type));
}
BNFreeTypeAndNameList(types, count);
return result;
}
vector BinaryView::GetDependencySortedTypes()
{
size_t count;
BNQualifiedNameAndType* types = BNGetAnalysisDependencySortedTypeList(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
QualifiedName name = QualifiedName::FromAPIObject(&types[i].name);
result.emplace_back(name, new Type(BNNewTypeReference(types[i].type)));
}
BNFreeTypeAndNameList(types, count);
return result;
}
vector BinaryView::GetTypeNames(const string& matching)
{
size_t count;
BNQualifiedName* names = BNGetAnalysisTypeNames(m_object, &count, matching.c_str());
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.push_back(QualifiedName::FromAPIObject(&names[i]));
}
BNFreeTypeNameList(names, count);
return result;
}
Ref BinaryView::GetTypeByName(const QualifiedName& name)
{
BNQualifiedName nameObj = name.GetAPIObject();
BNType* type = BNGetAnalysisTypeByName(m_object, &nameObj);
QualifiedName::FreeAPIObject(&nameObj);
if (!type)
return nullptr;
return new Type(type);
}
Ref BinaryView::GetTypeByRef(Ref ref)
{
BNType* type = BNGetAnalysisTypeByRef(m_object, ref->m_object);
if (!type)
return nullptr;
return new Type(type);
}
Ref BinaryView::GetTypeById(const string& id)
{
BNType* type = BNGetAnalysisTypeById(m_object, id.c_str());
if (!type)
return nullptr;
return new Type(type);
}
QualifiedName BinaryView::GetTypeNameById(const string& id)
{
BNQualifiedName name = BNGetAnalysisTypeNameById(m_object, id.c_str());
QualifiedName result = QualifiedName::FromAPIObject(&name);
BNFreeQualifiedName(&name);
return result;
}
string BinaryView::GetTypeId(const QualifiedName& name)
{
BNQualifiedName nameObj = name.GetAPIObject();
char* id = BNGetAnalysisTypeId(m_object, &nameObj);
QualifiedName::FreeAPIObject(&nameObj);
string result = id;
BNFreeString(id);
return result;
}
bool BinaryView::IsTypeAutoDefined(const QualifiedName& name)
{
BNQualifiedName nameObj = name.GetAPIObject();
bool result = BNIsAnalysisTypeAutoDefined(m_object, &nameObj);
QualifiedName::FreeAPIObject(&nameObj);
return result;
}
QualifiedName BinaryView::DefineType(const string& id, const QualifiedName& defaultName, Ref type)
{
BNQualifiedName nameObj = defaultName.GetAPIObject();
BNQualifiedName regName = BNDefineAnalysisType(m_object, id.c_str(), &nameObj, type->GetObject());
QualifiedName::FreeAPIObject(&nameObj);
QualifiedName result = QualifiedName::FromAPIObject(®Name);
BNFreeQualifiedName(®Name);
return result;
}
void BinaryView::DefineUserType(const QualifiedName& name, Ref type)
{
BNQualifiedName nameObj = name.GetAPIObject();
BNDefineUserAnalysisType(m_object, &nameObj, type->GetObject());
QualifiedName::FreeAPIObject(&nameObj);
}
std::unordered_map BinaryView::DefineTypes(const vector& types, ProgressFunction progress)
{
BNQualifiedNameTypeAndId* apiTypes = new BNQualifiedNameTypeAndId[types.size()];
for (size_t i = 0; i < types.size(); i++)
{
apiTypes[i].name = types[i].second.name.GetAPIObject();
apiTypes[i].type = types[i].second.type->GetObject();
apiTypes[i].id = BNAllocString(types[i].first.c_str());
}
ProgressContext cb;
cb.callback = progress;
char** resultIds;
BNQualifiedName* resultNames;
size_t resultCount = BNDefineAnalysisTypes(m_object, apiTypes, types.size(), ProgressCallback, &cb, &resultIds, &resultNames);
unordered_map result;
for (size_t i = 0; i < resultCount; i ++)
{
string id = resultIds[i];
QualifiedName name = QualifiedName::FromAPIObject(&resultNames[i]);
result.insert({id, name});
}
BNFreeStringList(resultIds, resultCount);
BNFreeTypeNameList(resultNames, resultCount);
for (size_t i = 0; i < types.size(); i++)
{
QualifiedName::FreeAPIObject(&apiTypes[i].name);
BNFreeString(apiTypes[i].id);
}
delete [] apiTypes;
return result;
}
void BinaryView::DefineUserTypes(const vector& types, ProgressFunction progress)
{
BNQualifiedNameAndType* apiTypes = new BNQualifiedNameAndType[types.size()];
for (size_t i = 0; i < types.size(); i++)
{
apiTypes[i].name = types[i].name.GetAPIObject();
apiTypes[i].type = types[i].type->GetObject();
}
ProgressContext cb;
cb.callback = progress;
BNDefineUserAnalysisTypes(m_object, apiTypes, types.size(), ProgressCallback, &cb);
for (size_t i = 0; i < types.size(); i++)
{
QualifiedName::FreeAPIObject(&apiTypes[i].name);
}
delete [] apiTypes;
}
void BinaryView::DefineUserTypes(const vector& types, ProgressFunction progress)
{
BNQualifiedNameAndType* apiTypes = new BNQualifiedNameAndType[types.size()];
for (size_t i = 0; i < types.size(); i++)
{
apiTypes[i].name = types[i].name.GetAPIObject();
apiTypes[i].type = types[i].type->GetObject();
}
ProgressContext cb;
cb.callback = progress;
BNDefineUserAnalysisTypes(m_object, apiTypes, types.size(), ProgressCallback, &cb);
for (size_t i = 0; i < types.size(); i++)
{
QualifiedName::FreeAPIObject(&apiTypes[i].name);
}
delete [] apiTypes;
}
void BinaryView::UndefineType(const string& id)
{
BNUndefineAnalysisType(m_object, id.c_str());
}
void BinaryView::UndefineUserType(const QualifiedName& name)
{
BNQualifiedName nameObj = name.GetAPIObject();
BNUndefineUserAnalysisType(m_object, &nameObj);
QualifiedName::FreeAPIObject(&nameObj);
}
void BinaryView::RenameType(const QualifiedName& oldName, const QualifiedName& newName)
{
BNQualifiedName oldNameObj = oldName.GetAPIObject();
BNQualifiedName newNameObj = newName.GetAPIObject();
BNRenameAnalysisType(m_object, &oldNameObj, &newNameObj);
QualifiedName::FreeAPIObject(&oldNameObj);
QualifiedName::FreeAPIObject(&newNameObj);
}
Ref BinaryView::GetSystemCallType(Platform *platform, uint32_t id)
{
BNType* type = BNGetAnalysisSystemCallType(m_object, platform->m_object, id);
if (!type)
return nullptr;
return new Type(type);
}
std::string BinaryView::GetSystemCallName(Platform *platform, uint32_t id)
{
char* name = BNGetAnalysisSystemCallName(m_object, platform->m_object, id);
string result = name;
BNFreeString(name);
return result;
}
void BinaryView::RegisterPlatformTypes(Platform* platform)
{
BNRegisterPlatformTypes(m_object, platform->GetObject());
}
std::optional BinaryView::LookupImportedTypePlatform(const QualifiedName& name)
{
BNPlatform* resultLib;
BNQualifiedName resultName;
BNQualifiedName sourceName = name.GetAPIObject();
bool result = BNLookupImportedTypePlatform(m_object, &sourceName, &resultLib, &resultName);
QualifiedName::FreeAPIObject(&sourceName);
if (!result)
return std::nullopt;
QualifiedName targetName = QualifiedName::FromAPIObject(&resultName);
BNFreeQualifiedName(&resultName);
return std::make_pair(new CorePlatform(resultLib), targetName);
}
void BinaryView::AddTypeLibrary(TypeLibrary* lib)
{
BNAddBinaryViewTypeLibrary(m_object, lib->GetObject());
}
Ref BinaryView::GetTypeLibrary(const std::string& name)
{
BNTypeLibrary* lib = BNGetBinaryViewTypeLibrary(m_object, name.c_str());
if (!lib)
return nullptr;
return new TypeLibrary(lib);
}
std::vector BinaryView::GetTypeLibraries()
{
size_t count;
BNTypeLibrary** libs = BNGetBinaryViewTypeLibraries(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; ++i)
{
result.push_back(new TypeLibrary(BNNewTypeLibraryReference(libs[i])));
}
BNFreeTypeLibraryList(libs, count);
return result;
}
Ref BinaryView::ImportTypeLibraryType(Ref& lib, const QualifiedName& name)
{
BNQualifiedName apiName = name.GetAPIObject();
BNTypeLibrary* apiLib = lib ? lib->GetObject() : nullptr;
BNType* result = BNBinaryViewImportTypeLibraryType(m_object, &apiLib, &apiName);
lib = apiLib ? new TypeLibrary(apiLib) : nullptr;
QualifiedName::FreeAPIObject(&apiName);
if (!result)
return nullptr;
return new Type(result);
}
Ref BinaryView::ImportTypeLibraryObject(Ref& lib, const QualifiedName& name)
{
BNQualifiedName apiName = name.GetAPIObject();
BNTypeLibrary* apiLib = lib ? lib->GetObject() : nullptr;
BNType* result = BNBinaryViewImportTypeLibraryObject(m_object, &apiLib, &apiName);
lib = apiLib ? new TypeLibrary(apiLib) : nullptr;
QualifiedName::FreeAPIObject(&apiName);
if (!result)
return nullptr;
return new Type(result);
}
Ref BinaryView::ImportTypeLibraryTypeByGuid(const string& guid)
{
BNType* result = BNBinaryViewImportTypeLibraryTypeByGuid(m_object, guid.c_str());
if (!result)
return nullptr;
return new Type(result);
}
std::optional BinaryView::GetTypeNameByGuid(const std::string& guid)
{
auto result = BNBinaryViewGetTypeNameByGuid(m_object, guid.c_str());
if (result.nameCount == 0)
return std::nullopt;
auto name = QualifiedName::FromAPIObject(&result);
BNFreeQualifiedName(&result);
return name;
}
void BinaryView::ExportTypeToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type)
{
BNQualifiedName apiName = name.GetAPIObject();
BNBinaryViewExportTypeToTypeLibrary(m_object, lib->GetObject(), &apiName, type->GetObject());
QualifiedName::FreeAPIObject(&apiName);
}
void BinaryView::ExportObjectToTypeLibrary(TypeLibrary* lib, const QualifiedName& name, Type* type)
{
BNQualifiedName apiName = name.GetAPIObject();
BNBinaryViewExportObjectToTypeLibrary(m_object, lib->GetObject(), &apiName, type->GetObject());
QualifiedName::FreeAPIObject(&apiName);
}
void BinaryView::RecordImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr, TypeLibrary* lib, const QualifiedName& name)
{
BNQualifiedName apiName = name.GetAPIObject();
BNBinaryViewRecordImportedObjectLibrary(m_object, tgtPlatform->m_object, tgtAddr, lib->GetObject(), &apiName);
QualifiedName::FreeAPIObject(&apiName);
}
std::optional BinaryView::LookupImportedObjectLibrary(Platform* tgtPlatform, uint64_t tgtAddr)
{
BNTypeLibrary* resultLib;
BNQualifiedName resultName;
if (!BNBinaryViewLookupImportedObjectLibrary(m_object, tgtPlatform->m_object, tgtAddr, &resultLib, &resultName))
return std::nullopt;
QualifiedName name = QualifiedName::FromAPIObject(&resultName);
BNFreeQualifiedName(&resultName);
return std::make_pair(new TypeLibrary(resultLib), name);
}
std::optional BinaryView::LookupImportedTypeLibrary(const QualifiedName& name)
{
BNTypeLibrary* resultLib;
BNQualifiedName resultName;
BNQualifiedName sourceName = name.GetAPIObject();
bool result = BNBinaryViewLookupImportedTypeLibrary(m_object, &sourceName, &resultLib, &resultName);
QualifiedName::FreeAPIObject(&sourceName);
if (!result)
return std::nullopt;
QualifiedName targetName = QualifiedName::FromAPIObject(&resultName);
BNFreeQualifiedName(&resultName);
return std::make_pair(new TypeLibrary(resultLib), targetName);
}
Ref BinaryView::AttachTypeArchive(const string& id, const string& path)
{
BNTypeArchive* archive = BNBinaryViewAttachTypeArchive(m_object, id.c_str(), path.c_str());
if (!archive)
return nullptr;
return new TypeArchive(archive);
}
void BinaryView::DetachTypeArchive(const string& id)
{
BNBinaryViewDetachTypeArchive(m_object, id.c_str());
}
Ref BinaryView::GetTypeArchive(const std::string& id) const
{
BNTypeArchive* result = BNBinaryViewGetTypeArchive(m_object, id.c_str());
if (!result)
return nullptr;
return new TypeArchive(result);
}
std::unordered_map BinaryView::GetTypeArchives() const
{
char** ids;
char** paths;
size_t count = BNBinaryViewGetTypeArchives(m_object, &ids, &paths);
std::unordered_map result;
for (size_t i = 0; i < count; i ++)
{
result.emplace(ids[i], paths[i]);
}
BNFreeStringList(ids, count);
BNFreeStringList(paths, count);
return result;
}
std::optional BinaryView::GetTypeArchivePath(const std::string& id) const
{
char* result = BNBinaryViewGetTypeArchivePath(m_object, id.c_str());
if (!result)
return std::nullopt;
std::string cppResult = result;
BNFreeString(result);
return cppResult;
}
std::unordered_map BinaryView::GetTypeArchiveTypeNames() const
{
BNQualifiedName* names;
size_t nameCount = BNBinaryViewGetTypeArchiveTypeNameList(m_object, &names);
std::unordered_map result;
for (size_t i = 0; i < nameCount; i++)
{
char** archiveIds;
char** typeIds;
size_t idCount = BNBinaryViewGetTypeArchiveTypeNames(m_object, &names[i], &archiveIds, &typeIds);
std::map ids;
for (size_t j = 0; j < idCount; ++j)
{
ids.emplace(archiveIds[j], typeIds[j]);
}
BNFreeStringList(archiveIds, idCount);
BNFreeStringList(typeIds, idCount);
}
BNFreeTypeNameList(names, nameCount);
return result;
}
std::unordered_map BinaryView::GetAssociatedTypeArchiveTypes() const
{
char** typeIds;
char** archiveIds;
char** archiveTypeIds;
size_t count = BNBinaryViewGetAssociatedTypeArchiveTypes(m_object, &typeIds, &archiveIds, &archiveTypeIds);
std::unordered_map result;
for (size_t i = 0; i < count; i++)
{
result.insert({typeIds[i], {archiveIds[i], archiveTypeIds[i]}});
}
BNFreeStringList(typeIds, count);
BNFreeStringList(archiveIds, count);
BNFreeStringList(archiveTypeIds, count);
return result;
}
std::unordered_map BinaryView::GetAssociatedTypesFromArchive(const std::string& archive) const
{
char** typeIds;
char** archiveTypeIds;
size_t count = BNBinaryViewGetAssociatedTypesFromArchive(m_object, archive.c_str(), &typeIds, &archiveTypeIds);
std::unordered_map result;
for (size_t i = 0; i < count; i++)
{
result.insert({typeIds[i], archiveTypeIds[i]});
}
BNFreeStringList(typeIds, count);
BNFreeStringList(archiveTypeIds, count);
return result;
}
std::optional BinaryView::GetAssociatedTypeArchiveTypeTarget(const std::string& id) const
{
char* archiveId;
char* archiveTypeId;
if (!BNBinaryViewGetAssociatedTypeArchiveTypeTarget(m_object, id.c_str(), &archiveId, &archiveTypeId))
return std::nullopt;
std::pair result = std::make_pair(archiveId, archiveTypeId);
BNFreeString(archiveId);
BNFreeString(archiveTypeId);
return result;
}
std::optional BinaryView::GetAssociatedTypeArchiveTypeSource(const std::string& archiveId, const std::string& archiveTypeId) const
{
char* typeId;
if (!BNBinaryViewGetAssociatedTypeArchiveTypeSource(m_object, archiveId.c_str(), archiveTypeId.c_str(), &typeId))
return std::nullopt;
std::string result = typeId;
BNFreeString(typeId);
return result;
}
BNSyncStatus BinaryView::GetTypeArchiveSyncStatus(const std::string& typeId) const
{
return BNBinaryViewGetTypeArchiveSyncStatus(m_object, typeId.c_str());
}
bool BinaryView::DisassociateTypeArchiveType(const std::string& typeId)
{
return BNBinaryViewDisassociateTypeArchiveType(m_object, typeId.c_str());
}
bool BinaryView::PullTypeArchiveTypes(const std::string& archiveId, const std::unordered_set& archiveTypeIds, std::unordered_map& updatedTypes)
{
std::vector apiArchiveTypeIds;
apiArchiveTypeIds.reserve(archiveTypeIds.size());
for (const auto& archiveTypeId: archiveTypeIds)
{
apiArchiveTypeIds.push_back(archiveTypeId.c_str());
}
char** apiUpdatedArchiveTypeIds;
char** apiUpdatedAnalysisTypeIds;
size_t apiUpdatedTypeCount;
if (!BNBinaryViewPullTypeArchiveTypes(m_object, archiveId.c_str(), apiArchiveTypeIds.data(), apiArchiveTypeIds.size(), &apiUpdatedArchiveTypeIds, &apiUpdatedAnalysisTypeIds, &apiUpdatedTypeCount))
return false;
updatedTypes.clear();
for (size_t i = 0; i < apiUpdatedTypeCount; i++)
{
updatedTypes.insert({apiUpdatedArchiveTypeIds[i], apiUpdatedAnalysisTypeIds[i]});
}
BNFreeStringList(apiUpdatedArchiveTypeIds, apiUpdatedTypeCount);
BNFreeStringList(apiUpdatedAnalysisTypeIds, apiUpdatedTypeCount);
return true;
}
bool BinaryView::PushTypeArchiveTypes(const std::string& archiveId, const std::unordered_set& typeIds, std::unordered_map& updatedTypes)
{
std::vector apiTypeIds;
apiTypeIds.reserve(typeIds.size());
for (const auto& typeId: typeIds)
{
apiTypeIds.push_back(typeId.c_str());
}
char** apiUpdatedAnalysisTypeIds;
char** apiUpdatedArchiveTypeIds;
size_t apiUpdatedTypeCount;
if (!BNBinaryViewPushTypeArchiveTypes(m_object, archiveId.c_str(), apiTypeIds.data(), apiTypeIds.size(), &apiUpdatedAnalysisTypeIds, &apiUpdatedArchiveTypeIds, &apiUpdatedTypeCount))
return false;
updatedTypes.clear();
for (size_t i = 0; i < apiUpdatedTypeCount; i++)
{
updatedTypes.insert({apiUpdatedAnalysisTypeIds[i], apiUpdatedArchiveTypeIds[i]});
}
BNFreeStringList(apiUpdatedAnalysisTypeIds, apiUpdatedTypeCount);
BNFreeStringList(apiUpdatedArchiveTypeIds, apiUpdatedTypeCount);
return true;
}
bool BinaryView::FindNextData(uint64_t start, const DataBuffer& data, uint64_t& result, BNFindFlag flags)
{
return BNFindNextData(m_object, start, data.GetBufferObject(), &result, flags);
}
bool BinaryView::FindNextText(uint64_t start, const std::string& data, uint64_t& result,
Ref settings, BNFindFlag flags, const FunctionViewType& viewType)
{
return BNFindNextText(m_object, start, data.c_str(), &result, settings->GetObject(), flags, viewType.ToAPIObject());
}
bool BinaryView::FindNextConstant(
uint64_t start, uint64_t constant, uint64_t& result, Ref settings, const FunctionViewType& viewType)
{
return BNFindNextConstant(m_object, start, constant, &result, settings->GetObject(), viewType.ToAPIObject());
}
struct MatchCallbackContextForDataBuffer
{
std::function func;
};
static bool MatchCallbackForDataBuffer(void* ctxt, uint64_t addr, BNDataBuffer* buffer)
{
MatchCallbackContextForDataBuffer* cb = (MatchCallbackContextForDataBuffer*)ctxt;
return cb->func(addr, DataBuffer(buffer));
}
struct MatchCallbackContextForText
{
std::function func;
};
static bool MatchCallbackForText(void* ctxt, uint64_t addr, const char* buffer, BNLinearDisassemblyLine* line)
{
MatchCallbackContextForText* cb = (MatchCallbackContextForText*)ctxt;
LinearDisassemblyLine result = LinearDisassemblyLine::FromAPIObject(line);
BNFreeLinearDisassemblyLines(line, 1);
return cb->func(addr, string(buffer), result);
}
struct MatchCallbackContextForConstant
{
std::function func;
};
static bool MatchCallbackForConstant(void* ctxt, uint64_t addr, BNLinearDisassemblyLine* line)
{
MatchCallbackContextForConstant* cb = (MatchCallbackContextForConstant*)ctxt;
LinearDisassemblyLine result = LinearDisassemblyLine::FromAPIObject(line);
BNFreeLinearDisassemblyLines(line, 1);
return cb->func(addr, result);
}
bool BinaryView::FindNextData(uint64_t start, uint64_t end, const DataBuffer& data, uint64_t& addr, BNFindFlag flags,
const ProgressFunction& progress)
{
ProgressContext fp;
fp.callback = progress;
return BNFindNextDataWithProgress(
m_object, start, end, data.GetBufferObject(), &addr, flags, &fp, ProgressCallback);
}
bool BinaryView::FindNextText(uint64_t start, uint64_t end, const std::string& data, uint64_t& addr,
Ref settings, BNFindFlag flags, const FunctionViewType& viewType,
const ProgressFunction& progress)
{
ProgressContext fp;
fp.callback = progress;
return BNFindNextTextWithProgress(
m_object, start, end, data.c_str(), &addr, settings->GetObject(), flags, viewType.ToAPIObject(), &fp, ProgressCallback);
}
bool BinaryView::FindNextConstant(uint64_t start, uint64_t end, uint64_t constant, uint64_t& addr,
Ref settings, const FunctionViewType& viewType,
const ProgressFunction& progress)
{
ProgressContext fp;
fp.callback = progress;
return BNFindNextConstantWithProgress(
m_object, start, end, constant, &addr, settings->GetObject(), viewType.ToAPIObject(), &fp, ProgressCallback);
}
bool BinaryView::FindAllData(uint64_t start, uint64_t end, const DataBuffer& data, BNFindFlag flags,
const ProgressFunction& progress,
const std::function& matchCallback)
{
ProgressContext fp;
fp.callback = progress;
MatchCallbackContextForDataBuffer mc;
mc.func = matchCallback;
return BNFindAllDataWithProgress(m_object, start, end, data.GetBufferObject(), flags, &fp, ProgressCallback,
&mc, MatchCallbackForDataBuffer);
}
bool BinaryView::FindAllText(uint64_t start, uint64_t end, const std::string& data, Ref settings,
BNFindFlag flags, const FunctionViewType& viewType, const ProgressFunction& progress,
const std::function&
matchCallback)
{
ProgressContext fp;
fp.callback = progress;
MatchCallbackContextForText mc;
mc.func = matchCallback;
return BNFindAllTextWithProgress(m_object, start, end, data.c_str(), settings->GetObject(), flags, viewType.ToAPIObject(), &fp,
ProgressCallback, &mc, MatchCallbackForText);
}
bool BinaryView::FindAllConstant(uint64_t start, uint64_t end, uint64_t constant, Ref settings,
const FunctionViewType& viewType, const ProgressFunction& progress,
const std::function& matchCallback)
{
ProgressContext fp;
fp.callback = progress;
MatchCallbackContextForConstant mc;
mc.func = matchCallback;
return BNFindAllConstantWithProgress(m_object, start, end, constant, settings->GetObject(), viewType.ToAPIObject(), &fp,
ProgressCallback, &mc, MatchCallbackForConstant);
}
string BinaryView::DetectSearchMode(const string& query)
{
char* searchMode = BNDetectSearchMode(query.c_str());
string result = searchMode;
BNFreeString(searchMode);
return result;
}
bool BinaryView::Search(const string& query, const ProgressFunction& progressCallback, const std::function& matchCallback)
{
ProgressContext fp;
fp.callback = progressCallback;
MatchCallbackContextForDataBuffer mc;
mc.func = matchCallback;
return BNSearch(m_object, query.c_str(), &fp, ProgressCallback, &mc, MatchCallbackForDataBuffer);
}
void BinaryView::Reanalyze()
{
BNReanalyzeAllFunctions(m_object);
}
Ref BinaryView::GetWorkflow()
{
BNWorkflow* workflow = BNGetWorkflowForBinaryView(m_object);
if (!workflow)
return nullptr;
return new Workflow(workflow, this);
}
void BinaryView::ShowPlainTextReport(const string& title, const string& contents)
{
BNShowPlainTextReport(m_object, title.c_str(), contents.c_str());
}
void BinaryView::ShowMarkdownReport(const string& title, const string& contents, const string& plainText)
{
BNShowMarkdownReport(m_object, title.c_str(), contents.c_str(), plainText.c_str());
}
void BinaryView::ShowHTMLReport(const string& title, const string& contents, const string& plainText)
{
BNShowHTMLReport(m_object, title.c_str(), contents.c_str(), plainText.c_str());
}
void BinaryView::ShowGraphReport(const string& title, FlowGraph* graph)
{
BNShowGraphReport(m_object, title.c_str(), graph->GetObject());
}
bool BinaryView::GetAddressInput(uint64_t& result, const string& prompt, const string& title)
{
uint64_t currentAddress = 0;
if (m_file)
currentAddress = m_file->GetCurrentOffset();
return BNGetAddressInput(&result, prompt.c_str(), title.c_str(), m_object, currentAddress);
}
bool BinaryView::GetAddressInput(uint64_t& result, const string& prompt, const string& title, uint64_t currentAddress)
{
return BNGetAddressInput(&result, prompt.c_str(), title.c_str(), m_object, currentAddress);
}
void BinaryView::BeginBulkAddSegments()
{
BNBeginBulkAddSegments(m_object);
}
void BinaryView::EndBulkAddSegments()
{
BNEndBulkAddSegments(m_object);
}
void BinaryView::CancelBulkAddSegments()
{
BNCancelBulkAddSegments(m_object);
}
void BinaryView::AddAutoSegment(uint64_t start, uint64_t length, uint64_t dataOffset, uint64_t dataLength, uint32_t flags)
{
BNAddAutoSegment(m_object, start, length, dataOffset, dataLength, flags);
}
void BinaryView::AddAutoSegments(const vector& segments)
{
BNAddAutoSegments(m_object, segments.data(), segments.size());
}
void BinaryView::RemoveAutoSegment(uint64_t start, uint64_t length)
{
BNRemoveAutoSegment(m_object, start, length);
}
void BinaryView::AddUserSegment(uint64_t start, uint64_t length, uint64_t dataOffset, uint64_t dataLength, uint32_t flags)
{
BNAddUserSegment(m_object, start, length, dataOffset, dataLength, flags);
}
void BinaryView::AddUserSegments(const vector& segments)
{
BNAddUserSegments(m_object, segments.data(), segments.size());
}
void BinaryView::RemoveUserSegment(uint64_t start, uint64_t length)
{
BNRemoveUserSegment(m_object, start, length);
}
vector BinaryView::GetSegments()
{
size_t count;
BNSegment** segments = BNGetSegments(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Segment(BNNewSegmentReference(segments[i])));
BNFreeSegmentList(segments, count);
return result;
}
Ref BinaryView::GetSegmentAt(uint64_t addr)
{
BNSegment* segment = BNGetSegmentAt(m_object, addr);
if (!segment)
return nullptr;
return new Segment(segment);
}
bool BinaryView::GetAddressForDataOffset(uint64_t offset, uint64_t& addr)
{
return BNGetAddressForDataOffset(m_object, offset, &addr);
}
bool BinaryView::GetDataOffsetForAddress(uint64_t addr, uint64_t& offset)
{
auto segment = GetSegmentAt(addr);
if (segment && segment->GetDataLength() && (segment->GetStart() GetEnd()))
{
offset = addr - segment->GetStart() + segment->GetDataOffset();
return true;
}
return false;
}
void BinaryView::AddAutoSection(const string& name, uint64_t start, uint64_t length, BNSectionSemantics semantics,
const string& type, uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection,
uint64_t infoData)
{
BNAddAutoSection(m_object, name.c_str(), start, length, semantics, type.c_str(), align, entrySize,
linkedSection.c_str(), infoSection.c_str(), infoData);
}
void BinaryView::AddAutoSections(const vector& sections)
{
BNAddAutoSections(m_object, sections.data(), sections.size());
}
void BinaryView::RemoveAutoSection(const string& name)
{
BNRemoveAutoSection(m_object, name.c_str());
}
void BinaryView::AddUserSection(const string& name, uint64_t start, uint64_t length, BNSectionSemantics semantics,
const string& type, uint64_t align, uint64_t entrySize, const string& linkedSection, const string& infoSection,
uint64_t infoData)
{
BNAddUserSection(m_object, name.c_str(), start, length, semantics, type.c_str(), align, entrySize,
linkedSection.c_str(), infoSection.c_str(), infoData);
}
void BinaryView::AddUserSections(const vector& sections)
{
BNAddUserSections(m_object, sections.data(), sections.size());
}
void BinaryView::RemoveUserSection(const string& name)
{
BNRemoveUserSection(m_object, name.c_str());
}
vector BinaryView::GetSections()
{
size_t count;
BNSection** sections = BNGetSections(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new Section(BNNewSectionReference(sections[i])));
BNFreeSectionList(sections, count);
return result;
}
vector BinaryView::GetSectionsAt(uint64_t addr)
{
size_t count;
BNSection** sections = BNGetSectionsAt(m_object, addr, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
result.push_back(new Section(BNNewSectionReference(sections[i])));
}
BNFreeSectionList(sections, count);
return result;
}
Ref BinaryView::GetSectionByName(const string& name)
{
BNSection* section = BNGetSectionByName(m_object, name.c_str());
if (section)
return new Section(section);
return nullptr;
}
vector BinaryView::GetUniqueSectionNames(const vector& names)
{
const char** incomingNames = new const char*[names.size()];
for (size_t i = 0; i < names.size(); i++)
incomingNames[i] = names[i].c_str();
char** outgoingNames = BNGetUniqueSectionNames(m_object, incomingNames, names.size());
vector result;
result.reserve(names.size());
for (size_t i = 0; i < names.size(); i++)
result.push_back(outgoingNames[i]);
delete[] incomingNames;
BNFreeStringList(outgoingNames, names.size());
return result;
}
vector BinaryView::GetAllocatedRanges()
{
size_t count;
BNAddressRange* ranges = BNGetAllocatedRanges(m_object, &count);
vector result;
copy(&ranges[0], &ranges[count], back_inserter(result));
BNFreeAddressRanges(ranges);
return result;
}
vector BinaryView::GetMappedAddressRanges()
{
size_t count;
BNAddressRange* ranges = BNGetMappedAddressRanges(m_object, &count);
vector result;
copy(&ranges[0], &ranges[count], back_inserter(result));
BNFreeAddressRanges(ranges);
return result;
}
vector BinaryView::GetBackedAddressRanges()
{
size_t count;
BNAddressRange* ranges = BNGetBackedAddressRanges(m_object, &count);
vector result;
copy(&ranges[0], &ranges[count], back_inserter(result));
BNFreeAddressRanges(ranges);
return result;
}
string BinaryView::GetCommentForAddress(uint64_t addr) const
{
char* comment = BNGetGlobalCommentForAddress(m_object, addr);
string result = comment;
BNFreeString(comment);
return result;
}
vector BinaryView::GetCommentedAddresses() const
{
size_t count;
uint64_t* addrs = BNGetGlobalCommentedAddresses(m_object, &count);
vector result;
result.insert(result.end(), addrs, &addrs[count]);
BNFreeAddressList(addrs);
return result;
}
void BinaryView::SetCommentForAddress(uint64_t addr, const string& comment)
{
BNSetGlobalCommentForAddress(m_object, addr, comment.c_str());
}
void BinaryView::StoreMetadata(const std::string& key, Ref inValue, BNMetadataStoreFlag flags)
{
if (!inValue)
return;
BNBinaryViewStoreMetadata(m_object, key.c_str(), inValue->GetObject(), flags);
}
Ref BinaryView::QueryMetadata(const std::string& key)
{
BNMetadata* value = BNBinaryViewQueryMetadata(m_object, key.c_str());
if (!value)
return nullptr;
return new Metadata(value);
}
void BinaryView::RemoveMetadata(const std::string& key)
{
BNBinaryViewRemoveMetadata(m_object, key.c_str());
}
Ref BinaryView::GetMetadata()
{
return new Metadata(BNBinaryViewGetMetadata(m_object));
}
Ref BinaryView::GetAutoMetadata()
{
return new Metadata(BNBinaryViewGetAutoMetadata(m_object));
}
string BinaryView::GetStringMetadata(const string& key)
{
auto data = QueryMetadata(key);
if (!data || !data->IsString())
throw QueryMetadataException("Failed to find key: " + key);
return data->GetString();
}
vector BinaryView::GetRawMetadata(const string& key)
{
auto data = QueryMetadata(key);
if (!data || !data->IsRaw())
throw QueryMetadataException("Failed to find key: " + key);
return data->GetRaw();
}
uint64_t BinaryView::GetUIntMetadata(const string& key)
{
auto data = QueryMetadata(key);
if (!data || !data->IsUnsignedInteger())
throw QueryMetadataException("Failed to find key: " + key);
return data->GetUnsignedInteger();
}
vector BinaryView::GetLoadSettingsTypeNames()
{
size_t count = 0;
char** outgoingNames = BNBinaryViewGetLoadSettingsTypeNames(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(outgoingNames[i]);
BNFreeStringList(outgoingNames, count);
return result;
}
Ref BinaryView::GetLoadSettings(const string& typeName)
{
BNSettings* settings = BNBinaryViewGetLoadSettings(m_object, typeName.c_str());
if (!settings)
return nullptr;
return new Settings(settings);
}
void BinaryView::SetLoadSettings(const string& typeName, Ref settings)
{
BNBinaryViewSetLoadSettings(m_object, typeName.c_str(), settings ? settings->GetObject() : nullptr);
}
BNAnalysisParameters BinaryView::GetParametersForAnalysis()
{
return BNGetParametersForAnalysis(m_object);
}
void BinaryView::SetParametersForAnalysis(BNAnalysisParameters params)
{
BNSetParametersForAnalysis(m_object, params);
}
uint64_t BinaryView::GetMaxFunctionSizeForAnalysis()
{
return BNGetMaxFunctionSizeForAnalysis(m_object);
}
void BinaryView::SetMaxFunctionSizeForAnalysis(uint64_t size)
{
BNSetMaxFunctionSizeForAnalysis(m_object, size);
}
bool BinaryView::GetNewAutoFunctionAnalysisSuppressed()
{
return BNGetNewAutoFunctionAnalysisSuppressed(m_object);
}
void BinaryView::SetNewAutoFunctionAnalysisSuppressed(bool suppress)
{
BNSetNewAutoFunctionAnalysisSuppressed(m_object, suppress);
}
bool BinaryView::ShouldSkipTargetAnalysis(const ArchAndAddr& source, Ref sourceFunc,
uint64_t sourceEnd, const ArchAndAddr& target)
{
BNArchitectureAndAddress sourceCopy;
sourceCopy.arch = source.arch ? source.arch->GetObject() : nullptr;
sourceCopy.address = source.address;
BNArchitectureAndAddress targetCopy;
targetCopy.address = target.address;
targetCopy.arch = target.arch ? target.arch->GetObject() : nullptr;
auto func = sourceFunc ? sourceFunc->GetObject() : nullptr;
return BNShouldSkipTargetAnalysis(m_object, &sourceCopy, func, sourceEnd, &targetCopy);
}
set BinaryView::GetNameSpaces() const
{
set nameSpaces;
size_t count = 0;
BNNameSpace* nameSpaceList = BNGetNameSpaces(m_object, &count);
for (size_t i = 0; i < count; i++)
nameSpaces.insert(NameSpace::FromAPIObject(&nameSpaceList[i]));
BNFreeNameSpaceList(nameSpaceList, count);
return nameSpaces;
}
NameSpace BinaryView::GetInternalNameSpace()
{
BNNameSpace ns = BNGetInternalNameSpace();
NameSpace nameSpace = NameSpace::FromAPIObject(&ns);
BNFreeNameSpace(&ns);
return nameSpace;
}
NameSpace BinaryView::GetExternalNameSpace()
{
BNNameSpace ns = BNGetExternalNameSpace();
NameSpace nameSpace = NameSpace::FromAPIObject(&ns);
BNFreeNameSpace(&ns);
return nameSpace;
}
bool BinaryView::ParseExpression(
Ref view, const string& expression, uint64_t& offset, uint64_t here, string& errorString)
{
char* err = nullptr;
if (!BNParseExpression(view ? view->GetObject() : nullptr, expression.c_str(), &offset, here, &err))
{
if (err)
{
errorString = string(err);
BNFreeParseError(err);
}
return false;
}
return true;
}
Ref BinaryView::CreateStructureFromOffsetAccess(const QualifiedName& type, bool* newMemberAdded) const
{
BNQualifiedName typeObj = type.GetAPIObject();
BNStructure* result = BNCreateStructureFromOffsetAccess(m_object, &typeObj, newMemberAdded);
return new Structure(result);
}
Confidence BinaryView::CreateStructureMemberFromAccess(const QualifiedName& name, uint64_t offset) const
{
BNQualifiedName typeObj = name.GetAPIObject();
BNTypeWithConfidence type = BNCreateStructureMemberFromAccess(m_object, &typeObj, offset);
if (type.type)
return Confidence(new Type(type.type), type.confidence);
return nullptr;
}
Ref BinaryView::CreateLogger(const string& name)
{
return LogRegistry::CreateLogger(name, GetFile()->GetSessionId());
}
void BinaryView::AddExpressionParserMagicValue(const std::string& name, uint64_t value)
{
BNAddExpressionParserMagicValue(m_object, name.c_str(), value);
}
void BinaryView::RemoveExpressionParserMagicValue(const string& name)
{
BNRemoveExpressionParserMagicValue(m_object, name.c_str());
}
void BinaryView::AddExpressionParserMagicValues(const std::vector& names, const std::vector& values)
{
if (names.empty() || values.empty() || (names.size() != values.size()))
return;
const char** namesArray = new const char*[names.size()];
auto* valuesArray = new uint64_t[names.size()];
for (size_t i = 0; i < names.size(); i++)
{
namesArray[i] = names[i].c_str();
valuesArray[i] = values[i];
}
BNAddExpressionParserMagicValues(m_object, namesArray, valuesArray, names.size());
delete[] namesArray;
delete[] valuesArray;
}
bool BinaryView::GetExpressionParserMagicValue(const std::string& name, uint64_t* value)
{
return BNGetExpressionParserMagicValue(m_object, name.c_str(), value);
}
void BinaryView::RemoveExpressionParserMagicValues(const vector& names)
{
if (names.empty())
return;
const char** toRemove = new const char*[names.size()];
for (size_t i = 0; i < names.size(); i++)
toRemove[i] = names[i].c_str();
BNRemoveExpressionParserMagicValues(m_object, toRemove, names.size());
delete[] toRemove;
}
Ref BinaryView::AddExternalLibrary(const std::string& name, Ref backingFile, bool isAuto)
{
BNExternalLibrary* lib = BNBinaryViewAddExternalLibrary(m_object, name.c_str(), backingFile ? backingFile->m_object : nullptr, isAuto);
if (!lib)
return nullptr;
return new ExternalLibrary(lib);
}
void BinaryView::RemoveExternalLibrary(const std::string& name)
{
BNBinaryViewRemoveExternalLibrary(m_object, name.c_str());
}
Ref BinaryView::GetExternalLibrary(const std::string& name)
{
BNExternalLibrary* lib = BNBinaryViewGetExternalLibrary(m_object, name.c_str());
if (!lib)
return nullptr;
return new ExternalLibrary(lib);
}
std::vector BinaryView::GetExternalLibraries()
{
size_t count;
BNExternalLibrary** libs = BNBinaryViewGetExternalLibraries(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new ExternalLibrary(BNNewExternalLibraryReference(libs[i])));
BNFreeExternalLibraryList(libs, count);
return result;
}
Ref BinaryView::AddExternalLocation(Ref sourceSymbol, Ref library, std::optional targetSymbol, std::optional targetAddress, bool isAuto)
{
BNExternalLocation* loc = BNBinaryViewAddExternalLocation(m_object,
sourceSymbol->GetObject(),
library ? library->m_object : nullptr,
targetSymbol.has_value() ? targetSymbol.value().c_str() : nullptr,
targetAddress.has_value() ? &targetAddress.value() : nullptr,
isAuto
);
if (!loc)
return nullptr;
return new ExternalLocation(loc);
}
void BinaryView::RemoveExternalLocation(Ref sourceSymbol)
{
BNBinaryViewRemoveExternalLocation(m_object, sourceSymbol->GetObject());
}
Ref BinaryView::GetExternalLocation(Ref sourceSymbol)
{
BNExternalLocation* loc = BNBinaryViewGetExternalLocation(m_object, sourceSymbol->GetObject());
if (!loc)
return nullptr;
return new ExternalLocation(loc);
}
std::vector BinaryView::GetExternalLocations()
{
size_t count;
BNExternalLocation** locs = BNBinaryViewGetExternalLocations(m_object, &count);
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.push_back(new ExternalLocation(BNNewExternalLocationReference(locs[i])));
BNFreeExternalLocationList(locs, count);
return result;
}
Confidence BinaryView::GetGlobalPointerValue() const
{
auto values = GetGlobalPointerValues();
if (values.empty())
return Confidence();
return values[0].second;
}
static vector ConvertGlobalPointerValues(
BNRegisterValueWithConfidenceAndRegister* values, size_t count)
{
vector result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
result.emplace_back(values[i].reg,
Confidence(RegisterValue::FromAPIObject(values[i].value.value), values[i].value.confidence));
BNFreeRegisterValueWithConfidenceAndRegisterList(values);
return result;
}
vector BinaryView::GetGlobalPointerValues() const
{
size_t count;
BNRegisterValueWithConfidenceAndRegister* values = BNGetGlobalPointerValues(m_object, &count);
return ConvertGlobalPointerValues(values, count);
}
vector BinaryView::GetDefaultGlobalPointerValues() const
{
size_t count;
BNRegisterValueWithConfidenceAndRegister* values = BNGetDefaultGlobalPointerValues(m_object, &count);
return ConvertGlobalPointerValues(values, count);
}
vector BinaryView::GetUserGlobalPointerValues() const
{
size_t count;
BNRegisterValueWithConfidenceAndRegister* values = BNGetUserGlobalPointerValues(m_object, &count);
return ConvertGlobalPointerValues(values, count);
}
bool BinaryView::UserGlobalPointerValueSet() const
{
return UserGlobalPointerValuesSet();
}
bool BinaryView::UserGlobalPointerValuesSet() const
{
return BNUserGlobalPointerValuesSet(m_object);
}
void BinaryView::ClearUserGlobalPointerValue()
{
ClearUserGlobalPointerValues();
}
void BinaryView::ClearUserGlobalPointerValues()
{
return BNClearUserGlobalPointerValues(m_object);
}
void BinaryView::SetUserGlobalPointerValue(const Confidence& value)
{
vector values;
for (auto& [reg, _] : GetGlobalPointerValues())
if (reg != BN_INVALID_REGISTER)
values.emplace_back(reg, value);
if (values.empty())
values.emplace_back(BN_INVALID_REGISTER, value);
SetUserGlobalPointerValues(values);
}
void BinaryView::SetUserGlobalPointerValues(const vector& values)
{
vector apiValues;
apiValues.reserve(values.size());
for (auto& [reg, value] : values)
{
BNRegisterValueWithConfidenceAndRegister v;
v.reg = reg;
v.value.confidence = value.GetConfidence();
v.value.value.value = value.GetValue().value;
v.value.value.state = value.GetValue().state;
v.value.value.size = value.GetValue().size;
v.value.value.offset = value.GetValue().offset;
apiValues.push_back(v);
}
BNSetUserGlobalPointerValues(m_object, apiValues.data(), apiValues.size());
}
optional BinaryView::StringifyUnicodeData(Architecture* arch, const DataBuffer& buffer, bool nullTerminates, bool allowShortStrings)
{
char* str = nullptr;
BNStringType type = AsciiString;
if (!BNStringifyUnicodeData(m_object, arch ? arch->GetObject() : nullptr, buffer.GetBufferObject(), nullTerminates, allowShortStrings, &str, &type))
return nullopt;
string result(str);
BNFreeString(str);
return make_pair(result, type);
}
Ref BinaryView::GetNextRelocation(uint64_t addr, uint64_t maxAddr)
{
BNRelocation* reloc = BNGetNextRelocation(m_object, addr, maxAddr);
if (!reloc)
return nullptr;
return new Relocation(reloc);
}
vector BinaryView::DerefParameterNamedTypeRefs(const vector& params)
{
vector result;
result.reserve(params.size());
for (auto& i : params)
result.emplace_back(i.name, i.type->DerefNamedTypeReference(this)->WithConfidence(i.type.GetConfidence()),
i.locationSource, i.location);
return result;
}
ReturnValue BinaryView::DerefReturnValueNamedTypeRefs(const ReturnValue& returnValue)
{
ReturnValue result = returnValue;
if (result.type.GetValue())
result.type.SetValue(result.type->DerefNamedTypeReference(this));
return result;
}
Relocation::Relocation(BNRelocation* reloc)
{
m_object = reloc;
}
BNRelocationInfo Relocation::GetInfo() const
{
return BNRelocationGetInfo(m_object);
}
Architecture* Relocation::GetArchitecture() const
{
return new CoreArchitecture(BNRelocationGetArchitecture(m_object));
}
uint64_t Relocation::GetTarget() const
{
return BNRelocationGetTarget(m_object);
}
uint64_t Relocation::GetAddress() const
{
return BNRelocationGetReloc(m_object);
}
Ref Relocation::GetSymbol() const
{
BNSymbol* sym = BNRelocationGetSymbol(m_object);
if (!sym)
return nullptr;
return new Symbol(sym);
}
BinaryData::BinaryData(BNBinaryView* view) : BinaryView(view) {}
BinaryData::BinaryData(FileMetadata* file) : BinaryView(BNCreateBinaryDataView(file->GetObject())) {}
BinaryData::BinaryData(FileMetadata* file, const DataBuffer& data) :
BinaryView(BNCreateBinaryDataViewFromBuffer(file->GetObject(), data.GetBufferObject()))
{}
BinaryData::BinaryData(FileMetadata* file, const void* data, size_t len) :
BinaryView(BNCreateBinaryDataViewFromData(file->GetObject(), data, len))
{}
BinaryData::BinaryData(FileMetadata* file, const string& path) :
BinaryView(BNCreateBinaryDataViewFromFilename(file->GetObject(), path.c_str()))
{}
BinaryData::BinaryData(FileMetadata* file, FileAccessor* accessor) :
BinaryView(BNCreateBinaryDataViewFromFile(file->GetObject(), accessor->GetCallbacks()))
{}
Ref BinaryData::CreateFromFilename(FileMetadata* file, const std::string& path)
{
// This can fail, and throwing an exception in a c++ ctor is Ugly, so now there's a helper method here
BNBinaryView* handle = BNCreateBinaryDataViewFromFilename(file->GetObject(), path.c_str());
if (!handle)
return nullptr;
return new BinaryData(handle);
}
Ref BinaryData::CreateFromFile(FileMetadata* file, FileAccessor* accessor)
{
// This can fail, and throwing an exception in a c++ ctor is Ugly, so now there's a helper method here
BNBinaryView* handle = BNCreateBinaryDataViewFromFile(file->GetObject(), accessor->GetCallbacks());
if (!handle)
return nullptr;
return new BinaryData(handle);
}
Ref BinaryNinja::Load(const std::string& filename, bool updateAnalysis,
ProgressFunction progress, Ref options)
{
return Load(filename, updateAnalysis, options->GetJsonString(), progress);
}
Ref BinaryNinja::Load(
const DataBuffer& rawData, bool updateAnalysis, ProgressFunction progress, Ref options)
{
Ref file = new FileMetadata();
Ref view = new BinaryData(file, rawData);
return Load(view, updateAnalysis, progress, options, false);
}
Ref BinaryNinja::Load(Ref view, bool updateAnalysis,
ProgressFunction progress, Ref options, bool isDatabase)
{
return Load(view, updateAnalysis, options->GetJsonString(), progress);
}
Ref BinaryNinja::Load(const std::string& filename, bool updateAnalysis, const std::string& options, ProgressFunction progress)
{
ProgressContext cb;
cb.callback = progress;
BNBinaryView* handle = BNLoadFilename(filename.c_str(), updateAnalysis, options.c_str(), ProgressCallback, &cb);
if (!handle)
return nullptr;
return new BinaryView(handle);
}
Ref BinaryNinja::Load(const DataBuffer& rawData, bool updateAnalysis, const std::string& options, ProgressFunction progress)
{
Ref file = new FileMetadata();
Ref view = new BinaryData(file, rawData);
return Load(view, updateAnalysis, options, progress);
}
Ref BinaryNinja::Load(Ref view, bool updateAnalysis, const std::string& options, ProgressFunction progress)
{
ProgressContext cb;
cb.callback = progress;
BNBinaryView* handle = BNLoadBinaryView(view->GetObject(), updateAnalysis, options.c_str(), ProgressCallback, &cb);
if (!handle)
return nullptr;
return new BinaryView(handle);
}
Ref BinaryNinja::Load(Ref projectFile, bool updateAnalysis, const std::string& options, ProgressFunction progress)
{
ProgressContext cb;
cb.callback = progress;
BNBinaryView* handle = BNLoadProjectFile(projectFile->GetObject(), updateAnalysis, options.c_str(), ProgressCallback, &cb);
if (!handle)
return nullptr;
return new BinaryView(handle);
}
Ref BinaryNinja::ParseTextFormat(const std::string& filename)
{
BNBinaryView* handle = BNParseTextFormat(filename.c_str());
if (!handle)
return nullptr;
return new BinaryView(handle);
}
SymbolQueue::SymbolQueue()
{
m_object = BNCreateSymbolQueue();
}
SymbolQueue::~SymbolQueue()
{
BNDestroySymbolQueue(m_object);
}
void SymbolQueue::ResolveCallback(void* ctxt, BNSymbol** symbol, BNTypeWithConfidence* type)
{
SymbolQueueResolveContext* resolve = (SymbolQueueResolveContext*)ctxt;
auto result = resolve->resolve();
delete resolve;
*symbol = result.first ? BNNewSymbolReference(result.first->GetObject()) : nullptr;
type->type = result.second.GetValue() ? BNNewTypeReference(result.second.GetValue()->GetObject()) : nullptr;
type->confidence = result.second.GetConfidence();
}
void SymbolQueue::AddCallback(void* ctxt, BNSymbol* symbol, BNTypeWithConfidence* type)
{
SymbolQueueAddContext* add = (SymbolQueueAddContext*)ctxt;
Ref apiSymbol = new Symbol(symbol);
Confidence apiType(type->type ? new Type(type->type) : nullptr, type->confidence);
add->add(apiSymbol, apiType);
delete add;
}
void SymbolQueue::Append(
const std::function& resolve, const std::function& add)
{
SymbolQueueResolveContext* resolveCtxt = new SymbolQueueResolveContext {resolve};
SymbolQueueAddContext* addCtxt = new SymbolQueueAddContext {add};
BNAppendSymbolQueue(m_object, ResolveCallback, resolveCtxt, AddCallback, addCtxt);
}
void SymbolQueue::Process()
{
BNProcessSymbolQueue(m_object);
}