// Copyright (c) 2020-2025 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 "binaryninjaapi.h" using namespace std; using namespace BinaryNinja; LinearViewCursor::LinearViewCursor(LinearViewObject* root) { m_object = BNCreateLinearViewCursor(root->GetObject()); } LinearViewCursor::LinearViewCursor(BNLinearViewCursor* cursor) { m_object = cursor; } bool LinearViewCursor::IsBeforeBegin() const { return BNIsLinearViewCursorBeforeBegin(m_object); } bool LinearViewCursor::IsAfterEnd() const { return BNIsLinearViewCursorAfterEnd(m_object); } bool LinearViewCursor::IsValid() const { return !(IsBeforeBegin() || IsAfterEnd()); } Ref LinearViewCursor::GetCurrentObject() const { BNLinearViewObject* result = BNGetLinearViewCursorCurrentObject(m_object); if (result) return new LinearViewObject(result); return nullptr; } vector LinearViewCursor::GetPath() const { size_t count; BNLinearViewObjectIdentifier* path = BNGetLinearViewCursorPath(m_object, &count); vector result; for (size_t i = 0; i < count; i++) { LinearViewObjectIdentifier id; id.name = path[i].name; id.type = path[i].type; id.start = path[i].start; id.end = path[i].end; result.push_back(id); } BNFreeLinearViewCursorPath(path, count); return result; } vector> LinearViewCursor::GetPathObjects() const { size_t count; BNLinearViewObject** path = BNGetLinearViewCursorPathObjects(m_object, &count); vector> result; for (size_t i = 0; i < count; i++) result.push_back(new LinearViewObject(BNNewLinearViewObjectReference(path[i]))); BNFreeLinearViewCursorPathObjects(path, count); return result; } BNAddressRange LinearViewCursor::GetOrderingIndex() const { return BNGetLinearViewCursorOrderingIndex(m_object); } uint64_t LinearViewCursor::GetOrderingIndexTotal() const { return BNGetLinearViewCursorOrderingIndexTotal(m_object); } void LinearViewCursor::SeekToBegin() { BNSeekLinearViewCursorToBegin(m_object); } void LinearViewCursor::SeekToEnd() { BNSeekLinearViewCursorToEnd(m_object); } void LinearViewCursor::SeekToAddress(uint64_t addr) { BNSeekLinearViewCursorToAddress(m_object, addr); } bool LinearViewCursor::SeekToPath(const vector& path) { BNLinearViewObjectIdentifier* ids = new BNLinearViewObjectIdentifier[path.size()]; for (size_t i = 0; i < path.size(); i++) { ids[i].name = BNAllocString(path[i].name.c_str()); ids[i].type = path[i].type; ids[i].start = path[i].start; ids[i].end = path[i].end; } bool result = BNSeekLinearViewCursorToPath(m_object, ids, path.size()); for (size_t i = 0; i < path.size(); i++) BNFreeString(ids[i].name); delete[] ids; return result; } bool LinearViewCursor::SeekToPath(const vector& path, uint64_t addr) { BNLinearViewObjectIdentifier* ids = new BNLinearViewObjectIdentifier[path.size()]; for (size_t i = 0; i < path.size(); i++) { ids[i].name = BNAllocString(path[i].name.c_str()); ids[i].type = path[i].type; ids[i].start = path[i].start; ids[i].end = path[i].end; } bool result = BNSeekLinearViewCursorToPathAndAddress(m_object, ids, path.size(), addr); for (size_t i = 0; i < path.size(); i++) BNFreeString(ids[i].name); delete[] ids; return result; } bool LinearViewCursor::SeekToPath(LinearViewCursor* cursor) { return BNSeekLinearViewCursorToCursorPath(m_object, cursor->GetObject()); } bool LinearViewCursor::SeekToPath(LinearViewCursor* cursor, uint64_t addr) { return BNSeekLinearViewCursorToCursorPathAndAddress(m_object, cursor->GetObject(), addr); } void LinearViewCursor::SeekToOrderingIndex(uint64_t idx) { BNSeekLinearViewCursorToOrderingIndex(m_object, idx); } bool LinearViewCursor::Next() { return BNLinearViewCursorNext(m_object); } bool LinearViewCursor::Previous() { return BNLinearViewCursorPrevious(m_object); } vector LinearViewCursor::GetLines() { size_t count; BNLinearDisassemblyLine* lines = BNGetLinearViewCursorLines(m_object, &count); vector result; result.reserve(count); for (size_t i = 0; i < count; i++) result.push_back(LinearDisassemblyLine::FromAPIObject(&lines[i])); BNFreeLinearDisassemblyLines(lines, count); return result; } Ref LinearViewCursor::Duplicate() { return new LinearViewCursor(BNDuplicateLinearViewCursor(m_object)); } std::vector LinearViewCursor::GetRenderLayers() const { size_t count = 0; BNRenderLayer** layers = BNGetLinearViewCursorRenderLayers(m_object, &count); std::vector result; for (size_t i = 0; i < count; i ++) { result.push_back(new CoreRenderLayer(layers[i])); } BNFreeRenderLayerList(layers); return result; } void LinearViewCursor::AddRenderLayer(RenderLayer* layer) { BNAddLinearViewCursorRenderLayer(m_object, layer->GetObject()); } void LinearViewCursor::RemoveRenderLayer(RenderLayer* layer) { BNRemoveLinearViewCursorRenderLayer(m_object, layer->GetObject()); } int LinearViewCursor::Compare(LinearViewCursor* a, LinearViewCursor* b) { return BNCompareLinearViewCursors(a->GetObject(), b->GetObject()); }